1 1.1 jmmv // Copyright 2010 Google Inc. 2 1.1 jmmv // All rights reserved. 3 1.1 jmmv // 4 1.1 jmmv // Redistribution and use in source and binary forms, with or without 5 1.1 jmmv // modification, are permitted provided that the following conditions are 6 1.1 jmmv // met: 7 1.1 jmmv // 8 1.1 jmmv // * Redistributions of source code must retain the above copyright 9 1.1 jmmv // notice, this list of conditions and the following disclaimer. 10 1.1 jmmv // * Redistributions in binary form must reproduce the above copyright 11 1.1 jmmv // notice, this list of conditions and the following disclaimer in the 12 1.1 jmmv // documentation and/or other materials provided with the distribution. 13 1.1 jmmv // * Neither the name of Google Inc. nor the names of its contributors 14 1.1 jmmv // may be used to endorse or promote products derived from this software 15 1.1 jmmv // without specific prior written permission. 16 1.1 jmmv // 17 1.1 jmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 1.1 jmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 1.1 jmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 1.1 jmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 1.1 jmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 1.1 jmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 1.1 jmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 1.1 jmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 1.1 jmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 1.1 jmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 1.1 jmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 1.1 jmmv 29 1.1 jmmv #if !defined(UTILS_OPTIONAL_IPP) 30 1.1 jmmv #define UTILS_OPTIONAL_IPP 31 1.1 jmmv 32 1.1 jmmv #include <cstddef> 33 1.1 jmmv 34 1.1 jmmv #include "utils/defs.hpp" 35 1.1 jmmv #include "utils/optional.hpp" 36 1.1 jmmv #include "utils/sanity.hpp" 37 1.1 jmmv 38 1.1 jmmv 39 1.1 jmmv /// Initializes an optional object to the none value. 40 1.1 jmmv template< class T > 41 1.1 jmmv utils::optional< T >::optional(void) : 42 1.1 jmmv _data(NULL) 43 1.1 jmmv { 44 1.1 jmmv } 45 1.1 jmmv 46 1.1 jmmv 47 1.1 jmmv /// Explicitly initializes an optional object to the none value. 48 1.1 jmmv /// 49 1.1 jmmv /// \param unused_none A copy of the utils::none instance. 50 1.1 jmmv template< class T > 51 1.1 jmmv utils::optional< T >::optional( 52 1.1 jmmv utils::detail::none_t UTILS_UNUSED_PARAM(none)) : 53 1.1 jmmv _data(NULL) 54 1.1 jmmv { 55 1.1 jmmv } 56 1.1 jmmv 57 1.1 jmmv 58 1.1 jmmv /// Initializes an optional object to a non-none value. 59 1.1 jmmv /// 60 1.1 jmmv /// \param data The initial value for the object. 61 1.1 jmmv template< class T > 62 1.1 jmmv utils::optional< T >::optional(const T& data) : 63 1.1 jmmv _data(new T(data)) 64 1.1 jmmv { 65 1.1 jmmv } 66 1.1 jmmv 67 1.1 jmmv 68 1.1 jmmv /// Copy constructor. 69 1.1 jmmv /// 70 1.1 jmmv /// \param other The optional object to copy from. 71 1.1 jmmv template< class T > 72 1.1 jmmv utils::optional< T >::optional(const optional< T >& other) : 73 1.1 jmmv _data(other._data == NULL ? NULL : new T(*(other._data))) 74 1.1 jmmv { 75 1.1 jmmv } 76 1.1 jmmv 77 1.1 jmmv 78 1.1 jmmv /// Destructor. 79 1.1 jmmv template< class T > 80 1.1 jmmv utils::optional< T >::~optional(void) 81 1.1 jmmv { 82 1.1 jmmv if (_data != NULL) 83 1.1 jmmv delete _data; 84 1.1 jmmv _data = NULL; // Prevent accidental reuse. 85 1.1 jmmv } 86 1.1 jmmv 87 1.1 jmmv 88 1.1 jmmv /// Explicitly assigns an optional object to the none value. 89 1.1 jmmv /// 90 1.1 jmmv /// \param unused_none A copy of the utils::none instance. 91 1.1 jmmv /// 92 1.1 jmmv /// \return A reference to this. 93 1.1 jmmv template< class T > 94 1.1 jmmv utils::optional< T >& 95 1.1 jmmv utils::optional< T >::operator=(utils::detail::none_t UTILS_UNUSED_PARAM(none)) 96 1.1 jmmv { 97 1.1 jmmv if (_data != NULL) 98 1.1 jmmv delete _data; 99 1.1 jmmv _data = NULL; 100 1.1 jmmv return *this; 101 1.1 jmmv } 102 1.1 jmmv 103 1.1 jmmv 104 1.1 jmmv /// Assigns a new value to the optional object. 105 1.1 jmmv /// 106 1.1 jmmv /// \param data The initial value for the object. 107 1.1 jmmv /// 108 1.1 jmmv /// \return A reference to this. 109 1.1 jmmv template< class T > 110 1.1 jmmv utils::optional< T >& 111 1.1 jmmv utils::optional< T >::operator=(const T& data) 112 1.1 jmmv { 113 1.1 jmmv T* new_data = new T(data); 114 1.1 jmmv if (_data != NULL) 115 1.1 jmmv delete _data; 116 1.1 jmmv _data = new_data; 117 1.1 jmmv return *this; 118 1.1 jmmv } 119 1.1 jmmv 120 1.1 jmmv 121 1.1 jmmv /// Copies an optional value. 122 1.1 jmmv /// 123 1.1 jmmv /// \param other The optional object to copy from. 124 1.1 jmmv /// 125 1.1 jmmv /// \return A reference to this. 126 1.1 jmmv template< class T > 127 1.1 jmmv utils::optional< T >& 128 1.1 jmmv utils::optional< T >::operator=(const optional< T >& other) 129 1.1 jmmv { 130 1.1 jmmv T* new_data = other._data == NULL ? NULL : new T(*(other._data)); 131 1.1 jmmv if (_data != NULL) 132 1.1 jmmv delete _data; 133 1.1 jmmv _data = new_data; 134 1.1 jmmv return *this; 135 1.1 jmmv } 136 1.1 jmmv 137 1.1 jmmv 138 1.1 jmmv /// Equality comparator. 139 1.1 jmmv /// 140 1.1 jmmv /// \param other The other object to compare this one to. 141 1.1 jmmv /// 142 1.1 jmmv /// \return True if this object and other are equal; false otherwise. 143 1.1 jmmv template< class T > 144 1.1 jmmv bool 145 1.1 jmmv utils::optional< T >::operator==(const optional< T >& other) const 146 1.1 jmmv { 147 1.1 jmmv if (_data == NULL && other._data == NULL) { 148 1.1 jmmv return true; 149 1.1 jmmv } else if (_data == NULL || other._data == NULL) { 150 1.1 jmmv return false; 151 1.1 jmmv } else { 152 1.1 jmmv INV(_data != NULL && other._data != NULL); 153 1.1 jmmv return *_data == *other._data; 154 1.1 jmmv } 155 1.1 jmmv } 156 1.1 jmmv 157 1.1 jmmv 158 1.1 jmmv /// Inequality comparator. 159 1.1 jmmv /// 160 1.1 jmmv /// \param other The other object to compare this one to. 161 1.1 jmmv /// 162 1.1 jmmv /// \return True if this object and other are different; false otherwise. 163 1.1 jmmv template< class T > 164 1.1 jmmv bool 165 1.1 jmmv utils::optional< T >::operator!=(const optional< T >& other) const 166 1.1 jmmv { 167 1.1 jmmv return !(*this == other); 168 1.1 jmmv } 169 1.1 jmmv 170 1.1 jmmv 171 1.1 jmmv /// Gets the value hold by the optional object. 172 1.1 jmmv /// 173 1.1 jmmv /// \pre The optional object must not be none. 174 1.1 jmmv /// 175 1.1 jmmv /// \return A reference to the data. 176 1.1 jmmv template< class T > 177 1.1 jmmv const T& 178 1.1 jmmv utils::optional< T >::get(void) const 179 1.1 jmmv { 180 1.1 jmmv PRE(_data != NULL); 181 1.1 jmmv return *_data; 182 1.1 jmmv } 183 1.1 jmmv 184 1.1 jmmv 185 1.1 jmmv /// Gets the value of this object with a default fallback. 186 1.1 jmmv /// 187 1.1 jmmv /// \param default_value The value to return if this object holds no value. 188 1.1 jmmv /// 189 1.1 jmmv /// \return A reference to the data in the optional object, or the reference 190 1.1 jmmv /// passed in as a parameter. 191 1.1 jmmv template< class T > 192 1.1 jmmv const T& 193 1.1 jmmv utils::optional< T >::get_default(const T& default_value) const 194 1.1 jmmv { 195 1.1 jmmv if (_data != NULL) 196 1.1 jmmv return *_data; 197 1.1 jmmv else 198 1.1 jmmv return default_value; 199 1.1 jmmv } 200 1.1 jmmv 201 1.1 jmmv 202 1.1 jmmv /// Tests whether the optional object contains data or not. 203 1.1 jmmv /// 204 1.1 jmmv /// \return True if the object is not none; false otherwise. 205 1.1 jmmv template< class T > 206 1.1 jmmv utils::optional< T >::operator bool(void) const 207 1.1 jmmv { 208 1.1 jmmv return _data != NULL; 209 1.1 jmmv } 210 1.1 jmmv 211 1.1 jmmv 212 1.1 jmmv /// Tests whether the optional object contains data or not. 213 1.1 jmmv /// 214 1.1 jmmv /// \return True if the object is not none; false otherwise. 215 1.1 jmmv template< class T > 216 1.1 jmmv T& 217 1.1 jmmv utils::optional< T >::get(void) 218 1.1 jmmv { 219 1.1 jmmv PRE(_data != NULL); 220 1.1 jmmv return *_data; 221 1.1 jmmv } 222 1.1 jmmv 223 1.1 jmmv 224 1.1 jmmv /// Injects the object into a stream. 225 1.1 jmmv /// 226 1.1 jmmv /// \param output The stream into which to inject the object. 227 1.1 jmmv /// \param object The object to format. 228 1.1 jmmv /// 229 1.1 jmmv /// \return The output stream. 230 1.1 jmmv template< class T > 231 1.1 jmmv std::ostream& utils::operator<<(std::ostream& output, 232 1.1 jmmv const optional< T >& object) 233 1.1 jmmv { 234 1.1 jmmv if (!object) { 235 1.1 jmmv output << "none"; 236 1.1 jmmv } else { 237 1.1 jmmv output << object.get(); 238 1.1 jmmv } 239 1.1 jmmv return output; 240 1.1 jmmv } 241 1.1 jmmv 242 1.1 jmmv 243 1.1 jmmv /// Helper function to instantiate optional objects. 244 1.1 jmmv /// 245 1.1 jmmv /// \param value The value for the optional object. Shouldn't be none, as 246 1.1 jmmv /// optional objects can be constructed from none right away. 247 1.1 jmmv /// 248 1.1 jmmv /// \return A new optional object. 249 1.1 jmmv template< class T > 250 1.1 jmmv utils::optional< T > 251 1.1 jmmv utils::make_optional(const T& value) 252 1.1 jmmv { 253 1.1 jmmv return optional< T >(value); 254 1.1 jmmv } 255 1.1 jmmv 256 1.1 jmmv 257 1.1 jmmv #endif // !defined(UTILS_OPTIONAL_IPP) 258