optional_test.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 949 行 · 第 1/2 页
CPP
949 行
int count = get_instance_count( ARG(T) ) ; set_throw_on_copy( ARG(T) ) ; bool passed = false ; try { // This should: // Attempt to copy construct 'opt' and throw. // opt1 won't be constructed. set_pending_copy( ARG(T) ) ; optional<T> opt1 = opt ; passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); check_is_not_pending_copy( ARG(T) ); check_instance_count(count, ARG(T) ); // Nothing should have happened to the source optional. check_initialized(opt); check_value(opt,a,z); reset_throw_on_copy( ARG(T) ) ;}//// Test Assignment to an Uninitialized optional from an Initialized optional// for a T with a throwing copy-ctor//template<class T>void test_throwing_assign_to_uninitialized( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T a(11); optional<T> opt0 ; optional<T> opt1(a) ; int count = get_instance_count( ARG(T) ) ; set_throw_on_copy( ARG(T) ) ; bool passed = false ; try { // This should: // Attempt to copy construct 'opt1.value()' into opt0 and throw. // opt0 should be left uninitialized. set_pending_copy( ARG(T) ) ; opt0 = opt1 ; passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); check_is_not_pending_copy( ARG(T) ); check_instance_count(count, ARG(T) ); check_uninitialized(opt0); reset_throw_on_copy( ARG(T) ) ;}//// Test Assignment to an Initialized optional from an Initialized optional// for a T with a throwing copy-ctor//template<class T>void test_throwing_assign_to_initialized( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T a(12); T b(13); T x(-1); optional<T> opt0(a) ; optional<T> opt1(b) ; int count = get_instance_count( ARG(T) ) ; set_throw_on_assign( ARG(T) ) ; bool passed = false ; try { // This should: // Attempt to copy construct 'opt1.value()' into opt0 and throw. // opt0 is kept initialized but its value not neccesarily fully assigned // (in this test, incompletely assigned is flaged with the value -1 being set) set_pending_assign( ARG(T) ) ; opt0 = opt1 ; passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); // opt0 was left uninitialized check_is_not_pending_assign( ARG(T) ); check_instance_count(count, ARG(T) ); check_initialized(opt0); check_value(opt0,x,z); reset_throw_on_assign( ARG(T) ) ;}//// Test swap in a no-throwing case//template<class T>void test_no_throwing_swap( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T a(14); T b(15); optional<T> def0 ; optional<T> def1 ; optional<T> opt0(a) ; optional<T> opt1(b) ; int count = get_instance_count( ARG(T) ) ; swap(def0,def1); check_uninitialized(def0); check_uninitialized(def1); swap(def0,opt0); check_uninitialized(opt0); check_initialized(def0); check_value(def0,a,z); // restore def0 and opt0 swap(def0,opt0); swap(opt0,opt1); check_instance_count(count, ARG(T) ); check_initialized(opt0); check_initialized(opt1); check_value(opt0,b,z); check_value(opt1,a,z);}//// Test swap in a throwing case//template<class T>void test_throwing_swap( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T a(16); T b(17); T x(-1); optional<T> opt0(a) ; optional<T> opt1(b) ; set_throw_on_assign( ARG(T) ) ; // // Case 1: Both Initialized. // bool passed = false ; try { // This should attempt to swap optionals and fail at swap(X&,X&). swap(opt0,opt1); passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); // optional's swap doesn't affect the initialized states of the arguments. Therefore, // the following must hold: check_initialized(opt0); check_initialized(opt1); check_value(opt0,x,a); check_value(opt1,b,x); // // Case 2: Only one Initialized. // reset_throw_on_assign( ARG(T) ) ; opt0.reset(); opt1.reset(a); set_throw_on_copy( ARG(T) ) ; passed = false ; try { // This should attempt to swap optionals and fail at opt0.reset(*opt1) // Both opt0 and op1 are left unchanged (unswaped) swap(opt0,opt1); passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); check_uninitialized(opt0); check_initialized(opt1); check_value(opt1,a,x); reset_throw_on_copy( ARG(T) ) ;}//// This verifies relational operators.//template<class T>void test_relops( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T v0(0); T v1(1); T v2(1); optional<T> def0 ; optional<T> def1 ; optional<T> opt0(v0); optional<T> opt1(v1); optional<T> opt2(v2); // Check identity BOOST_CHECK ( def0 == def0 ) ; BOOST_CHECK ( opt0 == opt0 ) ; BOOST_CHECK ( !(def0 != def0) ) ; BOOST_CHECK ( !(opt0 != opt0) ) ; // Check when both are uininitalized. BOOST_CHECK ( def0 == def1 ) ; // both uninitialized compare equal BOOST_CHECK ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized BOOST_CHECK ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized BOOST_CHECK ( !(def0 != def1) ) ; BOOST_CHECK ( def0 <= def1 ) ; BOOST_CHECK ( def0 >= def1 ) ; // Check when only lhs is uninitialized. BOOST_CHECK ( def0 != opt0 ) ; // uninitialized is never equal to initialized BOOST_CHECK ( !(def0 == opt0) ) ; BOOST_CHECK ( def0 < opt0 ) ; // uninitialized is always less than initialized BOOST_CHECK ( !(def0 > opt0) ) ; BOOST_CHECK ( def0 <= opt0 ) ; BOOST_CHECK ( !(def0 >= opt0) ) ; // Check when only rhs is uninitialized. BOOST_CHECK ( opt0 != def0 ) ; // initialized is never equal to uninitialized BOOST_CHECK ( !(opt0 == def0) ) ; BOOST_CHECK ( !(opt0 < def0) ) ; // initialized is never less than uninitialized BOOST_CHECK ( opt0 > def0 ) ; BOOST_CHECK ( !(opt0 <= def0) ) ; BOOST_CHECK ( opt0 >= opt0 ) ; // If both are initialized, values are compared BOOST_CHECK ( opt0 != opt1 ) ; BOOST_CHECK ( opt1 == opt2 ) ; BOOST_CHECK ( opt0 < opt1 ) ; BOOST_CHECK ( opt1 > opt0 ) ; BOOST_CHECK ( opt1 <= opt2 ) ; BOOST_CHECK ( opt1 >= opt0 ) ; // Compare against a value directly BOOST_CHECK ( opt0 == v0 ) ; BOOST_CHECK ( opt0 != v1 ) ; BOOST_CHECK ( opt1 == v2 ) ; BOOST_CHECK ( opt0 < v1 ) ; BOOST_CHECK ( opt1 > v0 ) ; BOOST_CHECK ( opt1 <= v2 ) ; BOOST_CHECK ( opt1 >= v0 ) ; BOOST_CHECK ( v0 != opt1 ) ; BOOST_CHECK ( v1 == opt2 ) ; BOOST_CHECK ( v0 < opt1 ) ; BOOST_CHECK ( v1 > opt0 ) ; BOOST_CHECK ( v1 <= opt2 ) ; BOOST_CHECK ( v1 >= opt0 ) ; BOOST_CHECK ( def0 != v0 ) ; BOOST_CHECK ( !(def0 == v0) ) ; BOOST_CHECK ( def0 < v0 ) ; BOOST_CHECK ( !(def0 > v0) ) ; BOOST_CHECK ( def0 <= v0 ) ; BOOST_CHECK ( !(def0 >= v0) ) ; BOOST_CHECK ( v0 != def0 ) ; BOOST_CHECK ( !(v0 == def0) ) ; BOOST_CHECK ( !(v0 < def0) ) ; BOOST_CHECK ( v0 > def0 ) ; BOOST_CHECK ( !(v0 <= def0) ) ; BOOST_CHECK ( v0 >= opt0 ) ;}template<class T>void test_none( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); using boost::none ; optional<T> def0 ; optional<T> def1(none) ; optional<T> non_def( T(1234) ) ; BOOST_CHECK ( def0 == none ) ; BOOST_CHECK ( non_def != none ) ; BOOST_CHECK ( !def1 ) ; BOOST_CHECK ( !(non_def < none) ) ; BOOST_CHECK ( non_def > none ) ; BOOST_CHECK ( !(non_def <= none) ) ; BOOST_CHECK ( non_def >= none ) ; non_def = none ; BOOST_CHECK ( !non_def ) ; test_default_implicit_construction(T(1),none);}template<class T>void test_arrow( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T a(1234); optional<T> oa(a) ; optional<T> const coa(a) ; BOOST_CHECK ( coa->V() == 1234 ) ; oa->V() = 4321 ; BOOST_CHECK ( a.V() = 1234 ) ; BOOST_CHECK ( (*oa).V() = 4321 ) ;}void test_with_builtin_types(){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(double) ); test_conditional_ctor_and_get_valur_or( ARG(double) ); test_uninitialized_access( ARG(double) ); test_no_throwing_swap( ARG(double) ); test_relops( ARG(double) ) ; test_none( ARG(double) ) ;}void test_with_class_type(){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); test_basics( ARG(X) ); test_conditional_ctor_and_get_valur_or( ARG(X) ); test_direct_value_manip( ARG(X) ); test_uninitialized_access( ARG(X) ); test_throwing_direct_init( ARG(X) ); test_throwing_val_assign_on_uninitialized( ARG(X) ); test_throwing_val_assign_on_initialized( ARG(X) ); test_throwing_copy_initialization( ARG(X) ); test_throwing_assign_to_uninitialized( ARG(X) ); test_throwing_assign_to_initialized( ARG(X) ); test_no_throwing_swap( ARG(X) ); test_throwing_swap( ARG(X) ); test_relops( ARG(X) ) ; test_none( ARG(X) ) ; test_arrow( ARG(X) ) ; BOOST_CHECK ( X::count == 0 ) ;}int eat ( bool ) { return 1 ; }int eat ( char ) { return 1 ; }int eat ( int ) { return 1 ; }int eat ( void const* ) { return 1 ; }template<class T> int eat ( T ) { return 0 ; }//// This verifies that operator safe_bool() behaves properly.//template<class T>void test_no_implicit_conversions_impl( T const& ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); optional<T> def ; BOOST_CHECK ( eat(def) == 0 ) ;}void test_no_implicit_conversions(){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); bool b = false ; char c = 0 ; int i = 0 ; void const* p = 0 ; test_no_implicit_conversions_impl(b); test_no_implicit_conversions_impl(c); test_no_implicit_conversions_impl(i); test_no_implicit_conversions_impl(p);}struct A {} ;void test_conversions1(){ TRACE( std::endl << BOOST_CURRENT_FUNCTION );#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR char c = 20 ; optional<char> opt0(c); optional<int> opt1(opt0); BOOST_CHECK(*opt1 == static_cast<int>(c));#endif#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT float f = 21.22f ; double d = f ; optional<float> opt2(f) ; optional<double> opt3 ; opt3 = opt2 ; BOOST_CHECK(*opt3 == d);#endif}void test_conversions2(){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); char c = 20 ; optional<int> opt(c); BOOST_CHECK( get(opt) == static_cast<int>(c)); float f = 21.22f ; optional<double> opt1; opt1 = f ; BOOST_CHECK(*get(&opt1) == static_cast<double>(f));}int test_main( int, char* [] ){ try { test_with_class_type(); test_with_builtin_types(); test_no_implicit_conversions(); test_conversions1(); test_conversions2(); } catch ( ... ) { BOOST_ERROR("Unexpected Exception caught!"); } return 0;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?