123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- // Copyright (C) 2003, Fernando Luis Cacciola Carballal.
- // Copyright (C) 2014, Andrzej Krzemienski.
- //
- // Use, modification, and distribution is subject to the Boost Software
- // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- // See http://www.boost.org/lib/optional for documentation.
- //
- // You are welcome to contact the author at:
- // fernando_cacciola@hotmail.com
- //
- #include <boost/core/ignore_unused.hpp>
- #ifdef ENABLE_TRACE
- #define TRACE(msg) std::cout << msg << std::endl ;
- #else
- #define TRACE(msg)
- #endif
- namespace boost {
- void assertion_failed (char const * expr, char const * func, char const * file, long )
- {
- using std::string ;
- string msg = string("Boost assertion failure for \"")
- + string(expr)
- + string("\" at file \"")
- + string(file)
- + string("\" function \"")
- + string(func)
- + string("\"") ;
- TRACE(msg);
- throw std::logic_error(msg);
- }
- }
- using boost::optional ;
- #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
- using boost::swap ;
- using boost::get ;
- using boost::get_pointer ;
- #endif
- // MSVC6.0 does not support comparisons of optional against a literal null pointer value (0)
- // via the safe_bool operator.
- #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1
- #define BOOST_OPTIONAL_NO_NULL_COMPARE
- #else
- #define BOOST_OPTIONAL_NO_NULL_COMPARE // Andrzej: I also disable 0 comparison everywhere
- #endif
- #define ARG(T) (static_cast< T const* >(0))
- //
- // Helper class used to verify the lifetime managment of the values held by optional
- //
- class X
- {
- public :
- X ( int av ) : v(av)
- {
- ++ count ;
- TRACE ( "X::X(" << av << "). this=" << this ) ;
- }
- X ( X const& rhs ) : v(rhs.v)
- {
- pending_copy = false ;
- TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
- if ( throw_on_copy )
- {
- TRACE ( "throwing exception in X's copy ctor" ) ;
- throw 0 ;
- }
- ++ count ;
- }
- ~X()
- {
- pending_dtor = false ;
- -- count ;
- TRACE ( "X::~X(). v=" << v << " this=" << this );
- }
- X& operator= ( X const& rhs )
- {
- pending_assign = false ;
- if ( throw_on_assign )
- {
- TRACE ( "throwing exception in X's assignment" ) ;
- v = -1 ;
- throw 0 ;
- }
- else
- {
- v = rhs.v ;
- TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
- }
- return *this ;
- }
- friend bool operator == ( X const& a, X const& b )
- { return a.v == b.v ; }
- friend bool operator != ( X const& a, X const& b )
- { return a.v != b.v ; }
- friend bool operator < ( X const& a, X const& b )
- { return a.v < b.v ; }
- int V() const { return v ; }
- int& V() { return v ; }
- static int count ;
- static bool pending_copy ;
- static bool pending_dtor ;
- static bool pending_assign ;
- static bool throw_on_copy ;
- static bool throw_on_assign ;
- private :
- int v ;
- private :
- X() ;
- } ;
- int X::count = 0 ;
- bool X::pending_copy = false ;
- bool X::pending_dtor = false ;
- bool X::pending_assign = false ;
- bool X::throw_on_copy = false ;
- bool X::throw_on_assign = false ;
- inline void set_pending_copy ( X const* ) { X::pending_copy = true ; }
- inline void set_pending_dtor ( X const* ) { X::pending_dtor = true ; }
- inline void set_pending_assign ( X const* ) { X::pending_assign = true ; }
- inline void set_throw_on_copy ( X const* ) { X::throw_on_copy = true ; }
- inline void set_throw_on_assign ( X const* ) { X::throw_on_assign = true ; }
- inline void reset_throw_on_copy ( X const* ) { X::throw_on_copy = false ; }
- inline void reset_throw_on_assign ( X const* ) { X::throw_on_assign = false ; }
- inline void check_is_pending_copy ( X const* ) { BOOST_TEST( X::pending_copy ) ; }
- inline void check_is_pending_dtor ( X const* ) { BOOST_TEST( X::pending_dtor ) ; }
- inline void check_is_pending_assign ( X const* ) { BOOST_TEST( X::pending_assign ) ; }
- inline void check_is_not_pending_copy ( X const* ) { BOOST_TEST( !X::pending_copy ) ; }
- inline void check_is_not_pending_dtor ( X const* ) { BOOST_TEST( !X::pending_dtor ) ; }
- inline void check_is_not_pending_assign( X const* ) { BOOST_TEST( !X::pending_assign ) ; }
- inline void check_instance_count ( int c, X const* ) { BOOST_TEST( X::count == c ) ; }
- inline int get_instance_count ( X const* ) { return X::count ; }
- inline void set_pending_copy (...) {}
- inline void set_pending_dtor (...) {}
- inline void set_pending_assign (...) {}
- inline void set_throw_on_copy (...) {}
- inline void set_throw_on_assign (...) {}
- inline void reset_throw_on_copy (...) {}
- inline void reset_throw_on_assign (...) {}
- inline void check_is_pending_copy (...) {}
- inline void check_is_pending_dtor (...) {}
- inline void check_is_pending_assign (...) {}
- inline void check_is_not_pending_copy (...) {}
- inline void check_is_not_pending_dtor (...) {}
- inline void check_is_not_pending_assign(...) {}
- inline void check_instance_count (...) {}
- inline int get_instance_count (...) { return 0 ; }
- template<class T>
- inline void check_uninitialized_const ( optional<T> const& opt )
- {
- #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_TEST( opt == 0 ) ;
- #endif
- BOOST_TEST( !opt ) ;
- BOOST_TEST( !get_pointer(opt) ) ;
- BOOST_TEST( !opt.get_ptr() ) ;
- BOOST_TEST( !opt.has_value() ) ;
- BOOST_TEST( !opt.is_initialized() ) ;
- BOOST_TEST( opt == boost::none ) ;
- }
- template<class T>
- inline void check_uninitialized ( optional<T>& opt )
- {
- #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_TEST( opt == 0 ) ;
- #endif
- BOOST_TEST( !opt ) ;
- BOOST_TEST( !get_pointer(opt) ) ;
- BOOST_TEST( !opt.get_ptr() ) ;
- BOOST_TEST( !opt.has_value() ) ;
- BOOST_TEST( !opt.is_initialized() ) ;
- BOOST_TEST( opt == boost::none ) ;
- check_uninitialized_const(opt);
- }
- template<class T>
- inline void check_initialized_const ( optional<T> const& opt )
- {
- BOOST_TEST( opt ) ;
- #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_TEST( opt != 0 ) ;
- #endif
- BOOST_TEST ( !!opt ) ;
- BOOST_TEST ( get_pointer(opt) ) ;
- BOOST_TEST ( opt.get_ptr() ) ;
- BOOST_TEST ( opt.has_value() ) ;
- BOOST_TEST ( opt.is_initialized() ) ;
- BOOST_TEST ( opt != boost::none ) ;
- }
- template<class T>
- inline void check_initialized ( optional<T>& opt )
- {
- BOOST_TEST( opt ) ;
- #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_TEST( opt != 0 ) ;
- #endif
- BOOST_TEST ( !!opt ) ;
- BOOST_TEST ( get_pointer(opt) ) ;
- BOOST_TEST ( opt.get_ptr() ) ;
- BOOST_TEST ( opt.has_value() ) ;
- BOOST_TEST ( opt.is_initialized() ) ;
- BOOST_TEST ( opt != boost::none ) ;
- check_initialized_const(opt);
- }
- template<class T>
- inline void check_value_const ( optional<T> const& opt, T const& v, T const& z )
- {
- BOOST_TEST( *opt == v ) ;
- BOOST_TEST( *opt != z ) ;
- BOOST_TEST( opt.get() == v ) ;
- BOOST_TEST( opt.get() != z ) ;
- BOOST_TEST( (*(opt.operator->()) == v) ) ;
- BOOST_TEST( *get_pointer(opt) == v ) ;
- }
- template<class T>
- inline void check_value ( optional<T>& opt, T const& v, T const& z )
- {
- #if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // 1200 == VC++ 6.0
- // For some reason, VC6.0 is creating a temporary while evaluating (*opt == v),
- // so we need to turn throw on copy off first.
- reset_throw_on_copy( ARG(T) ) ;
- #endif
- BOOST_TEST( *opt == v ) ;
- BOOST_TEST( *opt != z ) ;
- BOOST_TEST( opt.get() == v ) ;
- BOOST_TEST( opt.get() != z ) ;
- BOOST_TEST( (*(opt.operator->()) == v) ) ;
- BOOST_TEST( *get_pointer(opt) == v ) ;
- check_value_const(opt,v,z);
- }
|