⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optional_test.cpp

📁 C++的一个好库。。。现在很流行
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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/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) ) ;
  set_pending_copy  ( ARG(T) ) ;
  set_pending_dtor  ( ARG(T) ) ;
  oa = ob ;
  check_is_not_pending_assign( ARG(T) ) ;
  check_is_pending_copy      ( ARG(T) ) ;
  check_is_pending_dtor      ( 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);
}

//
// 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.0
void 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);

  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 ( ... ) {}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -