1 // Copyright (C) 2003, Fernando Luis Cacciola Carballal.
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)
7 // See http://www.boost.org/lib/optional for documentation.
9 // You are welcome to contact the author at:
10 // fernando_cacciola@hotmail.com
13 #define TRACE(msg) std::cout << msg << std::endl ;
20 void assertion_failed (char const * expr
, char const * func
, char const * file
, long )
23 string msg
= string("Boost assertion failure for \"")
25 + string("\" at file \"")
27 + string("\" function \"")
33 throw std::logic_error(msg
);
38 using boost::optional
;
40 template<class T
> inline void unused_variable ( T
) {}
42 #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
45 using boost::get_pointer
;
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
54 #define ARG(T) (static_cast< T const* >(0))
57 // Helper class used to verify the lifetime managment of the values held by optional
67 TRACE ( "X::X(" << av
<< "). this=" << this ) ;
70 X ( X
const& rhs
) : v(rhs
.v
)
72 pending_copy
= false ;
74 TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs
.v
) ;
78 TRACE ( "throwing exception in X's copy ctor" ) ;
87 pending_dtor
= false ;
91 TRACE ( "X::~X(). v=" << v
<< " this=" << this );
94 X
& operator= ( X
const& rhs
)
96 pending_assign
= false ;
98 if ( throw_on_assign
)
100 TRACE ( "throwing exception in X's assignment" ) ;
110 TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs
.v
) ;
115 friend bool operator == ( X
const& a
, X
const& b
)
116 { return a
.v
== b
.v
; }
118 friend bool operator != ( X
const& a
, X
const& b
)
119 { return a
.v
!= b
.v
; }
121 friend bool operator < ( X
const& a
, X
const& b
)
122 { return a
.v
< b
.v
; }
124 int V() const { return v
; }
125 int& V() { return v
; }
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
;
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 ;
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
; }
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 ; }
185 inline void check_uninitialized_const ( optional
<T
> const& opt
)
187 #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
188 BOOST_CHECK( opt
== 0 ) ;
190 BOOST_CHECK( !opt
) ;
191 BOOST_CHECK( !get_pointer(opt
) ) ;
192 BOOST_CHECK( !opt
.get_ptr() ) ;
195 inline void check_uninitialized ( optional
<T
>& opt
)
197 #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
198 BOOST_CHECK( opt
== 0 ) ;
200 BOOST_CHECK( !opt
) ;
201 BOOST_CHECK( !get_pointer(opt
) ) ;
202 BOOST_CHECK( !opt
.get_ptr() ) ;
204 check_uninitialized_const(opt
);
208 inline void check_initialized_const ( optional
<T
> const& opt
)
212 #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
213 BOOST_CHECK( opt
!= 0 ) ;
216 BOOST_CHECK ( !!opt
) ;
217 BOOST_CHECK ( get_pointer(opt
) ) ;
218 BOOST_CHECK ( opt
.get_ptr() ) ;
222 inline void check_initialized ( optional
<T
>& opt
)
226 #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
227 BOOST_CHECK( opt
!= 0 ) ;
230 BOOST_CHECK ( !!opt
) ;
231 BOOST_CHECK ( get_pointer(opt
) ) ;
232 BOOST_CHECK ( opt
.get_ptr() ) ;
234 check_initialized_const(opt
);
238 inline void check_value_const ( optional
<T
> const& opt
, T
const& v
, T
const& z
)
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
) ;
249 inline void check_value ( optional
<T
>& opt
, T
const& v
, T
const& z
)
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
) ) ;
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
) ;
264 check_value_const(opt
,v
,z
);