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 + -
显示快捷键?