optional_test.cpp
来自「Boost provides free peer-reviewed portab」· C++ 代码 · 共 949 行 · 第 1/2 页
CPP
949 行
// 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<iostream>#include<stdexcept>#include<string>#define BOOST_ENABLE_ASSERT_HANDLER#include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin#include "boost/optional/optional.hpp"#ifdef __BORLANDC__#pragma hdrstop#endif#include "boost/none.hpp"#include "boost/test/minimal.hpp"#include "optional_test_common.cpp"void test_implicit_construction ( optional<double> opt, double v, double z ){ check_value(opt,v,z);}void test_implicit_construction ( optional<X> opt, X const& v, X const& z ){ check_value(opt,v,z);}void test_default_implicit_construction ( double, optional<double> opt ){ BOOST_CHECK(!opt);}void test_default_implicit_construction ( X const&, optional<X> opt ){ BOOST_CHECK(!opt);}//// Basic test.// Check ordinary functionality:// Initialization, assignment, comparison and value-accessing.//template<class T>void test_basics( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T a(1); // Default construction. // 'def' state is Uninitialized. // T::T() is not called (and it is not even defined) optional<T> def ; check_uninitialized(def); // Implicit construction // The first parameter is implicitely converted to optional<T>(a); test_implicit_construction(a,a,z); // Direct initialization. // 'oa' state is Initialized with 'a' // T::T( T const& x ) is used. set_pending_copy( ARG(T) ) ; optional<T> oa ( a ) ; check_is_not_pending_copy( ARG(T) ); check_initialized(oa); check_value(oa,a,z); T b(2); optional<T> ob ; // Value-Assignment upon Uninitialized optional. // T::T( T const& x ) is used. set_pending_copy( ARG(T) ) ; ob = a ; check_is_not_pending_copy( ARG(T) ) ; check_initialized(ob); check_value(ob,a,z); // Value-Assignment upon Initialized optional. // T::operator=( T const& x ) is used set_pending_assign( ARG(T) ) ; set_pending_copy ( ARG(T) ) ; set_pending_dtor ( ARG(T) ) ; ob = b ; check_is_not_pending_assign( ARG(T) ) ; check_is_pending_copy ( ARG(T) ) ; check_is_pending_dtor ( ARG(T) ) ; check_initialized(ob); check_value(ob,b,z); // Assignment initialization. // T::T ( T const& x ) is used to copy new value. set_pending_copy( ARG(T) ) ; optional<T> const oa2 ( oa ) ; check_is_not_pending_copy( ARG(T) ) ; check_initialized_const(oa2); check_value_const(oa2,a,z); // Assignment // T::operator= ( T const& x ) is used to copy new value. set_pending_assign( ARG(T) ) ; oa = ob ; check_is_not_pending_assign( ARG(T) ) ; check_initialized(oa); check_value(oa,b,z); // Uninitializing Assignment upon Initialized Optional // T::~T() is used to destroy previous value in oa. set_pending_dtor( ARG(T) ) ; set_pending_copy( ARG(T) ) ; oa = def ; check_is_not_pending_dtor( ARG(T) ) ; check_is_pending_copy ( ARG(T) ) ; check_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_uninitialized(oa); // Deinitialization of Initialized Optional // T::~T() is used to destroy previous value in ob. set_pending_dtor( ARG(T) ) ; ob.reset(); check_is_not_pending_dtor( ARG(T) ) ; check_uninitialized(ob); // Deinitialization of Uninitialized Optional // (Dtor is not called this time) set_pending_dtor( ARG(T) ) ; ob.reset(); check_is_pending_dtor( ARG(T) ) ; check_uninitialized(ob); }template<class T>void test_conditional_ctor_and_get_valur_or ( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T a(321); T z(123); optional<T> const cdef0(false,a); optional<T> def0(false,a); optional<T> def1 = boost::make_optional(false,a); // T is not within boost so ADL won't find make_optional unqualified check_uninitialized(def0); check_uninitialized(def1); optional<T> const co0(true,a); optional<T> o0(true,a); optional<T> o1 = boost::make_optional(true,a); // T is not within boost so ADL won't find make_optional unqualified check_initialized(o0); check_initialized(o1); check_value(o0,a,z); check_value(o1,a,z); T b = def0.get_value_or(z); BOOST_CHECK( b == z ) ; b = get_optional_value_or(def0,z); BOOST_CHECK( b == z ) ; b = o0.get_value_or(z); BOOST_CHECK( b == a ) ; b = get_optional_value_or(o0,z); BOOST_CHECK( b == a ) ; T const& crz = z ; T& rz = z ; T const& crzz = def0.get_value_or(crz); BOOST_CHECK( crzz == crz ) ; T& rzz = def0.get_value_or(rz); BOOST_CHECK( rzz == rz ) ; T const& crzzz = get_optional_value_or(cdef0,crz); BOOST_CHECK( crzzz == crz ) ; T& rzzz = get_optional_value_or(def0,rz); BOOST_CHECK( rzzz == rz ) ; T const& crb = o0.get_value_or(crz); BOOST_CHECK( crb == a ) ; T& rb = o0.get_value_or(rz); BOOST_CHECK( rb == b ) ; T const& crbb = get_optional_value_or(co0,crz); BOOST_CHECK( crbb == b ) ; T const& crbbb = get_optional_value_or(o0,crz); BOOST_CHECK( crbbb == b ) ; T& rbb = get_optional_value_or(o0,rz); BOOST_CHECK( rbb == b ) ; T& ra = a ; optional<T&> defref(false,ra); BOOST_CHECK(!defref); optional<T&> ref(true,ra); BOOST_CHECK(!!ref); a = T(432); BOOST_CHECK( *ref == a ) ; T& r1 = defref.get_value_or(z); BOOST_CHECK( r1 == z ) ; T& r2 = ref.get_value_or(z); BOOST_CHECK( r2 == a ) ;}//// Test Direct Value Manipulation//template<class T>void test_direct_value_manip( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T x(3); optional<T> const c_opt0(x) ; optional<T> opt0(x); BOOST_CHECK( c_opt0.get().V() == x.V() ) ; BOOST_CHECK( opt0.get().V() == x.V() ) ; BOOST_CHECK( c_opt0->V() == x.V() ) ; BOOST_CHECK( opt0->V() == x.V() ) ; BOOST_CHECK( (*c_opt0).V() == x.V() ) ; BOOST_CHECK( (* opt0).V() == x.V() ) ; T y(4); opt0 = y ; BOOST_CHECK( get(opt0).V() == y.V() ) ;}//// Test Uninitialized access assert//template<class T>void test_uninitialized_access( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); optional<T> def ; bool passed = false ; try { // This should throw because 'def' is uninitialized T const& n = def.get() ; unused_variable(n); passed = true ; } catch (...) {} BOOST_CHECK(!passed); passed = false ; try { // This should throw because 'def' is uninitialized T const& n = *def ; unused_variable(n); passed = true ; } catch (...) {} BOOST_CHECK(!passed); passed = false ; try { T v(5) ; unused_variable(v); // This should throw because 'def' is uninitialized *def = v ; passed = true ; } catch (...) {} BOOST_CHECK(!passed); passed = false ; try { // This should throw because 'def' is uninitialized T v = *(def.operator->()) ; unused_variable(v); passed = true ; } catch (...) {} BOOST_CHECK(!passed);}#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0void prevent_buggy_optimization( bool v ) {}#endif//// Test Direct Initialization of optional for a T with throwing copy-ctor.//template<class T>void test_throwing_direct_init( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T a(6); int count = get_instance_count( ARG(T) ) ; set_throw_on_copy( ARG(T) ) ; bool passed = false ; try { // This should: // Attempt to copy construct 'a' and throw. // 'opt' won't be constructed. set_pending_copy( ARG(T) ) ;#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0 // Intel C++ 7.0 specific: // For some reason, when "check_is_not_pending_copy", // after the exception block is reached, // X::pending_copy==true even though X's copy ctor set it to false. // I guessed there is some sort of optimization bug, // and it seems to be the since the following additional line just // solves the problem (!?) prevent_buggy_optimization(X::pending_copy);#endif optional<T> opt(a) ; passed = true ; } catch ( ... ){} BOOST_CHECK(!passed); check_is_not_pending_copy( ARG(T) ); check_instance_count(count, ARG(T) ); reset_throw_on_copy( ARG(T) ) ;}//// Test Value Assignment to an Uninitialized optional for a T with a throwing copy-ctor//template<class T>void test_throwing_val_assign_on_uninitialized( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T a(7); int count = get_instance_count( ARG(T) ) ; set_throw_on_copy( ARG(T) ) ; optional<T> opt ; bool passed = false ; try { // This should: // Attempt to copy construct 'a' and throw. // opt should be left uninitialized. set_pending_copy( ARG(T) ) ; opt.reset( a ); passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); check_is_not_pending_copy( ARG(T) ); check_instance_count(count, ARG(T) ); check_uninitialized(opt); reset_throw_on_copy( ARG(T) ) ;}//// Test Value Reset on an Initialized optional for a T with a throwing copy-ctor//template<class T>void test_throwing_val_assign_on_initialized( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T a(8); T b(9); T x(-1); int count = get_instance_count( ARG(T) ) ; optional<T> opt ( b ) ; ++ count ; check_instance_count(count, ARG(T) ); check_value(opt,b,z); set_throw_on_assign( ARG(T) ) ; bool passed = false ; try { // This should: // Attempt to assign 'a' and throw. // opt 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) ) ; opt.reset ( a ) ; passed = true ; } catch ( ... ) {} BOOST_CHECK(!passed); check_is_not_pending_assign( ARG(T) ); check_instance_count(count, ARG(T) ); check_initialized(opt); check_value(opt,x,z); reset_throw_on_assign ( ARG(T) ) ;}//// Test Copy Initialization from an Initialized optional for a T with a throwing copy-ctor//template<class T>void test_throwing_copy_initialization( T const* ){ TRACE( std::endl << BOOST_CURRENT_FUNCTION ); T z(0); T a(10); optional<T> opt (a);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?