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