// Copyright (C) 2003, Fernando Luis Cacciola Carballal. // // 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 #include #include #define BOOST_ENABLE_ASSERT_HANDLER #include "boost/optional.hpp" #ifdef __BORLANDC__ #pragma hdrstop #endif #include "boost/none.hpp" #include "boost/test/minimal.hpp" #include "optional_test_common.cpp" template inline void check_ref_uninitialized_const ( optional const& opt ) { #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE BOOST_CHECK( opt == 0 ) ; #endif BOOST_CHECK( !opt ) ; } template inline void check_ref_uninitialized ( optional& opt ) { #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE BOOST_CHECK( opt == 0 ) ; #endif BOOST_CHECK( !opt ) ; check_ref_uninitialized_const(opt); } template inline void check_ref_initialized_const ( optional const& opt ) { BOOST_CHECK( opt ) ; #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE BOOST_CHECK( opt != 0 ) ; #endif BOOST_CHECK ( !!opt ) ; } template inline void check_ref_initialized ( optional& opt ) { BOOST_CHECK( opt ) ; #ifndef BOOST_OPTIONAL_NO_NULL_COMPARE BOOST_CHECK( opt != 0 ) ; #endif BOOST_CHECK ( !!opt ) ; check_ref_initialized_const(opt); } template inline void check_ref_value_const ( optional const& opt, T const& v, T const& z ) { BOOST_CHECK( *opt == v ) ; BOOST_CHECK( *opt != z ) ; BOOST_CHECK( opt.get() == v ) ; BOOST_CHECK( opt.get() != z ) ; } template inline void check_ref_value ( optional& opt, T const& v, T const& z ) { BOOST_CHECK( *opt == v ) ; BOOST_CHECK( *opt != z ) ; BOOST_CHECK( opt.get() == v ) ; BOOST_CHECK( opt.get() != z ) ; check_ref_value_const(opt,v,z); } // // Basic test. // Check ordinary functionality: // Initialization, assignment, comparison and value-accessing. // template void test_basics( T const* ) { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T original_a(1); T a(1); T b(2); T c(10); T& aref = a ; T& bref = b ; // Default construction. // 'def' state is Uninitialized. // T::T() is not called optional def ; check_ref_uninitialized(def); // Direct initialization. // 'oa' state is Initialized and binds to 'a' // T::T( T const& x ) is NOT used becasue the optional holds a reference. set_pending_copy( ARG(T) ) ; optional oa ( aref ) ; check_is_pending_copy( ARG(T) ); check_ref_initialized(oa); check_ref_value(oa,a,z); *oa = b ; // changes the value of 'a' through the reference BOOST_CHECK( a == b ) ; // Copy initialization. // T::T ( T const& x ) is NOT used becasue the optional holds a reference. set_pending_copy( ARG(T) ) ; optional const oa2 ( oa ) ; check_is_pending_copy( ARG(T) ) ; check_ref_initialized_const(oa2); check_ref_value_const(oa2,a,z); *oa2 = original_a ; // restores the value of 'a' through the reference BOOST_CHECK( a == original_a ) ; optional ob ; // Value-Assignment upon Uninitialized optional. // T::T ( T const& x ) is NOT used becasue the optional holds a reference. set_pending_copy( ARG(T) ) ; ob = a ; // Binds ob to a temporary non-const refererence to 'a' check_is_pending_copy( ARG(T) ) ; check_ref_initialized(ob); check_ref_value(ob,a,z); a = c; check_ref_value(ob,a,z); // Value-Assignment upon Initialized optional. // T::operator= ( T const& x ) is used. set_pending_assign( ARG(T) ) ; ob = b ; // Rebinds 'ob' to 'b' (without changing 'a') check_is_pending_assign( ARG(T) ) ; check_ref_initialized(ob); check_ref_value(ob,b,z); BOOST_CHECK(a == c); // From a=c in previous test b = c; check_ref_value(ob,b,z); // Assignment initialization. // T::T ( T const& x ) is NOT used becasue the optional holds a reference. set_pending_copy( ARG(T) ) ; optional const oa3 = b ; check_is_pending_copy( ARG(T) ) ; check_ref_initialized_const(oa3); check_ref_value_const(oa3,b,z); // Assignment // T::operator=( T const& x ) is used. set_pending_assign( ARG(T) ) ; oa = ob ; // Rebinds 'a' to 'b' check_is_pending_assign( ARG(T) ) ; check_ref_initialized(oa); a = original_a ; check_ref_value(oa,b,z); // Uninitializing Assignment upon Initialized Optional // T::~T() is NOT used becasue the optional holds a reference. set_pending_dtor( ARG(T) ) ; set_pending_copy( ARG(T) ) ; oa = def ; check_is_pending_dtor( ARG(T) ) ; check_is_pending_copy( ARG(T) ) ; check_ref_uninitialized(oa); // Uninitializing Assignment upon Uninitialized Optional // (Dtor is not called this time) set_pending_dtor( ARG(T) ) ; set_pending_copy( ARG(T) ) ; oa = def ; check_is_pending_dtor( ARG(T) ) ; check_is_pending_copy( ARG(T) ) ; check_ref_uninitialized(oa); // Deinitialization of Initialized Optional // T::~T() is NOT used becasue the optional holds a reference. set_pending_dtor( ARG(T) ) ; ob.reset(); check_is_pending_dtor( ARG(T) ) ; check_ref_uninitialized(ob); // Deinitialization of Uninitialized Optional // T::~T() is not called this time set_pending_dtor( ARG(T) ) ; ob.reset(); check_is_pending_dtor( ARG(T) ) ; check_ref_uninitialized(ob); } void test_with_builtin_types() { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(double) ); } void test_with_class_type() { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(X) ); BOOST_CHECK ( X::count == 0 ) ; } void test_binding() { int i = 0 ; optional ori1 = i ; BOOST_CHECK( &(*ori1) == &i ) ; optional ori2(i) ; BOOST_CHECK( &(*ori2) == &i ) ; int const ci = 0 ; optional orci1 = ci ; BOOST_CHECK( &(*orci1) == &ci ) ; optional orci2(ci) ; BOOST_CHECK( &(*orci2) == &ci ) ; } int test_main( int, char* [] ) { try { test_with_class_type(); test_with_builtin_types(); test_binding(); } catch ( ... ) { BOOST_ERROR("Unexpected Exception caught!"); } return 0; }