| 1 | // Copyright (C) 2003, Fernando Luis Cacciola Carballal. |
|---|
| 2 | // |
|---|
| 3 | // Use, modification, and distribution is subject to the Boost Software |
|---|
| 4 | // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at |
|---|
| 5 | // http://www.boost.org/LICENSE_1_0.txt) |
|---|
| 6 | // |
|---|
| 7 | // See http://www.boost.org/lib/optional for documentation. |
|---|
| 8 | // |
|---|
| 9 | // You are welcome to contact the author at: |
|---|
| 10 | // fernando_cacciola@hotmail.com |
|---|
| 11 | // |
|---|
| 12 | #ifdef ENABLE_TRACE |
|---|
| 13 | #define TRACE(msg) std::cout << msg << std::endl ; |
|---|
| 14 | #else |
|---|
| 15 | #define TRACE(msg) |
|---|
| 16 | #endif |
|---|
| 17 | |
|---|
| 18 | namespace boost { |
|---|
| 19 | |
|---|
| 20 | void assertion_failed (char const * expr, char const * func, char const * file, long ) |
|---|
| 21 | { |
|---|
| 22 | using std::string ; |
|---|
| 23 | string msg = string("Boost assertion failure for \"") |
|---|
| 24 | + string(expr) |
|---|
| 25 | + string("\" at file \"") |
|---|
| 26 | + string(file) |
|---|
| 27 | + string("\" function \"") |
|---|
| 28 | + string(func) |
|---|
| 29 | + string("\"") ; |
|---|
| 30 | |
|---|
| 31 | TRACE(msg); |
|---|
| 32 | |
|---|
| 33 | throw std::logic_error(msg); |
|---|
| 34 | } |
|---|
| 35 | |
|---|
| 36 | } |
|---|
| 37 | |
|---|
| 38 | using boost::optional ; |
|---|
| 39 | |
|---|
| 40 | template<class T> inline void unused_variable ( T ) {} |
|---|
| 41 | |
|---|
| 42 | #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP |
|---|
| 43 | using boost::swap ; |
|---|
| 44 | using boost::get ; |
|---|
| 45 | using boost::get_pointer ; |
|---|
| 46 | #endif |
|---|
| 47 | |
|---|
| 48 | // MSVC6.0 does not support comparisons of optional against a literal null pointer value (0) |
|---|
| 49 | // via the safe_bool operator. |
|---|
| 50 | #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1 |
|---|
| 51 | #define BOOST_OPTIONAL_NO_NULL_COMPARE |
|---|
| 52 | #endif |
|---|
| 53 | |
|---|
| 54 | #define ARG(T) (static_cast< T const* >(0)) |
|---|
| 55 | |
|---|
| 56 | // |
|---|
| 57 | // Helper class used to verify the lifetime managment of the values held by optional |
|---|
| 58 | // |
|---|
| 59 | class X |
|---|
| 60 | { |
|---|
| 61 | public : |
|---|
| 62 | |
|---|
| 63 | X ( int av ) : v(av) |
|---|
| 64 | { |
|---|
| 65 | ++ count ; |
|---|
| 66 | |
|---|
| 67 | TRACE ( "X::X(" << av << "). this=" << this ) ; |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | X ( X const& rhs ) : v(rhs.v) |
|---|
| 71 | { |
|---|
| 72 | pending_copy = false ; |
|---|
| 73 | |
|---|
| 74 | TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ; |
|---|
| 75 | |
|---|
| 76 | if ( throw_on_copy ) |
|---|
| 77 | { |
|---|
| 78 | TRACE ( "throwing exception in X's copy ctor" ) ; |
|---|
| 79 | throw 0 ; |
|---|
| 80 | } |
|---|
| 81 | |
|---|
| 82 | ++ count ; |
|---|
| 83 | } |
|---|
| 84 | |
|---|
| 85 | ~X() |
|---|
| 86 | { |
|---|
| 87 | pending_dtor = false ; |
|---|
| 88 | |
|---|
| 89 | -- count ; |
|---|
| 90 | |
|---|
| 91 | TRACE ( "X::~X(). v=" << v << " this=" << this ); |
|---|
| 92 | } |
|---|
| 93 | |
|---|
| 94 | X& operator= ( X const& rhs ) |
|---|
| 95 | { |
|---|
| 96 | pending_assign = false ; |
|---|
| 97 | |
|---|
| 98 | if ( throw_on_assign ) |
|---|
| 99 | { |
|---|
| 100 | TRACE ( "throwing exception in X's assignment" ) ; |
|---|
| 101 | |
|---|
| 102 | v = -1 ; |
|---|
| 103 | |
|---|
| 104 | throw 0 ; |
|---|
| 105 | } |
|---|
| 106 | else |
|---|
| 107 | { |
|---|
| 108 | v = rhs.v ; |
|---|
| 109 | |
|---|
| 110 | TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ; |
|---|
| 111 | } |
|---|
| 112 | return *this ; |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | friend bool operator == ( X const& a, X const& b ) |
|---|
| 116 | { return a.v == b.v ; } |
|---|
| 117 | |
|---|
| 118 | friend bool operator != ( X const& a, X const& b ) |
|---|
| 119 | { return a.v != b.v ; } |
|---|
| 120 | |
|---|
| 121 | friend bool operator < ( X const& a, X const& b ) |
|---|
| 122 | { return a.v < b.v ; } |
|---|
| 123 | |
|---|
| 124 | int V() const { return v ; } |
|---|
| 125 | int& V() { return v ; } |
|---|
| 126 | |
|---|
| 127 | static int count ; |
|---|
| 128 | static bool pending_copy ; |
|---|
| 129 | static bool pending_dtor ; |
|---|
| 130 | static bool pending_assign ; |
|---|
| 131 | static bool throw_on_copy ; |
|---|
| 132 | static bool throw_on_assign ; |
|---|
| 133 | |
|---|
| 134 | private : |
|---|
| 135 | |
|---|
| 136 | int v ; |
|---|
| 137 | |
|---|
| 138 | private : |
|---|
| 139 | |
|---|
| 140 | X() ; |
|---|
| 141 | } ; |
|---|
| 142 | |
|---|
| 143 | |
|---|
| 144 | int X::count = 0 ; |
|---|
| 145 | bool X::pending_copy = false ; |
|---|
| 146 | bool X::pending_dtor = false ; |
|---|
| 147 | bool X::pending_assign = false ; |
|---|
| 148 | bool X::throw_on_copy = false ; |
|---|
| 149 | bool X::throw_on_assign = false ; |
|---|
| 150 | |
|---|
| 151 | inline void set_pending_copy ( X const* x ) { X::pending_copy = true ; } |
|---|
| 152 | inline void set_pending_dtor ( X const* x ) { X::pending_dtor = true ; } |
|---|
| 153 | inline void set_pending_assign ( X const* x ) { X::pending_assign = true ; } |
|---|
| 154 | inline void set_throw_on_copy ( X const* x ) { X::throw_on_copy = true ; } |
|---|
| 155 | inline void set_throw_on_assign ( X const* x ) { X::throw_on_assign = true ; } |
|---|
| 156 | inline void reset_throw_on_copy ( X const* x ) { X::throw_on_copy = false ; } |
|---|
| 157 | inline void reset_throw_on_assign ( X const* x ) { X::throw_on_assign = false ; } |
|---|
| 158 | inline void check_is_pending_copy ( X const* x ) { BOOST_CHECK( X::pending_copy ) ; } |
|---|
| 159 | inline void check_is_pending_dtor ( X const* x ) { BOOST_CHECK( X::pending_dtor ) ; } |
|---|
| 160 | inline void check_is_pending_assign ( X const* x ) { BOOST_CHECK( X::pending_assign ) ; } |
|---|
| 161 | inline void check_is_not_pending_copy ( X const* x ) { BOOST_CHECK( !X::pending_copy ) ; } |
|---|
| 162 | inline void check_is_not_pending_dtor ( X const* x ) { BOOST_CHECK( !X::pending_dtor ) ; } |
|---|
| 163 | inline void check_is_not_pending_assign( X const* x ) { BOOST_CHECK( !X::pending_assign ) ; } |
|---|
| 164 | inline void check_instance_count ( int c, X const* x ) { BOOST_CHECK( X::count == c ) ; } |
|---|
| 165 | inline int get_instance_count ( X const* x ) { return X::count ; } |
|---|
| 166 | |
|---|
| 167 | inline void set_pending_copy (...) {} |
|---|
| 168 | inline void set_pending_dtor (...) {} |
|---|
| 169 | inline void set_pending_assign (...) {} |
|---|
| 170 | inline void set_throw_on_copy (...) {} |
|---|
| 171 | inline void set_throw_on_assign (...) {} |
|---|
| 172 | inline void reset_throw_on_copy (...) {} |
|---|
| 173 | inline void reset_throw_on_assign (...) {} |
|---|
| 174 | inline void check_is_pending_copy (...) {} |
|---|
| 175 | inline void check_is_pending_dtor (...) {} |
|---|
| 176 | inline void check_is_pending_assign (...) {} |
|---|
| 177 | inline void check_is_not_pending_copy (...) {} |
|---|
| 178 | inline void check_is_not_pending_dtor (...) {} |
|---|
| 179 | inline void check_is_not_pending_assign(...) {} |
|---|
| 180 | inline void check_instance_count (...) {} |
|---|
| 181 | inline int get_instance_count (...) { return 0 ; } |
|---|
| 182 | |
|---|
| 183 | |
|---|
| 184 | template<class T> |
|---|
| 185 | inline void check_uninitialized_const ( optional<T> const& opt ) |
|---|
| 186 | { |
|---|
| 187 | #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE |
|---|
| 188 | BOOST_CHECK( opt == 0 ) ; |
|---|
| 189 | #endif |
|---|
| 190 | BOOST_CHECK( !opt ) ; |
|---|
| 191 | BOOST_CHECK( !get_pointer(opt) ) ; |
|---|
| 192 | BOOST_CHECK( !opt.get_ptr() ) ; |
|---|
| 193 | } |
|---|
| 194 | template<class T> |
|---|
| 195 | inline void check_uninitialized ( optional<T>& opt ) |
|---|
| 196 | { |
|---|
| 197 | #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE |
|---|
| 198 | BOOST_CHECK( opt == 0 ) ; |
|---|
| 199 | #endif |
|---|
| 200 | BOOST_CHECK( !opt ) ; |
|---|
| 201 | BOOST_CHECK( !get_pointer(opt) ) ; |
|---|
| 202 | BOOST_CHECK( !opt.get_ptr() ) ; |
|---|
| 203 | |
|---|
| 204 | check_uninitialized_const(opt); |
|---|
| 205 | } |
|---|
| 206 | |
|---|
| 207 | template<class T> |
|---|
| 208 | inline void check_initialized_const ( optional<T> const& opt ) |
|---|
| 209 | { |
|---|
| 210 | BOOST_CHECK( opt ) ; |
|---|
| 211 | |
|---|
| 212 | #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE |
|---|
| 213 | BOOST_CHECK( opt != 0 ) ; |
|---|
| 214 | #endif |
|---|
| 215 | |
|---|
| 216 | BOOST_CHECK ( !!opt ) ; |
|---|
| 217 | BOOST_CHECK ( get_pointer(opt) ) ; |
|---|
| 218 | BOOST_CHECK ( opt.get_ptr() ) ; |
|---|
| 219 | } |
|---|
| 220 | |
|---|
| 221 | template<class T> |
|---|
| 222 | inline void check_initialized ( optional<T>& opt ) |
|---|
| 223 | { |
|---|
| 224 | BOOST_CHECK( opt ) ; |
|---|
| 225 | |
|---|
| 226 | #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE |
|---|
| 227 | BOOST_CHECK( opt != 0 ) ; |
|---|
| 228 | #endif |
|---|
| 229 | |
|---|
| 230 | BOOST_CHECK ( !!opt ) ; |
|---|
| 231 | BOOST_CHECK ( get_pointer(opt) ) ; |
|---|
| 232 | BOOST_CHECK ( opt.get_ptr() ) ; |
|---|
| 233 | |
|---|
| 234 | check_initialized_const(opt); |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | template<class T> |
|---|
| 238 | inline void check_value_const ( optional<T> const& opt, T const& v, T const& z ) |
|---|
| 239 | { |
|---|
| 240 | BOOST_CHECK( *opt == v ) ; |
|---|
| 241 | BOOST_CHECK( *opt != z ) ; |
|---|
| 242 | BOOST_CHECK( opt.get() == v ) ; |
|---|
| 243 | BOOST_CHECK( opt.get() != z ) ; |
|---|
| 244 | BOOST_CHECK( (*(opt.operator->()) == v) ) ; |
|---|
| 245 | BOOST_CHECK( *get_pointer(opt) == v ) ; |
|---|
| 246 | } |
|---|
| 247 | |
|---|
| 248 | template<class T> |
|---|
| 249 | inline void check_value ( optional<T>& opt, T const& v, T const& z ) |
|---|
| 250 | { |
|---|
| 251 | #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // 1200 == VC++ 6.0 |
|---|
| 252 | // For some reason, VC6.0 is creating a temporary while evaluating (*opt == v), |
|---|
| 253 | // so we need to turn throw on copy off first. |
|---|
| 254 | reset_throw_on_copy( ARG(T) ) ; |
|---|
| 255 | #endif |
|---|
| 256 | |
|---|
| 257 | BOOST_CHECK( *opt == v ) ; |
|---|
| 258 | BOOST_CHECK( *opt != z ) ; |
|---|
| 259 | BOOST_CHECK( opt.get() == v ) ; |
|---|
| 260 | BOOST_CHECK( opt.get() != z ) ; |
|---|
| 261 | BOOST_CHECK( (*(opt.operator->()) == v) ) ; |
|---|
| 262 | BOOST_CHECK( *get_pointer(opt) == v ) ; |
|---|
| 263 | |
|---|
| 264 | check_value_const(opt,v,z); |
|---|
| 265 | } |
|---|
| 266 | |
|---|
| 267 | |
|---|