diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index dc29fea..952c75d 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -19,10 +19,10 @@ import testing ; [ run optional_test.cpp ] [ run optional_test_conversions_from_U.cpp ] [ run optional_test_tie.cpp ] - [ run optional_test_ref.cpp ] [ run optional_test_ref_assign_portable_minimum.cpp ] [ run optional_test_ref_assign_mutable_int.cpp ] [ run optional_test_ref_assign_const_int.cpp ] + [ run optional_test_ref_converting_ctor.cpp ] [ run optional_test_ref_portable_minimum.cpp ] [ run optional_test_inplace.cpp ] [ run optional_test_io.cpp ] diff --git a/test/optional_test_ref.cpp b/test/optional_test_ref.cpp deleted file mode 100644 index 6525ed3..0000000 --- a/test/optional_test_ref.cpp +++ /dev/null @@ -1,272 +0,0 @@ -// 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 -#include -#include - -#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" - -template -inline void check_ref_uninitialized_const ( optional const& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; -} -template -inline void check_ref_uninitialized ( optional& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; - - check_ref_uninitialized_const(opt); -} - -template -inline void check_ref_initialized_const ( optional const& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; -} - -template -inline void check_ref_initialized ( optional& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; - - check_ref_initialized_const(opt); -} - -template -inline void check_ref_value_const ( optional const& opt, T const& v, T const& z ) -{ - BOOST_CHECK( *opt == v ) ; - BOOST_CHECK( *opt != z ) ; - BOOST_CHECK( opt.get() == v ) ; - BOOST_CHECK( opt.get() != z ) ; -} - -template -inline void check_ref_value ( optional& opt, T const& v, T const& z ) -{ - BOOST_CHECK( *opt == v ) ; - BOOST_CHECK( *opt != z ) ; - BOOST_CHECK( opt.get() == v ) ; - BOOST_CHECK( opt.get() != z ) ; - - check_ref_value_const(opt,v,z); -} - -// -// Basic test. -// Check ordinary functionality: -// Initialization, assignment, comparison and value-accessing. -// -template -void test_basics( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T z(0); - - T original_a(1); - - T a(1); - - T b(2); - - T c(10); - - T& aref = a ; - T& bref = b ; - - // Default construction. - // 'def' state is Uninitialized. - // T::T() is not called - optional def ; - check_ref_uninitialized(def); - - // Direct initialization. - // 'oa' state is Initialized and binds to 'a' - // T::T( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - optional oa ( aref ) ; - check_is_pending_copy( ARG(T) ); - check_ref_initialized(oa); - check_ref_value(oa,a,z); - *oa = b ; // changes the value of 'a' through the reference - BOOST_CHECK( a == b ) ; - - - // Copy initialization. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - optional const oa2 ( oa ) ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized_const(oa2); - check_ref_value_const(oa2,a,z); - *oa2 = original_a ; // restores the value of 'a' through the reference - BOOST_CHECK( a == original_a ) ; - - optional ob ; - - // Value-Assignment upon Uninitialized optional. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - ob = a ; // Binds ob to a temporary non-const refererence to 'a' - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized(ob); - check_ref_value(ob,a,z); - a = c; - check_ref_value(ob,a,z); - - // Value-Assignment upon Initialized optional. - // T::operator= ( T const& x ) is used. - set_pending_assign( ARG(T) ) ; - ob = b ; // Rebinds 'ob' to 'b' (without changing 'a') - check_is_pending_assign( ARG(T) ) ; - check_ref_initialized(ob); - check_ref_value(ob,b,z); - BOOST_CHECK(a == c); // From a=c in previous test - b = c; - check_ref_value(ob,b,z); - - - // Assignment initialization. - // T::T ( T const& x ) is NOT used becasue the optional holds a reference. - set_pending_copy( ARG(T) ) ; - optional const oa3 = b ; - check_is_pending_copy( ARG(T) ) ; - check_ref_initialized_const(oa3); - check_ref_value_const(oa3,b,z); - - - // Assignment - // T::operator=( T const& x ) is used. - set_pending_assign( ARG(T) ) ; - oa = ob ; // Rebinds 'a' to 'b' - check_is_pending_assign( ARG(T) ) ; - check_ref_initialized(oa); - a = original_a ; - check_ref_value(oa,b,z); - - // Uninitializing Assignment upon Initialized Optional - // T::~T() is NOT used becasue the optional holds a reference. - 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_ref_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_ref_uninitialized(oa); - - - // Deinitialization of Initialized Optional - // T::~T() is NOT used becasue the optional holds a reference. - set_pending_dtor( ARG(T) ) ; - ob.reset(); - check_is_pending_dtor( ARG(T) ) ; - check_ref_uninitialized(ob); - - // Deinitialization of Uninitialized Optional - // T::~T() is not called this time - set_pending_dtor( ARG(T) ) ; - ob.reset(); - check_is_pending_dtor( ARG(T) ) ; - check_ref_uninitialized(ob); -} - - -void test_with_builtin_types() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(double) ); -} - -void test_with_class_type() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(X) ); - - BOOST_CHECK ( X::count == 0 ) ; -} - -void test_binding() -{ - int i = 0 ; - optional ori1 = i ; - BOOST_CHECK( &(*ori1) == &i ) ; - - optional ori2(i) ; - BOOST_CHECK( &(*ori2) == &i ) ; - - int const ci = 0 ; - optional orci1 = ci ; - BOOST_CHECK( &(*orci1) == &ci ) ; - - optional orci2(ci) ; - BOOST_CHECK( &(*orci2) == &ci ) ; -} - -int test_main( int, char* [] ) -{ - try - { - test_with_class_type(); - test_with_builtin_types(); - test_binding(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; -} - - diff --git a/test/optional_test_ref_converting_ctor.cpp b/test/optional_test_ref_converting_ctor.cpp new file mode 100644 index 0000000..d7df3dc --- /dev/null +++ b/test/optional_test_ref_converting_ctor.cpp @@ -0,0 +1,107 @@ +// Copyright (C) 2014 Andrzej Krzemienski. +// +// 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: akrzemi1@gmail.com + + +#include "boost/optional/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "boost/core/addressof.hpp" +#include "boost/core/enable_if.hpp" +#include "boost/core/lightweight_test.hpp" +#include "testable_classes.hpp" + +using boost::optional; +using boost::none; + +template +void test_converting_ctor() +{ + typename concrete_type_of::type v1(1), v2(2); + + { + optional o1 = v1, o1_ = v1, o2 = v2; + + BOOST_TEST(o1); + BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1)); + BOOST_TEST(o1_); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1)); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1)); + + BOOST_TEST(o2); + BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2)); + BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1)); + } + { + const optional o1 = v1, o1_ = v1, o2 = v2; + + BOOST_TEST(o1); + BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1)); + BOOST_TEST(o1_); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1)); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1)); + + BOOST_TEST(o2); + BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2)); + BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1)); + } +} + +template +void test_converting_ctor_for_noconst_const() +{ + typename concrete_type_of::type v1(1), v2(2); + + { + optional o1 = v1, o1_ = v1, o2 = v2; + + BOOST_TEST(o1); + BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1)); + BOOST_TEST(o1_); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1)); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1)); + + BOOST_TEST(o2); + BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2)); + BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1)); + } + { + const optional o1 = v1, o1_ = v1, o2 = v2; + + BOOST_TEST(o1); + BOOST_TEST(boost::addressof(*o1) == boost::addressof(v1)); + BOOST_TEST(o1_); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(v1)); + BOOST_TEST(boost::addressof(*o1_) == boost::addressof(*o1)); + + BOOST_TEST(o2); + BOOST_TEST(boost::addressof(*o2) == boost::addressof(v2)); + BOOST_TEST(boost::addressof(*o2) != boost::addressof(*o1)); + } +} + +template +void test_all_const_cases() +{ + test_converting_ctor(); + test_converting_ctor(); + test_converting_ctor_for_noconst_const(); +} + +int main() +{ + test_all_const_cases(); + test_all_const_cases(); + //test_all_const_cases(); + + return boost::report_errors(); +} diff --git a/test/optional_test_ref_portable_minimum.cpp b/test/optional_test_ref_portable_minimum.cpp index ddcffc9..e8439c9 100644 --- a/test/optional_test_ref_portable_minimum.cpp +++ b/test/optional_test_ref_portable_minimum.cpp @@ -23,6 +23,38 @@ using boost::optional; using boost::none; +struct CountingClass +{ + static int count; + static int assign_count; + CountingClass() { ++count; } + CountingClass(const CountingClass&) { ++count; } + CountingClass& operator=(const CountingClass&) { ++assign_count; return *this; } + ~CountingClass() { ++count; } +}; + +int CountingClass::count = 0; +int CountingClass::assign_count = 0; + +void test_no_object_creation() +{ + BOOST_TEST_EQ(0, CountingClass::count); + BOOST_TEST_EQ(0, CountingClass::assign_count); + { + CountingClass v1, v2; + optional oA(v1); + optional oB; + optional oC = oA; + oB = oA; + *oB = v2; + oC = none; + oC = optional(v2); + oB = none; + oA = oB; + } + BOOST_TEST_EQ(4, CountingClass::count); + BOOST_TEST_EQ(1, CountingClass::assign_count); +} template typename boost::enable_if< has_arrow >::type