// 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 #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 inline void check_uninitialized_const ( optional 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 inline void check_uninitialized ( optional& 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 inline void check_initialized_const ( optional 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 inline void check_initialized ( optional& 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 inline void check_value_const ( optional 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 inline void check_value ( optional& 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); }