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. 40template< class T > 41utils::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. 50template< class T > 51utils::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. 61template< class T > 62utils::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. 71template< class T > 72utils::optional< T >::optional(const optional< T >& other) : 73 _data(other._data == NULL ? NULL : new T(*(other._data))) 74{ 75} 76 77 78/// Destructor. 79template< class T > 80utils::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. 93template< class T > 94utils::optional< T >& 95utils::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. 109template< class T > 110utils::optional< T >& 111utils::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. 126template< class T > 127utils::optional< T >& 128utils::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. 143template< class T > 144bool 145utils::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. 163template< class T > 164bool 165utils::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. 176template< class T > 177const T& 178utils::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. 191template< class T > 192const T& 193utils::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. 205template< class T > 206utils::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. 215template< class T > 216T& 217utils::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. 230template< class T > 231std::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. 249template< class T > 250utils::optional< T > 251utils::make_optional(const T& value) 252{ 253 return optional< T >(value); 254} 255 256 257#endif // !defined(UTILS_OPTIONAL_IPP) 258