forked from boostorg/optional
Additional tests
[SVN r19996]
This commit is contained in:
@ -26,233 +26,18 @@
|
||||
|
||||
#include "boost/test/minimal.hpp"
|
||||
|
||||
#ifdef ENABLE_TRACE
|
||||
#define TRACE(msg) std::cout << msg << std::endl ;
|
||||
#else
|
||||
#define TRACE(msg)
|
||||
#endif
|
||||
#include "optional_test_common.cpp"
|
||||
|
||||
namespace boost {
|
||||
|
||||
void assertion_failed (char const * expr, char const * func, char const * file, long )
|
||||
void test_implicit_construction ( optional<double> opt, double v, double z )
|
||||
{
|
||||
using std::string ;
|
||||
string msg = string("Boost assertion failure for \"")
|
||||
+ string(expr)
|
||||
+ string("\" at file \"")
|
||||
+ string(file)
|
||||
+ string("\" function \"")
|
||||
+ string(func)
|
||||
+ string("\"") ;
|
||||
|
||||
TRACE(msg);
|
||||
|
||||
throw std::logic_error(msg);
|
||||
check_value(opt,v,z);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using boost::optional ;
|
||||
|
||||
template<class T> inline void unused_variable ( T const& ) {}
|
||||
|
||||
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
|
||||
using boost::swap ;
|
||||
using boost::get_pointer ;
|
||||
#endif
|
||||
|
||||
// MSVC6.0 does not support comparisons of optional against a literal null pointer value (0)
|
||||
// via the safe_bool operator.
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1
|
||||
#define BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
#endif
|
||||
|
||||
#define ARG(T) (static_cast< T const* >(0))
|
||||
|
||||
//
|
||||
// Helper class used to verify the lifetime managment of the values held by optional
|
||||
//
|
||||
class X
|
||||
void test_implicit_construction ( optional<X> opt, X const& v, X const& z )
|
||||
{
|
||||
public :
|
||||
|
||||
X ( int av ) : v(av)
|
||||
{
|
||||
++ count ;
|
||||
|
||||
TRACE ( "X::X(" << av << "). this=" << this ) ;
|
||||
check_value(opt,v,z);
|
||||
}
|
||||
|
||||
X ( X const& rhs ) : v(rhs.v)
|
||||
{
|
||||
pending_copy = false ;
|
||||
|
||||
TRACE ( "X::X( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
|
||||
|
||||
if ( throw_on_copy )
|
||||
{
|
||||
TRACE ( "throwing exception in X's copy ctor" ) ;
|
||||
throw 0 ;
|
||||
}
|
||||
|
||||
++ count ;
|
||||
}
|
||||
|
||||
~X()
|
||||
{
|
||||
pending_dtor = false ;
|
||||
|
||||
-- count ;
|
||||
|
||||
TRACE ( "X::~X(). v=" << v << " this=" << this );
|
||||
}
|
||||
|
||||
X& operator= ( X const& rhs )
|
||||
{
|
||||
v = rhs.v ;
|
||||
|
||||
TRACE ( "X::operator =( X const& rhs). this=" << this << " rhs.v=" << rhs.v ) ;
|
||||
|
||||
return *this ;
|
||||
}
|
||||
|
||||
friend bool operator == ( X const& a, X const& b )
|
||||
{ return a.v == b.v ; }
|
||||
|
||||
friend bool operator != ( X const& a, X const& b )
|
||||
{ return a.v != b.v ; }
|
||||
|
||||
friend bool operator < ( X const& a, X const& b )
|
||||
{ return a.v < b.v ; }
|
||||
|
||||
int V() const { return v ; }
|
||||
int& V() { return v ; }
|
||||
|
||||
static int count ;
|
||||
static bool pending_copy ;
|
||||
static bool pending_dtor ;
|
||||
static bool throw_on_copy ;
|
||||
|
||||
private :
|
||||
|
||||
int v ;
|
||||
|
||||
private :
|
||||
|
||||
X() ;
|
||||
} ;
|
||||
|
||||
|
||||
int X::count = 0 ;
|
||||
bool X::pending_copy = false ;
|
||||
bool X::pending_dtor = false ;
|
||||
bool X::throw_on_copy = false ;
|
||||
|
||||
inline void set_pending_copy ( X const* x ) { X::pending_copy = true ; }
|
||||
inline void set_pending_dtor ( X const* x ) { X::pending_dtor = true ; }
|
||||
inline void set_throw_on_copy ( X const* x ) { X::throw_on_copy = true ; }
|
||||
inline void reset_throw_on_copy ( X const* x ) { X::throw_on_copy = false ; }
|
||||
inline void check_is_pending_copy ( X const* x ) { BOOST_CHECK( X::pending_copy ) ; }
|
||||
inline void check_is_pending_dtor ( X const* x ) { BOOST_CHECK( X::pending_dtor ) ; }
|
||||
inline void check_is_not_pending_copy( X const* x ) { BOOST_CHECK( !X::pending_copy ) ; }
|
||||
inline void check_is_not_pending_dtor( X const* x ) { BOOST_CHECK( !X::pending_dtor ) ; }
|
||||
inline void check_instance_count ( int c, X const* x ) { BOOST_CHECK( X::count == c ) ; }
|
||||
inline int get_instance_count ( X const* x ) { return X::count ; }
|
||||
|
||||
inline void set_pending_copy (...) {}
|
||||
inline void set_pending_dtor (...) {}
|
||||
inline void set_throw_on_copy (...) {}
|
||||
inline void reset_throw_on_copy (...) {}
|
||||
inline void check_is_pending_copy (...) {}
|
||||
inline void check_is_pending_dtor (...) {}
|
||||
inline void check_is_not_pending_copy(...) {}
|
||||
inline void check_is_not_pending_dtor(...) {}
|
||||
inline void check_instance_count (...) {}
|
||||
inline int get_instance_count (...) { return 0 ; }
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void check_uninitialized_const ( optional<T> const& opt )
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt == 0 ) ;
|
||||
#endif
|
||||
BOOST_CHECK( !opt ) ;
|
||||
BOOST_CHECK( !get_pointer(opt) ) ;
|
||||
BOOST_CHECK( !opt.get() ) ;
|
||||
}
|
||||
template<class T>
|
||||
inline void check_uninitialized ( optional<T>& opt )
|
||||
{
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt == 0 ) ;
|
||||
#endif
|
||||
BOOST_CHECK( !opt ) ;
|
||||
BOOST_CHECK( !get_pointer(opt) ) ;
|
||||
BOOST_CHECK( !opt.get() ) ;
|
||||
|
||||
check_uninitialized_const(opt);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_initialized_const ( optional<T> const& opt )
|
||||
{
|
||||
BOOST_CHECK( opt ) ;
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt != 0 ) ;
|
||||
#endif
|
||||
|
||||
BOOST_CHECK ( !!opt ) ;
|
||||
BOOST_CHECK ( get_pointer(opt) ) ;
|
||||
BOOST_CHECK ( opt.get() ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_initialized ( optional<T>& opt )
|
||||
{
|
||||
BOOST_CHECK( opt ) ;
|
||||
|
||||
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
|
||||
BOOST_CHECK( opt != 0 ) ;
|
||||
#endif
|
||||
|
||||
BOOST_CHECK ( !!opt ) ;
|
||||
BOOST_CHECK ( get_pointer(opt) ) ;
|
||||
BOOST_CHECK ( opt.get() ) ;
|
||||
|
||||
check_initialized_const(opt);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_value_const ( optional<T> const& opt, T const& v, T const& z )
|
||||
{
|
||||
BOOST_CHECK( *opt == v ) ;
|
||||
BOOST_CHECK( *opt != z ) ;
|
||||
BOOST_CHECK( (*(opt.operator->()) == v) ) ;
|
||||
BOOST_CHECK( *get_pointer(opt) == v ) ;
|
||||
BOOST_CHECK( *opt.get() == v ) ;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void check_value ( optional<T>& opt, T const& v, T const& z )
|
||||
{
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, <= 1200) // 1200 == VC++ 6.0
|
||||
// For some reason, VC6.0 is creating a temporary while evaluating (*opt == v),
|
||||
// so we need to turn throw on copy off first.
|
||||
reset_throw_on_copy( ARG(T) ) ;
|
||||
#endif
|
||||
|
||||
BOOST_CHECK( *opt == v ) ;
|
||||
BOOST_CHECK( *opt != z ) ;
|
||||
BOOST_CHECK( (*(opt.operator->()) == v) ) ;
|
||||
BOOST_CHECK( *get_pointer(opt) == v ) ;
|
||||
BOOST_CHECK( *opt.get() == v ) ;
|
||||
|
||||
check_value_const(opt,v,z);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Basic test.
|
||||
// Check ordinary functionality:
|
||||
@ -273,6 +58,10 @@ void test_basics( T const* )
|
||||
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.
|
||||
@ -282,7 +71,6 @@ void test_basics( T const* )
|
||||
check_initialized(oa);
|
||||
check_value(oa,a,z);
|
||||
|
||||
|
||||
T b(2);
|
||||
|
||||
optional<T> ob ;
|
||||
@ -290,19 +78,18 @@ void test_basics( T const* )
|
||||
// Value-Assignment upon Uninitialized optional.
|
||||
// T::T ( T const& x ) is used.
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
ob.reset(a) ;
|
||||
ob = a ;
|
||||
check_is_not_pending_copy( ARG(T) ) ;
|
||||
check_initialized(ob);
|
||||
check_value(ob,a,z);
|
||||
|
||||
// Value-Assignment upon Initialized optional.
|
||||
// This uses T::operator= ( T const& x ) directly
|
||||
// on the reference returned by operator*()
|
||||
// T::T ( T const& x ) is used
|
||||
set_pending_dtor( ARG(T) ) ;
|
||||
set_pending_copy( ARG(T) ) ;
|
||||
*ob = b ;
|
||||
check_is_pending_dtor( ARG(T) ) ;
|
||||
check_is_pending_copy( ARG(T) ) ;
|
||||
ob = b ;
|
||||
check_is_not_pending_dtor( ARG(T) ) ;
|
||||
check_is_not_pending_copy( ARG(T) ) ;
|
||||
check_initialized(ob);
|
||||
check_value(ob,b,z);
|
||||
|
||||
@ -371,6 +158,9 @@ void test_direct_value_manip( T const* )
|
||||
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() ) ;
|
||||
|
||||
@ -378,10 +168,8 @@ void test_direct_value_manip( T const* )
|
||||
BOOST_CHECK( (* opt0).V() == x.V() ) ;
|
||||
|
||||
T y(4);
|
||||
*opt0 = y ;
|
||||
BOOST_CHECK( (*opt0).V() == y.V() ) ;
|
||||
|
||||
BOOST_CHECK( x < (*opt0) ) ;
|
||||
opt0 = y ;
|
||||
BOOST_CHECK( get(opt0).V() == y.V() ) ;
|
||||
}
|
||||
|
||||
//
|
||||
@ -396,6 +184,17 @@ void test_uninitialized_access( T const* )
|
||||
|
||||
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 ;
|
||||
@ -706,8 +505,6 @@ void test_no_throwing_swap( T const* )
|
||||
|
||||
int count = get_instance_count( ARG(T) ) ;
|
||||
|
||||
using boost::swap ;
|
||||
|
||||
swap(def0,def1);
|
||||
check_uninitialized(def0);
|
||||
check_uninitialized(def1);
|
||||
@ -819,17 +616,37 @@ void test_relops( T const* )
|
||||
BOOST_CHECK ( !(def0 != def0) ) ;
|
||||
BOOST_CHECK ( !(opt0 != opt0) ) ;
|
||||
|
||||
// If both are uininitalized they compare equal
|
||||
BOOST_CHECK ( def0 == def1 ) ;
|
||||
// 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 ) ;
|
||||
|
||||
// If only one is initialized they compare unequal
|
||||
BOOST_CHECK ( def0 != opt0 ) ;
|
||||
BOOST_CHECK ( !(def1 == opt1) ) ;
|
||||
// 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 ) ;
|
||||
}
|
||||
|
||||
void test_with_builtin_types()
|
||||
@ -893,7 +710,7 @@ void test_no_implicit_conversions()
|
||||
}
|
||||
|
||||
struct A {} ;
|
||||
void test_conversions()
|
||||
void test_conversions1()
|
||||
{
|
||||
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
|
||||
|
||||
@ -914,6 +731,20 @@ void test_conversions()
|
||||
#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
|
||||
@ -921,7 +752,8 @@ int test_main( int, char* [] )
|
||||
test_with_class_type();
|
||||
test_with_builtin_types();
|
||||
test_no_implicit_conversions();
|
||||
test_conversions();
|
||||
test_conversions1();
|
||||
test_conversions2();
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
|
Reference in New Issue
Block a user