diff options
Diffstat (limited to 'libs/optional/test')
34 files changed, 2299 insertions, 1478 deletions
diff --git a/libs/optional/test/Jamfile.v2 b/libs/optional/test/Jamfile.v2 index aeb0900fa..d654545fc 100644 --- a/libs/optional/test/Jamfile.v2 +++ b/libs/optional/test/Jamfile.v2 @@ -17,15 +17,27 @@ import testing ; { test-suite optional : [ run optional_test.cpp ] + [ run optional_test_swap.cpp ] + [ run optional_test_conversions_from_U.cpp ] [ run optional_test_tie.cpp ] - [ run optional_test_ref.cpp ] - [ run optional_test_inplace.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_convert_assign_non_int.cpp ] + [ run optional_test_ref_convert_assign_mutable_int.cpp ] + [ run optional_test_ref_convert_assign_const_int.cpp ] + [ run optional_test_ref_portable_minimum.cpp ] + [ run optional_test_ref_move.cpp ] + [ run optional_test_inplace_factory.cpp ] [ run optional_test_io.cpp ] [ run optional_test_move.cpp ] + [ run optional_test_noexcept_move.cpp ] [ run optional_test_equals_none.cpp ] [ run optional_test_value_access.cpp ] [ run optional_test_emplace.cpp ] [ run optional_test_minimum_requirements.cpp ] + [ run optional_test_msvc_bug_workaround.cpp ] [ compile-fail optional_test_fail1.cpp ] [ compile-fail optional_test_fail3a.cpp ] [ compile-fail optional_test_fail3b.cpp ] @@ -41,7 +53,10 @@ import testing ; [ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ] + [ compile-fail optional_test_fail_convert_from_null.cpp ] [ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ] [ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ] + [ compile-fail optional_test_fail_io_without_io.cpp ] + [ compile-fail optional_test_fail_convert_assign_of_enums.cpp ] ; } diff --git a/libs/optional/test/optional_ref_assign_test_defs.hpp b/libs/optional/test/optional_ref_assign_test_defs.hpp new file mode 100644 index 000000000..292d0fc35 --- /dev/null +++ b/libs/optional/test/optional_ref_assign_test_defs.hpp @@ -0,0 +1,197 @@ +// 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 + +#ifndef BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP +#define BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP + +#include "boost/optional/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "boost/core/addressof.hpp" +#include "testable_classes.hpp" + +using boost::optional; +using boost::none; +using boost::addressof; + +template <typename T> +void test_copy_assignment_for_const() +{ + const typename concrete_type_of<T>::type v(2); + optional<const T&> o; + o = optional<const T&>(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST(val(*o) == val(v)); + BOOST_TEST(val(*o) == 2); +} + +template <typename T> +void test_copy_assignment_for_noconst_const() +{ + typename concrete_type_of<T>::type v(2); + optional<const T&> o; + o = optional<const T&>(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST(val(*o) == val(v)); + BOOST_TEST(val(*o) == 2); + + val(v) = 9; + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 9); + BOOST_TEST_EQ(val(v), 9); +} + +template <typename T> +void test_copy_assignment_for() +{ + typename concrete_type_of<T>::type v(2); + optional<T&> o; + o = optional<T&>(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST(val(*o) == val(v)); + BOOST_TEST(val(*o) == 2); + + val(v) = 9; + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 9); + BOOST_TEST_EQ(val(v), 9); + + val(*o) = 7; + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 7); + BOOST_TEST_EQ(val(v), 7); +} + +template <typename T> +void test_rebinding_assignment_semantics_const() +{ + const typename concrete_type_of<T>::type v(2), w(7); + optional<const T&> o(v); + + BOOST_TEST(o); + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + o = optional<const T&>(w); + BOOST_TEST_EQ(val(v), 2); + + BOOST_TEST(o); + BOOST_TEST(addressof(*o) != addressof(v)); + BOOST_TEST_NE(val(*o), val(v)); + BOOST_TEST_NE(val(*o), 2); + + BOOST_TEST(addressof(*o) == addressof(w)); + BOOST_TEST_EQ(val(*o), val(w)); + BOOST_TEST_EQ(val(*o), 7); +} + +template <typename T> +void test_rebinding_assignment_semantics_noconst_const() +{ + typename concrete_type_of<T>::type v(2), w(7); + optional<const T&> o(v); + + BOOST_TEST(o); + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + o = optional<const T&>(w); + BOOST_TEST_EQ(val(v), 2); + + BOOST_TEST(o); + BOOST_TEST(addressof(*o) != addressof(v)); + BOOST_TEST_NE(val(*o), val(v)); + BOOST_TEST_NE(val(*o), 2); + + BOOST_TEST(addressof(*o) == addressof(w)); + BOOST_TEST_EQ(val(*o), val(w)); + BOOST_TEST_EQ(val(*o), 7); +} + +template <typename T> +void test_rebinding_assignment_semantics() +{ + typename concrete_type_of<T>::type v(2), w(7); + optional<T&> o(v); + + BOOST_TEST(o); + BOOST_TEST(addressof(*o) == addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + o = optional<T&>(w); + BOOST_TEST_EQ(val(v), 2); + + BOOST_TEST(o); + BOOST_TEST(addressof(*o) != addressof(v)); + BOOST_TEST_NE(val(*o), val(v)); + BOOST_TEST_NE(val(*o), 2); + + BOOST_TEST(addressof(*o) == addressof(w)); + BOOST_TEST_EQ(val(*o), val(w)); + BOOST_TEST_EQ(val(*o), 7); + + val(*o) = 8; + BOOST_TEST(addressof(*o) == addressof(w)); + BOOST_TEST_EQ(val(*o), val(w)); + BOOST_TEST_EQ(val(*o), 8); + BOOST_TEST_EQ(val(w), 8); + BOOST_TEST_EQ(val(v), 2); +} + +template <typename T> +void test_converting_assignment() +{ + typename concrete_type_of<T>::type v1(1), v2(2), v3(3); + optional<T&> oA(v1), oB(none); + + oA = v2; + BOOST_TEST(oA); + BOOST_TEST(addressof(*oA) == addressof(v2)); + + oB = v3; + BOOST_TEST(oB); + BOOST_TEST(addressof(*oB) == addressof(v3)); +} + +template <typename T> +void test_converting_assignment_for_noconst_const() +{ + typename concrete_type_of<T>::type v1(1), v2(2), v3(3); + optional<const T&> oA(v1), oB(none); + + oA = v2; + BOOST_TEST(oA); + BOOST_TEST(addressof(*oA) == addressof(v2)); + + oB = v3; + BOOST_TEST(oB); + BOOST_TEST(addressof(*oB) == addressof(v3)); +} + +#endif //BOOST_OPTIONAL_TEST_OPTIONAL_REF_ASSIGN_TEST_DEFS_AK_07JAN2015_HPP + diff --git a/libs/optional/test/optional_test.cpp b/libs/optional/test/optional_test.cpp index e34ce7e23..359186741 100644 --- a/libs/optional/test/optional_test.cpp +++ b/libs/optional/test/optional_test.cpp @@ -906,372 +906,6 @@ void test_no_implicit_conversions() test_no_implicit_conversions_impl(p); } -struct A {} ; -void test_conversions1() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - -#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR - char c = 20 ; - optional<char> opt0(c); - optional<int> opt1(opt0); - BOOST_CHECK(*opt1 == static_cast<int>(c)); -#endif - -#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT - float f = 21.22f ; - double d = f ; - optional<float> opt2(f) ; - optional<double> opt3 ; - opt3 = opt2 ; - BOOST_CHECK(*opt3 == d); -#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)); -} - - -namespace optional_swap_test -{ - class default_ctor_exception : public std::exception {} ; - class copy_ctor_exception : public std::exception {} ; - class assignment_exception : public std::exception {} ; - - // - // Base class for swap test classes. Its assignment should not be called, when swapping - // optional<T> objects. (The default std::swap would do so.) - // - class base_class_with_forbidden_assignment - { - public: - base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &) - { - BOOST_CHECK(!"The assignment should not be used while swapping!"); - throw assignment_exception(); - } - - virtual ~base_class_with_forbidden_assignment() {} - }; - - // - // Class without default constructor - // - class class_without_default_ctor : public base_class_with_forbidden_assignment - { - public: - char data; - explicit class_without_default_ctor(char arg) : data(arg) {} - }; - - // - // Class whose default constructor should not be used by optional::swap! - // - class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment - { - public: - char data; - explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {} - - class_whose_default_ctor_should_not_be_used() - { - BOOST_CHECK(!"This default constructor should not be used while swapping!"); - throw default_ctor_exception(); - } - }; - - // - // Class whose default constructor should be used by optional::swap. - // Its copy constructor should be avoided! - // - class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment - { - public: - char data; - explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { } - - class_whose_default_ctor_should_be_used() : data('\0') { } - - class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &) - { - BOOST_CHECK(!"This copy constructor should not be used while swapping!"); - throw copy_ctor_exception(); - } - }; - - // - // Class template whose default constructor should be used by optional::swap. - // Its copy constructor should be avoided! - // - template <class T> - class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment - { - public: - T data; - explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { } - - template_whose_default_ctor_should_be_used() : data('\0') { } - - template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &) - { - BOOST_CHECK(!"This copy constructor should not be used while swapping!"); - throw copy_ctor_exception(); - } - }; - - // - // Class whose explicit constructor should be used by optional::swap. - // Its other constructors should be avoided! - // - class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment - { - public: - char data; - explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { } - - class_whose_explicit_ctor_should_be_used() - { - BOOST_CHECK(!"This default constructor should not be used while swapping!"); - throw default_ctor_exception(); - } - - class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &) - { - BOOST_CHECK(!"This copy constructor should not be used while swapping!"); - throw copy_ctor_exception(); - } - }; - - void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs) - { - std::swap(lhs.data, rhs.data); - } - - void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs) - { - std::swap(lhs.data, rhs.data); - } - - void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs) - { - std::swap(lhs.data, rhs.data); - } - - void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs) - { - std::swap(lhs.data, rhs.data); - } - - template <class T> - void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs) - { - std::swap(lhs.data, rhs.data); - } - - // - // optional<T>::swap should be customized when neither the copy constructor - // nor the default constructor of T are supposed to be used when swapping, e.g., - // for the following type T = class_whose_explicit_ctor_should_be_used. - // - void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y) - { - bool hasX(x); - bool hasY(y); - - if ( !hasX && !hasY ) - return; - - if( !hasX ) - x = boost::in_place('\0'); - else if ( !hasY ) - y = boost::in_place('\0'); - - optional_swap_test::swap(*x,*y); - - if( !hasX ) - y = boost::none ; - else if( !hasY ) - x = boost::none ; - } - - -} // End of namespace optional_swap_test. - - -namespace boost { - -// -// Compile time tweaking on whether or not swap should use the default constructor: -// - -template <> struct optional_swap_should_use_default_constructor< - optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ; - -template <> struct optional_swap_should_use_default_constructor< - optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ; - -template <class T> struct optional_swap_should_use_default_constructor< - optional_swap_test::template_whose_default_ctor_should_be_used<T> > : mpl::true_ {} ; - - -// -// Specialization of boost::swap: -// -template <> -void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y) -{ - optional_swap_test::swap(x, y); -} - -} // namespace boost - - -namespace std { - -// -// Specializations of std::swap: -// - -template <> -void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y) -{ - optional_swap_test::swap(x, y); -} - -template <> -void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y) -{ - optional_swap_test::swap(x, y); -} - -template <> -void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y) -{ - optional_swap_test::swap(x, y); -} - -template <> -void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y) -{ - optional_swap_test::swap(x, y); -} - -} // namespace std - - -// -// Tests whether the swap function works properly for optional<T>. -// Assumes that T has one data member, of type char. -// Returns true iff the test is passed. -// -template <class T> -bool test_swap_function( T const* ) -{ - const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); - try - { - optional<T> obj1; - optional<T> obj2('a'); - - // Self-swap should not have any effect. - swap(obj1, obj1); - swap(obj2, obj2); - BOOST_CHECK(!obj1); - BOOST_CHECK(!!obj2 && obj2->data == 'a'); - - // Call non-member swap. - swap(obj1, obj2); - - // Test if obj1 and obj2 are really swapped. - BOOST_CHECK(!!obj1 && obj1->data == 'a'); - BOOST_CHECK(!obj2); - - // Call non-member swap one more time. - swap(obj1, obj2); - - // Test if obj1 and obj2 are swapped back. - BOOST_CHECK(!obj1); - BOOST_CHECK(!!obj2 && obj2->data == 'a'); - } - catch(const std::exception &) - { - // The swap function should not throw, for our test cases. - return false ; - } - return boost::minimal_test::errors_counter() == counter_before_test ; -} - -// -// Tests whether the optional<T>::swap member function works properly. -// Assumes that T has one data member, of type char. -// Returns true iff the test is passed. -// -template <class T> -bool test_swap_member_function( T const* ) -{ - const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter(); - try - { - optional<T> obj1; - optional<T> obj2('a'); - - // Self-swap should not have any effect. - obj1.swap(obj1); - obj2.swap(obj2); - BOOST_CHECK(!obj1); - BOOST_CHECK(!!obj2 && obj2->data == 'a'); - - // Call member swap. - obj1.swap(obj2); - - // Test if obj1 and obj2 are really swapped. - BOOST_CHECK(!!obj1 && obj1->data == 'a'); - BOOST_CHECK(!obj2); - - // Call member swap one more time. - obj1.swap(obj2); - - // Test if obj1 and obj2 are swapped back. - BOOST_CHECK(!obj1); - BOOST_CHECK(!!obj2 && obj2->data == 'a'); - } - catch(const std::exception &) - { - // The optional<T>::swap member function should not throw, for our test cases. - return false ; - } - return boost::minimal_test::errors_counter() == counter_before_test ; -} - - -// -// Tests compile time tweaking of swap, by means of -// optional_swap_should_use_default_constructor. -// -void test_swap_tweaking() -{ - BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) ); - BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) ); - BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) ); - BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) ); - BOOST_CHECK( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) ); - BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) ); - BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) ); - BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) ); - BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) ); - BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) ); -} // Test for support for classes with overridden operator& class CustomAddressOfClass @@ -1307,9 +941,6 @@ int test_main( int, char* [] ) test_with_class_type(); test_with_builtin_types(); test_no_implicit_conversions(); - test_conversions1(); - test_conversions2(); - test_swap_tweaking(); test_custom_addressof_operator(); } catch ( ... ) diff --git a/libs/optional/test/optional_test_common.cpp b/libs/optional/test/optional_test_common.cpp index 532b74e7a..a527bd715 100644 --- a/libs/optional/test/optional_test_common.cpp +++ b/libs/optional/test/optional_test_common.cpp @@ -51,6 +51,8 @@ using boost::get_pointer ; // via the safe_bool operator. #if BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1300) ) // 1300 == VC++ 7.1 #define BOOST_OPTIONAL_NO_NULL_COMPARE +#else +#define BOOST_OPTIONAL_NO_NULL_COMPARE // Andrzej: I also disable 0 comparison everywhere #endif #define ARG(T) (static_cast< T const* >(0)) diff --git a/libs/optional/test/optional_test_conversions_from_U.cpp b/libs/optional/test/optional_test_conversions_from_U.cpp new file mode 100644 index 000000000..57d821577 --- /dev/null +++ b/libs/optional/test/optional_test_conversions_from_U.cpp @@ -0,0 +1,111 @@ +// 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/lightweight_test.hpp" + +using boost::optional; + + +// testing types: +// X is convertible to Y +// ADeriv is convertible to ABase +struct X +{ + int val; + explicit X(int v) : val(v) {} +}; + +struct Y +{ + int yval; + Y(X const& x) : yval(x.val) {} + friend bool operator==(Y const& l, Y const& r) { return l.yval == r.yval; } +}; + +struct ABase +{ + int val; + explicit ABase(int v) : val(v) {} + friend bool operator==(ABase const& l, ABase const& r) { return l.val == r.val; } +}; + +struct ADeriv : ABase +{ + explicit ADeriv(int v) : ABase(v) {} +}; + + +template <typename T, typename U> +void test_convert_optional_U_to_optional_T_for() +{ +#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR + { + optional<U> ou(U(8)); + optional<T> ot1(ou); + BOOST_TEST(ot1); + BOOST_TEST(*ot1 == T(*ou)); + } +#endif + +#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT + { + optional<U> ou(U(8)); + optional<T> ot2; + ot2 = ou; + BOOST_TEST(ot2); + BOOST_TEST(*ot2 == T(*ou)); + } +#endif +} + +void test_convert_optional_U_to_optional_T() +{ + test_convert_optional_U_to_optional_T_for<Y, X>(); + test_convert_optional_U_to_optional_T_for<ABase, ADeriv>(); + test_convert_optional_U_to_optional_T_for<long, short>(); + test_convert_optional_U_to_optional_T_for<double, float>(); +} + +template <typename T, typename U> +void test_convert_U_to_optional_T_for() +{ + U u(8); + optional<T> ot1(u); + BOOST_TEST(ot1); + BOOST_TEST(*ot1 == T(u)); + + optional<T> ot2; + ot2 = u; + BOOST_TEST(ot2); + BOOST_TEST(*ot2 == T(u)); +} + +void test_convert_U_to_optional_T() +{ + test_convert_U_to_optional_T_for<Y, X>(); + test_convert_U_to_optional_T_for<ABase, ADeriv>(); + test_convert_U_to_optional_T_for<long, short>(); + test_convert_U_to_optional_T_for<double, float>(); +} + +int main() +{ + test_convert_optional_U_to_optional_T(); + test_convert_U_to_optional_T(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_emplace.cpp b/libs/optional/test/optional_test_emplace.cpp index b55c1ebad..117f26ca3 100644 --- a/libs/optional/test/optional_test_emplace.cpp +++ b/libs/optional/test/optional_test_emplace.cpp @@ -8,19 +8,6 @@ // // You are welcome to contact the author at: // akrzemi1@gmail.com -// -// Revisions: -// -#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/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ -#include "boost/static_assert.hpp" #include "boost/optional/optional.hpp" @@ -28,15 +15,15 @@ #pragma hdrstop #endif +#include "boost/core/lightweight_test.hpp" #include "boost/none.hpp" -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - //#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT //#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR +using boost::optional; +using boost::none; + #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) class Guard @@ -68,36 +55,36 @@ void test_emplace() optional<Guard> o; o.emplace(); - BOOST_CHECK(o); - BOOST_CHECK(0 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(0 == o->which_ctor); o.emplace(i, 2.0); - BOOST_CHECK(o); - BOOST_CHECK(1 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(1 == o->which_ctor); o.emplace(1, d); - BOOST_CHECK(o); - BOOST_CHECK(2 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(2 == o->which_ctor); o.emplace(1, 2.0); - BOOST_CHECK(o); - BOOST_CHECK(3 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(3 == o->which_ctor); o.emplace(i, d); - BOOST_CHECK(o); - BOOST_CHECK(4 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(4 == o->which_ctor); o.emplace(cs); - BOOST_CHECK(o); - BOOST_CHECK(5 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(5 == o->which_ctor); o.emplace(ms); - BOOST_CHECK(o); - BOOST_CHECK(6 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(6 == o->which_ctor); o.emplace(std::string()); - BOOST_CHECK(o); - BOOST_CHECK(7 == o->which_ctor); + BOOST_TEST(o); + BOOST_TEST(7 == o->which_ctor); } @@ -119,10 +106,10 @@ void test_no_moves_on_emplacement() try { optional<ThrowOnMove> o; o.emplace(1); - BOOST_CHECK(o); + BOOST_TEST(o); } catch (...) { - BOOST_CHECK(false); + BOOST_TEST(false); } } #endif @@ -143,47 +130,40 @@ void test_clear_on_throw() optional<Thrower> ot; try { ot.emplace(false); - BOOST_CHECK(ot); + BOOST_TEST(ot); } catch(...) { - BOOST_CHECK(false); + BOOST_TEST(false); } try { ot.emplace(true); - BOOST_CHECK(false); + BOOST_TEST(false); } catch(...) { - BOOST_CHECK(!ot); + BOOST_TEST(!ot); } } void test_no_assignment_on_emplacement() { optional<const std::string> os; - BOOST_CHECK(!os); + BOOST_TEST(!os); os.emplace("wow"); - BOOST_CHECK(os); - BOOST_CHECK(*os == "wow"); + BOOST_TEST(os); + BOOST_TEST_EQ(*os, "wow"); } -int test_main( int, char* [] ) +int main() { - try - { #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) - test_emplace(); + test_emplace(); #endif #if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) - test_no_moves_on_emplacement(); + test_no_moves_on_emplacement(); #endif - test_clear_on_throw(); - test_no_assignment_on_emplacement(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; + test_clear_on_throw(); + test_no_assignment_on_emplacement(); + + return boost::report_errors(); } diff --git a/libs/optional/test/optional_test_equals_none.cpp b/libs/optional/test/optional_test_equals_none.cpp index aed777198..1c8c5d8c7 100644 --- a/libs/optional/test/optional_test_equals_none.cpp +++ b/libs/optional/test/optional_test_equals_none.cpp @@ -8,18 +8,6 @@ // // You are welcome to contact the author at: // akrzemi1@gmail.com -// -// Revisions: -// -#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/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ #include "boost/optional/optional.hpp" @@ -27,11 +15,9 @@ #pragma hdrstop #endif +#include "boost/core/lightweight_test.hpp" #include "boost/none.hpp" -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" struct SemiRegular // no operator== { @@ -41,28 +27,17 @@ private: void operator!=(SemiRegular const&) const {} void test_equal_to_none_of_noncomparable_T() { - optional<SemiRegular> i = SemiRegular(); - optional<SemiRegular> o; - - BOOST_CHECK(i != boost::none); - BOOST_CHECK(boost::none != i); - BOOST_CHECK(o == boost::none); - BOOST_CHECK(boost::none == o); + boost::optional<SemiRegular> i = SemiRegular(); + boost::optional<SemiRegular> o; + + BOOST_TEST(i != boost::none); + BOOST_TEST(boost::none != i); + BOOST_TEST(o == boost::none); + BOOST_TEST(boost::none == o); } -int test_main( int, char* [] ) +int main() { - try - { - test_equal_to_none_of_noncomparable_T(); - - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; + test_equal_to_none_of_noncomparable_T(); + return boost::report_errors(); } - - diff --git a/libs/optional/test/optional_test_fail_convert_assign_of_enums.cpp b/libs/optional/test/optional_test_fail_convert_assign_of_enums.cpp new file mode 100644 index 000000000..59538505a --- /dev/null +++ b/libs/optional/test/optional_test_fail_convert_assign_of_enums.cpp @@ -0,0 +1,26 @@ +// Copyright (C) 2015, 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.hpp" + +// THIS TEST SHOULD FAIL TO COMPILE + +enum E1 {e1}; +enum E2 {e2}; + +void test_converitng_assignment_of_different_enums() +{ + boost::optional<E2> o2(e2); + boost::optional<E1> o1; + o1 = o2; +} + +int main() {} diff --git a/libs/optional/test/optional_test_fail_convert_from_null.cpp b/libs/optional/test/optional_test_fail_convert_from_null.cpp new file mode 100644 index 000000000..a454615d4 --- /dev/null +++ b/libs/optional/test/optional_test_fail_convert_from_null.cpp @@ -0,0 +1,25 @@ +// 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.hpp" + +// +// THIS TEST SHOULD FAIL TO COMPILE +// + +struct NoInitFromNull{}; + +void test_conversion_from_null() +{ + boost::optional<NoInitFromNull> opt = 0; +} + + diff --git a/libs/optional/test/optional_test_fail_io_without_io.cpp b/libs/optional/test/optional_test_fail_io_without_io.cpp new file mode 100644 index 000000000..e986d3721 --- /dev/null +++ b/libs/optional/test/optional_test_fail_io_without_io.cpp @@ -0,0 +1,24 @@ +// Copyright (C) 2015, 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 <iostream> +#include "boost/optional.hpp" +// but no boost/optional/optional_io.hpp + +// THIS TEST SHOULD FAIL TO COMPILE +// Unless one includes header boost/optional/optional_io.hpp, it should not be possible +// to stream out an optional object. + +void test_streaming_out_optional() +{ + boost::optional<int> opt; + std::cout << opt; +}
\ No newline at end of file diff --git a/libs/optional/test/optional_test_inplace.cpp b/libs/optional/test/optional_test_inplace.cpp deleted file mode 100644 index b0e828507..000000000 --- a/libs/optional/test/optional_test_inplace.cpp +++ /dev/null @@ -1,84 +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<iostream> -#include<stdexcept> -#include<string> - -#define BOOST_ENABLE_ASSERT_HANDLER - -#include "boost/optional/optional.hpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#include "boost/utility/in_place_factory.hpp" -#include "boost/utility/typed_in_place_factory.hpp" -#endif - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -struct A -{ - A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {} - - friend bool operator == ( A const& x, A const& y ) - { return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; } - - double m_a0 ; - std::string m_a1 ; -} ; - -int test_main( int, char* [] ) -{ - double a00 = 3.14, a10 = 6.02e-23; - std::string a01("pi"), a11("mol"); - - A a0(a00,a01); - A a1(a10,a11); - - boost::optional<A> opt1(a0); - - boost::optional<A> opt2 ( boost::in_place(a00,a01) ) ; - - boost::optional<A> opt3 ( boost::in_place<A>(a00,a01) ) ; - - BOOST_CHECK( opt1 == opt2 ) ; - BOOST_CHECK( opt2 == opt2 ) ; - BOOST_CHECK( *opt2 == a0 ) ; - -#ifndef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION - - opt2 = boost::in_place(a10,a11); - BOOST_CHECK( *opt2 == a1 ) ; - - opt3 = boost::in_place<A>(a10,a11); - BOOST_CHECK( *opt3 == a1 ) ; - -#endif - - return 0; -} -#else -int test_main( int, char* [] ) -{ - // If in-place factories are not supported there is nothing to test - return 0 ; -} -#endif - - - diff --git a/libs/optional/test/optional_test_inplace_factory.cpp b/libs/optional/test/optional_test_inplace_factory.cpp new file mode 100644 index 000000000..1e852f0a2 --- /dev/null +++ b/libs/optional/test/optional_test_inplace_factory.cpp @@ -0,0 +1,104 @@ +// Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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: +// fernando_cacciola@hotmail.com + +#include<string> +#include "boost/optional/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT +#include "boost/utility/in_place_factory.hpp" +#include "boost/utility/typed_in_place_factory.hpp" +#endif + +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" + +struct Guard +{ + double num; + std::string str; + Guard() : num() {} + Guard(double num_, std::string str_) : num(num_), str(str_) {} + + friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; } + friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); } + +private: + Guard(const Guard&); + Guard& operator=(const Guard&); +}; + +void test_ctor() +{ +#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT + Guard g0, g1(1.0, "one"), g2(2.0, "two"); + + boost::optional<Guard> og0 ( boost::in_place() ); + boost::optional<Guard> og1 ( boost::in_place(1.0, "one") ); + boost::optional<Guard> og1_( boost::in_place(1.0, "one") ); + boost::optional<Guard> og2 ( boost::in_place<Guard>(2.0, "two") ); + + BOOST_TEST(og0); + BOOST_TEST(og1); + BOOST_TEST(og1_); + BOOST_TEST(og2); + + BOOST_TEST(*og0 == g0); + BOOST_TEST(*og1 == g1); + BOOST_TEST(*og1_ == g1); + BOOST_TEST(*og2 == g2); + + BOOST_TEST(og1_ == og1); + BOOST_TEST(og1_ != og2); + BOOST_TEST(og1_ != og0); +#endif +} + +void test_assign() +{ +#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT +#ifndef BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION + Guard g0, g1(1.0, "one"), g2(2.0, "two"); + + boost::optional<Guard> og0, og1, og1_, og2; + + og0 = boost::in_place(); + og1 = boost::in_place(1.0, "one"); + og1_ = boost::in_place(1.0, "one"); + og2 = boost::in_place<Guard>(2.0, "two"); + + BOOST_TEST(og0); + BOOST_TEST(og1); + BOOST_TEST(og1_); + BOOST_TEST(og2); + + BOOST_TEST(*og0 == g0); + BOOST_TEST(*og1 == g1); + BOOST_TEST(*og1_ == g1); + BOOST_TEST(*og2 == g2); + + BOOST_TEST(og1_ == og1); + BOOST_TEST(og1_ != og2); + BOOST_TEST(og1_ != og0); +#endif +#endif +} + +int main() +{ + test_ctor(); + test_assign(); + return boost::report_errors(); +}
\ No newline at end of file diff --git a/libs/optional/test/optional_test_inplace_fail.cpp b/libs/optional/test/optional_test_inplace_fail.cpp index c6ba1d62e..bb7c26f6c 100644 --- a/libs/optional/test/optional_test_inplace_fail.cpp +++ b/libs/optional/test/optional_test_inplace_fail.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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 @@ -8,53 +9,45 @@ // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com -// -#include<iostream> -#include<stdexcept> -#include<string> - -#define BOOST_ENABLE_ASSERT_HANDLER +#include<string> #include "boost/optional/optional.hpp" -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#include "boost/utility/in_place_factory.hpp" -#endif - #ifdef __BORLANDC__ #pragma hdrstop #endif -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -struct A -{ - A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {} - - friend bool operator == ( A const& x, A const& y ) - { return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; } +#include "boost/utility/in_place_factory.hpp" +#include "boost/utility/typed_in_place_factory.hpp" +#endif - double m_a0 ; - std::string m_a1 ; -} ; +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" -int test_main( int, char* [] ) +struct Guard { - int invalid_extra_parameter ; - boost::optional<A> opt2 ( boost::in_place(3.14,"pi",invalid_extra_parameter) ) ; - - return 0; -} -#else -int test_main( int, char* [] ) + double num; + std::string str; + Guard() : num() {} + Guard(double num_, std::string str_) : num(num_), str(str_) {} + + friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; } + friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); } + +private: + Guard(const Guard&); + Guard& operator=(const Guard&); +}; + + +int main() { - int invalid_extra_parameter ; - boost::optional<A> opt2 ( A(3.14,"pi",invalid_extra_parameter) ) ; - - return 0; -} +#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT + int excessive_param = 2; + boost::optional<Guard> og1 ( boost::in_place(1.0, "one", excessive_param) ); +#else + NOTHING_TO_TEST_SO_JUST_FAIL #endif - + return 0; +}
\ No newline at end of file diff --git a/libs/optional/test/optional_test_inplace_fail2.cpp b/libs/optional/test/optional_test_inplace_fail2.cpp index f82d85795..e6a000446 100644 --- a/libs/optional/test/optional_test_inplace_fail2.cpp +++ b/libs/optional/test/optional_test_inplace_fail2.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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 @@ -8,55 +9,45 @@ // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com -// -#include<iostream> -#include<stdexcept> -#include<string> - -#define BOOST_ENABLE_ASSERT_HANDLER +#include<string> #include "boost/optional/optional.hpp" -#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -#include "boost/utility/typed_in_place_factory.hpp" -#endif - #ifdef __BORLANDC__ #pragma hdrstop #endif -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT -struct A -{ - A ( double a0, std::string a1 ) : m_a0(a0), m_a1(a1) {} - - friend bool operator == ( A const& x, A const& y ) - { return x.m_a0 == y.m_a0 && x.m_a1 == y.m_a1 ; } +#include "boost/utility/in_place_factory.hpp" +#include "boost/utility/typed_in_place_factory.hpp" +#endif - double m_a0 ; - std::string m_a1 ; -} ; +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" -int test_main( int, char* [] ) +struct Guard { - // This must fail to compile. - // The first template argument to in_place<> is the target-type, - // not the first constructor parameter type. - boost::optional<A> opt2 ( boost::in_place<int>(3.14,"pi") ) ; - - return 0; -} -#else -int test_main( int, char* [] ) + double num; + std::string str; + Guard() : num() {} + Guard(double num_, std::string str_) : num(num_), str(str_) {} + + friend bool operator==(const Guard& lhs, const Guard& rhs) { return lhs.num == rhs.num && lhs.str == rhs.str; } + friend bool operator!=(const Guard& lhs, const Guard& rhs) { return !(lhs == rhs); } + +private: + Guard(const Guard&); + Guard& operator=(const Guard&); +}; + + +int main() { - boost::optional<A> opt2 ( int(3.14) ) ; - - return 0; -} +#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT + typedef int BAD_TARGET_TYPE; + boost::optional<Guard> og1 ( boost::in_place<BAD_TARGET_TYPE>(1.0, "one") ); +#else + NOTHING_TO_TEST_SO_JUST_FAIL #endif - - + return 0; +}
\ No newline at end of file diff --git a/libs/optional/test/optional_test_io.cpp b/libs/optional/test/optional_test_io.cpp index d4ee207ca..196363e22 100644 --- a/libs/optional/test/optional_test_io.cpp +++ b/libs/optional/test/optional_test_io.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// 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 @@ -8,52 +9,24 @@ // // You are welcome to contact the author at: // fernando_cacciola@hotmail.com -// -#include<stdexcept> -#include<string> -#include<sstream> - -#define BOOST_ENABLE_ASSERT_HANDLER +#include <sstream> #include "boost/optional/optional.hpp" #include "boost/optional/optional_io.hpp" -#include "boost/none.hpp" - -#include "boost/test/minimal.hpp" -#ifdef ENABLE_TRACE -#define TRACE(msg) std::cout << msg << std::endl ; -#else -#define TRACE(msg) +#ifdef __BORLANDC__ +#pragma hdrstop #endif -namespace boost { - -void assertion_failed (char const * expr, char const * func, char const * file, long ) -{ - 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); -} - -} +#include "boost/core/lightweight_test.hpp" -using namespace std ; -using namespace boost ; +using boost::optional; +using boost::make_optional; template<class Opt> void test2( Opt o, Opt buff ) { - stringstream s ; + std::stringstream s ; const int markv = 123 ; int mark = 0 ; @@ -61,8 +34,8 @@ void test2( Opt o, Opt buff ) s << o << " " << markv ; s >> buff >> mark ; - BOOST_ASSERT( buff == o ) ; - BOOST_ASSERT( mark == markv ) ; + BOOST_TEST( buff == o ) ; + BOOST_TEST( mark == markv ) ; } @@ -75,18 +48,41 @@ void test( T v, T w ) test2( optional<T> () , make_optional(w)); } -int test_main( int, char* [] ) + +template <class T> +void subtest_tag_none_reversibility_with_optional(optional<T> ov) { - try - { - test(1,2); - test(string("hello"),string("buffer")); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; + std::stringstream s; + s << boost::none; + s >> ov; + BOOST_TEST(!ov); } +template <class T> +void subtest_tag_none_equivalence_with_optional() +{ + std::stringstream s, r; + optional<T> ov; + s << boost::none; + r << ov; + BOOST_TEST_EQ(s.str(), r.str()); +} + +template <class T> +void test_tag_none(T v) +{ + subtest_tag_none_reversibility_with_optional(optional<T>(v)); + subtest_tag_none_reversibility_with_optional(optional<T>()); + subtest_tag_none_equivalence_with_optional<T>(); +} + + +int main() +{ + test(1,2); + test(std::string("hello"), std::string("buffer")); + test_tag_none(10); + test_tag_none(std::string("text")); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_minimum_requirements.cpp b/libs/optional/test/optional_test_minimum_requirements.cpp index 5649d6935..77ef1fc21 100644 --- a/libs/optional/test/optional_test_minimum_requirements.cpp +++ b/libs/optional/test/optional_test_minimum_requirements.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Andrzej Krzemienski. +// Copyright (C) 2014-2015 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 @@ -8,19 +8,6 @@ // // You are welcome to contact the author at: // akrzemi1@gmail.com -// -// Revisions: -// -#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/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ -#include "boost/static_assert.hpp" #include "boost/optional/optional.hpp" @@ -28,12 +15,9 @@ #pragma hdrstop #endif +#include "boost/core/lightweight_test.hpp" #include "boost/none.hpp" -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" - class NonConstructible { private: @@ -46,16 +30,10 @@ private: void test_non_constructible() { - optional<NonConstructible> o; - BOOST_CHECK(!o); - BOOST_CHECK(o == boost::none); - try { - o.value(); - BOOST_CHECK(false); - } - catch(...) { - BOOST_CHECK(true); - } + boost::optional<NonConstructible> o; + BOOST_TEST(!o); + BOOST_TEST(o == boost::none); + BOOST_TEST_THROWS(o.value(), boost::bad_optional_access); } class Guard @@ -72,33 +50,26 @@ private: void test_guard() { - optional<Guard> o; + boost::optional<Guard> o; o.emplace(1); - BOOST_CHECK(o); + BOOST_TEST(o); + BOOST_TEST(o != boost::none); } void test_non_assignable() { - optional<const std::string> o; + boost::optional<const std::string> o; o.emplace("cat"); - BOOST_CHECK(o); - BOOST_CHECK(*o == "cat"); + BOOST_TEST(o); + BOOST_TEST(o != boost::none); + BOOST_TEST_EQ(*o, std::string("cat")); } -int test_main( int, char* [] ) +int main() { - try - { - test_non_constructible(); - test_guard(); - test_non_assignable(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; -} - + test_non_constructible(); + test_guard(); + test_non_assignable(); + return boost::report_errors(); +}
\ No newline at end of file diff --git a/libs/optional/test/optional_test_move.cpp b/libs/optional/test/optional_test_move.cpp index affa07f33..51aa970f3 100644 --- a/libs/optional/test/optional_test_move.cpp +++ b/libs/optional/test/optional_test_move.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014 Andrzej Krzemienski. +// Copyright (C) 2014 - 2015 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 @@ -8,19 +8,7 @@ // // You are welcome to contact the author at: // akrzemi1@gmail.com -// -// Revisions: -// -#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/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ -#include "boost/static_assert.hpp" #include "boost/optional/optional.hpp" @@ -28,11 +16,10 @@ #pragma hdrstop #endif -#include "boost/none.hpp" +#include "boost/core/lightweight_test.hpp" -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" +using boost::optional; +using boost::none; //#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT //#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR @@ -86,37 +73,37 @@ bool operator!=( Oracle const& a, Oracle const& b ) { return a.val.i != b.val.i; void test_move_ctor_from_U() { optional<Oracle> o1 ((OracleVal())); - BOOST_CHECK(o1); - BOOST_CHECK(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed); + BOOST_TEST(o1); + BOOST_TEST(o1->s == sValueMoveConstructed || o1->s == sMoveConstructed); OracleVal v1; optional<Oracle> o2 (v1); - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed ); - BOOST_CHECK(v1.s == sIntConstructed); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sValueCopyConstructed || o2->s == sCopyConstructed || o2->s == sMoveConstructed ); + BOOST_TEST(v1.s == sIntConstructed); optional<Oracle> o3 (boost::move(v1)); - BOOST_CHECK(o3); - BOOST_CHECK(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed); - BOOST_CHECK(v1.s == sMovedFrom); + BOOST_TEST(o3); + BOOST_TEST(o3->s == sValueMoveConstructed || o3->s == sMoveConstructed); + BOOST_TEST(v1.s == sMovedFrom); } void test_move_ctor_form_T() { optional<Oracle> o1 ((Oracle())); - BOOST_CHECK(o1); - BOOST_CHECK(o1->s == sMoveConstructed); + BOOST_TEST(o1); + BOOST_TEST(o1->s == sMoveConstructed); Oracle v1; optional<Oracle> o2 (v1); - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sCopyConstructed); - BOOST_CHECK(v1.s == sDefaultConstructed); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sCopyConstructed); + BOOST_TEST(v1.s == sDefaultConstructed); optional<Oracle> o3 (boost::move(v1)); - BOOST_CHECK(o3); - BOOST_CHECK(o3->s == sMoveConstructed); - BOOST_CHECK(v1.s == sMovedFrom); + BOOST_TEST(o3); + BOOST_TEST(o3->s == sMoveConstructed); + BOOST_TEST(v1.s == sMovedFrom); } void test_move_ctor_from_optional_T() @@ -124,22 +111,22 @@ void test_move_ctor_from_optional_T() optional<Oracle> o1; optional<Oracle> o2(boost::move(o1)); - BOOST_CHECK(!o1); - BOOST_CHECK(!o2); + BOOST_TEST(!o1); + BOOST_TEST(!o2); optional<Oracle> o3((Oracle())); optional<Oracle> o4(boost::move(o3)); - BOOST_CHECK(o3); - BOOST_CHECK(o4); - BOOST_CHECK(o3->s == sMovedFrom); - BOOST_CHECK(o4->s == sMoveConstructed); + BOOST_TEST(o3); + BOOST_TEST(o4); + BOOST_TEST(o3->s == sMovedFrom); + BOOST_TEST(o4->s == sMoveConstructed); optional<Oracle> o5((optional<Oracle>())); - BOOST_CHECK(!o5); + BOOST_TEST(!o5); optional<Oracle> o6((optional<Oracle>(Oracle()))); - BOOST_CHECK(o6); - BOOST_CHECK(o6->s == sMoveConstructed); + BOOST_TEST(o6); + BOOST_TEST(o6->s == sMoveConstructed); optional<Oracle> o7(o6); // does copy ctor from non-const lvalue compile? } @@ -149,59 +136,59 @@ void test_move_assign_from_U() optional<Oracle> o1 = boost::none; // test if additional ctors didn't break it o1 = boost::none; // test if additional assignments didn't break it o1 = OracleVal(); - BOOST_CHECK(o1); + BOOST_TEST(o1); - BOOST_CHECK(o1->s == sValueMoveConstructed); + BOOST_TEST(o1->s == sValueMoveConstructed); o1 = OracleVal(); - BOOST_CHECK(o1); - BOOST_CHECK(o1->s == sMoveAssigned); + BOOST_TEST(o1); + BOOST_TEST(o1->s == sMoveAssigned); OracleVal v1; optional<Oracle> o2; o2 = v1; - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sValueCopyConstructed); - BOOST_CHECK(v1.s == sIntConstructed); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sValueCopyConstructed); + BOOST_TEST(v1.s == sIntConstructed); o2 = v1; - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sCopyAssigned || o2->s == sMoveAssigned); - BOOST_CHECK(v1.s == sIntConstructed); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sCopyAssigned || o2->s == sMoveAssigned); + BOOST_TEST(v1.s == sIntConstructed); optional<Oracle> o3; o3 = boost::move(v1); - BOOST_CHECK(o3); - BOOST_CHECK(o3->s == sValueMoveConstructed); - BOOST_CHECK(v1.s == sMovedFrom); + BOOST_TEST(o3); + BOOST_TEST(o3->s == sValueMoveConstructed); + BOOST_TEST(v1.s == sMovedFrom); } void test_move_assign_from_T() { optional<Oracle> o1; o1 = Oracle(); - BOOST_CHECK(o1); - BOOST_CHECK(o1->s == sMoveConstructed); + BOOST_TEST(o1); + BOOST_TEST(o1->s == sMoveConstructed); o1 = Oracle(); - BOOST_CHECK(o1); - BOOST_CHECK(o1->s == sMoveAssigned); + BOOST_TEST(o1); + BOOST_TEST(o1->s == sMoveAssigned); Oracle v1; optional<Oracle> o2; o2 = v1; - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sCopyConstructed); - BOOST_CHECK(v1.s == sDefaultConstructed); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sCopyConstructed); + BOOST_TEST(v1.s == sDefaultConstructed); o2 = v1; - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sCopyAssigned); - BOOST_CHECK(v1.s == sDefaultConstructed); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sCopyAssigned); + BOOST_TEST(v1.s == sDefaultConstructed); optional<Oracle> o3; o3 = boost::move(v1); - BOOST_CHECK(o3); - BOOST_CHECK(o3->s == sMoveConstructed); - BOOST_CHECK(v1.s == sMovedFrom); + BOOST_TEST(o3); + BOOST_TEST(o3->s == sMoveConstructed); + BOOST_TEST(v1.s == sMovedFrom); } void test_move_assign_from_optional_T() @@ -209,23 +196,23 @@ void test_move_assign_from_optional_T() optional<Oracle> o1; optional<Oracle> o2; o1 = optional<Oracle>(); - BOOST_CHECK(!o1); + BOOST_TEST(!o1); optional<Oracle> o3((Oracle())); o1 = o3; - BOOST_CHECK(o3); - BOOST_CHECK(o3->s == sMoveConstructed); - BOOST_CHECK(o1); - BOOST_CHECK(o1->s == sCopyConstructed); + BOOST_TEST(o3); + BOOST_TEST(o3->s == sMoveConstructed); + BOOST_TEST(o1); + BOOST_TEST(o1->s == sCopyConstructed); o2 = boost::move(o3); - BOOST_CHECK(o3); - BOOST_CHECK(o3->s == sMovedFrom); - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sMoveConstructed); + BOOST_TEST(o3); + BOOST_TEST(o3->s == sMovedFrom); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sMoveConstructed); o2 = optional<Oracle>((Oracle())); - BOOST_CHECK(o2); - BOOST_CHECK(o2->s == sMoveAssigned); + BOOST_TEST(o2); + BOOST_TEST(o2->s == sMoveAssigned); } class MoveOnly @@ -247,21 +234,21 @@ void test_with_move_only() { optional<MoveOnly> o1; optional<MoveOnly> o2((MoveOnly(1))); - BOOST_CHECK(o2); - BOOST_CHECK(o2->val == 1); + BOOST_TEST(o2); + BOOST_TEST(o2->val == 1); optional<MoveOnly> o3 (boost::move(o1)); - BOOST_CHECK(!o3); + BOOST_TEST(!o3); optional<MoveOnly> o4 (boost::move(o2)); - BOOST_CHECK(o4); - BOOST_CHECK(o4->val == 1); - BOOST_CHECK(o2); - BOOST_CHECK(o2->val == 0); + BOOST_TEST(o4); + BOOST_TEST(o4->val == 1); + BOOST_TEST(o2); + BOOST_TEST(o2->val == 0); o3 = boost::move(o4); - BOOST_CHECK(o3); - BOOST_CHECK(o3->val == 1); - BOOST_CHECK(o4); - BOOST_CHECK(o4->val == 0); + BOOST_TEST(o3); + BOOST_TEST(o3->val == 1); + BOOST_TEST(o4); + BOOST_TEST(o4->val == 0); } class MoveOnlyB @@ -287,15 +274,15 @@ void test_move_assign_from_optional_U() optional<MoveOnlyB> b1; b1 = boost::move(a); - BOOST_CHECK(b1); - BOOST_CHECK(b1->val == 2); - BOOST_CHECK(a); - BOOST_CHECK(a->val == 0); + BOOST_TEST(b1); + BOOST_TEST(b1->val == 2); + BOOST_TEST(a); + BOOST_TEST(a->val == 0); b1 = MoveOnly(4); - BOOST_CHECK(b1); - BOOST_CHECK(b1->val == 4); + BOOST_TEST(b1); + BOOST_TEST(b1->val == 4); } void test_move_ctor_from_optional_U() @@ -303,15 +290,15 @@ void test_move_ctor_from_optional_U() optional<MoveOnly> a((MoveOnly(2))); optional<MoveOnlyB> b1(boost::move(a)); - BOOST_CHECK(b1); - BOOST_CHECK(b1->val == 2); - BOOST_CHECK(a); - BOOST_CHECK(a->val == 0); + BOOST_TEST(b1); + BOOST_TEST(b1->val == 2); + BOOST_TEST(a); + BOOST_TEST(a->val == 0); optional<MoveOnlyB> b2(( optional<MoveOnly>(( MoveOnly(4) )) )); - BOOST_CHECK(b2); - BOOST_CHECK(b2->val == 4); + BOOST_TEST(b2); + BOOST_TEST(b2->val == 4); } void test_swap() @@ -320,8 +307,8 @@ void test_swap() optional<MoveOnly> b((MoveOnly(3))); swap(a, b); - BOOST_CHECK(a->val == 3); - BOOST_CHECK(b->val == 2); + BOOST_TEST(a->val == 3); + BOOST_TEST(b->val == 2); } void test_optional_ref_to_movables() @@ -329,66 +316,24 @@ void test_optional_ref_to_movables() MoveOnly m(3); optional<MoveOnly&> orm = m; orm->val = 2; - BOOST_CHECK(m.val == 2); + BOOST_TEST(m.val == 2); optional<MoveOnly&> orm2 = orm; orm2->val = 1; - BOOST_CHECK(m.val == 1); - BOOST_CHECK(orm->val == 1); + BOOST_TEST(m.val == 1); + BOOST_TEST(orm->val == 1); optional<MoveOnly&> orm3 = boost::move(orm); orm3->val = 4; - BOOST_CHECK(m.val == 4); - BOOST_CHECK(orm->val == 4); - BOOST_CHECK(orm2->val == 4); -} - -// these 4 classes have different noexcept signatures in move operations -struct NothrowBoth { - NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {}; - void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {}; -}; -struct NothrowCtor { - NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {}; - void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {}; -}; -struct NothrowAssign { - NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {}; - void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {}; -}; -struct NothrowNone { - NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {}; - void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {}; -}; - -#ifndef BOOST_NO_NOEXCEPT - -void test_noexcept() // this is a compile-time test -{ - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value); - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>())); - - BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>())); - - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>())); - - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value); - BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value); - BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>())); + BOOST_TEST(m.val == 4); + BOOST_TEST(orm->val == 4); + BOOST_TEST(orm2->val == 4); } -#endif // !defned BOOST_NO_NOEXCEPT #endif -int test_main( int, char* [] ) +int main() { - try - { #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES test_move_ctor_from_U(); test_move_ctor_form_T(); @@ -402,13 +347,6 @@ int test_main( int, char* [] ) test_optional_ref_to_movables(); test_swap(); #endif - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - return 0; + return boost::report_errors(); } - - diff --git a/libs/optional/test/optional_test_msvc_bug_workaround.cpp b/libs/optional/test/optional_test_msvc_bug_workaround.cpp new file mode 100644 index 000000000..30f3b02f0 --- /dev/null +++ b/libs/optional/test/optional_test_msvc_bug_workaround.cpp @@ -0,0 +1,41 @@ +// Copyright (C) 2015 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 + +#define BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES +#include "boost/optional/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "boost/core/lightweight_test.hpp" + + +struct Wrapper +{ + operator int () { return 9; } + operator boost::optional<int> () { return 7; } +}; + +void test() +{ +#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) + boost::optional<int> v = Wrapper(); + BOOST_TEST(v); + BOOST_TEST_EQ(*v, 7); +#endif +} + +int main() +{ + test(); + return boost::report_errors(); +}
\ No newline at end of file diff --git a/libs/optional/test/optional_test_noexcept_move.cpp b/libs/optional/test/optional_test_noexcept_move.cpp new file mode 100644 index 000000000..b0c2220d8 --- /dev/null +++ b/libs/optional/test/optional_test_noexcept_move.cpp @@ -0,0 +1,116 @@ +// 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/static_assert.hpp" +#include "boost/optional/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + + +using boost::optional; + + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES +#ifndef BOOST_NO_NOEXCEPT + +// these 4 classes have different noexcept signatures in move operations +struct NothrowBoth { + NothrowBoth(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {}; + void operator=(NothrowBoth&&) BOOST_NOEXCEPT_IF(true) {}; +}; +struct NothrowCtor { + NothrowCtor(NothrowCtor&&) BOOST_NOEXCEPT_IF(true) {}; + void operator=(NothrowCtor&&) BOOST_NOEXCEPT_IF(false) {}; +}; +struct NothrowAssign { + NothrowAssign(NothrowAssign&&) BOOST_NOEXCEPT_IF(false) {}; + void operator=(NothrowAssign&&) BOOST_NOEXCEPT_IF(true) {}; +}; +struct NothrowNone { + NothrowNone(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {}; + void operator=(NothrowNone&&) BOOST_NOEXCEPT_IF(false) {}; +}; + +#if 0 // these also test type_traits, which are wrong +void test_noexcept_as_defined() // this is a compile-time test +{ + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<NothrowBoth>::value); + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<NothrowBoth>::value); + + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<NothrowCtor>::value); + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<NothrowCtor>::value); + + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<NothrowAssign>::value); + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<NothrowAssign>::value); + + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<NothrowNone>::value); + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<NothrowNone>::value); +} + +void test_noexcept_on_optional_with_type_traits() // this is a compile-time test +{ + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowBoth> >::value); + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_assignable<optional<NothrowBoth> >::value); + BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowBoth>())); + + BOOST_STATIC_ASSERT(::boost::is_nothrow_move_constructible<optional<NothrowCtor> >::value); + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowCtor> >::value); + BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowCtor>())); + + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowAssign> >::value); + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowAssign> >::value); + BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowAssign>())); + + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_constructible<optional<NothrowNone> >::value); + BOOST_STATIC_ASSERT(!::boost::is_nothrow_move_assignable<optional<NothrowNone> >::value); + BOOST_STATIC_ASSERT(BOOST_NOEXCEPT_EXPR(optional<NothrowNone>())); +} +#endif + +void test_noexcept_optional_with_operator() // compile-time test +{ + typedef optional<NothrowBoth> ONx2; + typedef optional<NothrowCtor> ONxC; + typedef optional<NothrowAssign> ONxA; + typedef optional<NothrowNone> ONx0; + ONx2 onx2; + ONxC onxC; + ONxA onxA; + ONx0 onx0; + + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2() )); + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx2(boost::move(onx2)) )); + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( onx2 = ONx2() )); + + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC() )); + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxC(boost::move(onxC)) )); + BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxC = ONxC() )); + + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONxA() )); + BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONxA(boost::move(onxA)) )); + BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onxA = ONxA() )); + + BOOST_STATIC_ASSERT( BOOST_NOEXCEPT_EXPR( ONx0() )); + BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( ONx0(boost::move(onx0)) )); + BOOST_STATIC_ASSERT(!BOOST_NOEXCEPT_EXPR( onx0 = ONx0() )); +} + +#endif // !defned BOOST_NO_NOEXCEPT +#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES + +int main() +{ + return 0; +} + + diff --git a/libs/optional/test/optional_test_ref.cpp b/libs/optional/test/optional_test_ref.cpp deleted file mode 100644 index c01b08e72..000000000 --- a/libs/optional/test/optional_test_ref.cpp +++ /dev/null @@ -1,373 +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<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" - -template<class T> -inline void check_ref_uninitialized_const ( optional<T&> const& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; -} -template<class T> -inline void check_ref_uninitialized ( optional<T&>& opt ) -{ -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt == 0 ) ; -#endif - BOOST_CHECK( !opt ) ; - - check_ref_uninitialized_const(opt); -} - -template<class T> -inline void check_ref_initialized_const ( optional<T&> const& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; -} - -template<class T> -inline void check_ref_initialized ( optional<T&>& opt ) -{ - BOOST_CHECK( opt ) ; - -#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE - BOOST_CHECK( opt != 0 ) ; -#endif - - BOOST_CHECK ( !!opt ) ; - - check_ref_initialized_const(opt); -} - -template<class T> -inline void check_ref_value_const ( optional<T&> 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<class T> -inline void check_ref_value ( optional<T&>& 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<class T> -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<T&> 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<T&> 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<T&> 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<T&> 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<T&> 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); -} - -// -// This verifies relational operators. -// -template<class T> -void test_relops( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - reset_throw_on_copy( ARG(T) ) ; - - T v0(18); - T v1(19); - T v2(19); - - optional<T&> def0 ; - optional<T&> def1 ; - optional<T&> opt0(v0); - optional<T&> opt1(v1); - optional<T&> opt2(v2); - - // Check identity - BOOST_CHECK ( def0 == def0 ) ; - BOOST_CHECK ( opt0 == opt0 ) ; - BOOST_CHECK ( !(def0 != def0) ) ; - BOOST_CHECK ( !(opt0 != opt0) ) ; - - // 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 ) ; - - // 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 ) ; -} - -template<class T> -void test_none( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - using boost::none ; - - T a(1234); - - optional<T&> def0 ; - optional<T&> def1(none) ; - optional<T&> non_def(a) ; - - BOOST_CHECK ( def0 == none ) ; - BOOST_CHECK ( non_def != none ) ; - BOOST_CHECK ( !def1 ) ; - - non_def = none ; - BOOST_CHECK ( !non_def ) ; -} - -template<class T> -void test_arrow( T const* ) -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - T a(1234); - - optional<T&> oa(a) ; - optional<T&> const coa(a) ; - - BOOST_CHECK ( coa->V() == 1234 ) ; - - oa->V() = 4321 ; - - BOOST_CHECK ( a.V() = 4321 ) ; -} - -void test_with_builtin_types() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(double) ); - test_relops( ARG(double) ) ; - test_none ( ARG(double) ) ; -} - -void test_with_class_type() -{ - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - - test_basics( ARG(X) ); - test_relops( ARG(X) ) ; - test_none ( ARG(X) ) ; - test_arrow ( ARG(X) ) ; - - BOOST_CHECK ( X::count == 0 ) ; -} - -void test_binding() -{ - int i = 0 ; - optional<int&> ori1 = i ; - BOOST_CHECK( &(*ori1) == &i ) ; - - optional<int&> ori2(i) ; - BOOST_CHECK( &(*ori2) == &i ) ; - - int const ci = 0 ; - optional<int const&> orci1 = ci ; - BOOST_CHECK( &(*orci1) == &ci ) ; - - optional<int const&> 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/libs/optional/test/optional_test_ref_assign_const_int.cpp b/libs/optional/test/optional_test_ref_assign_const_int.cpp new file mode 100644 index 000000000..a14ef6da9 --- /dev/null +++ b/libs/optional/test/optional_test_ref_assign_const_int.cpp @@ -0,0 +1,34 @@ +// 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/lightweight_test.hpp" +#include "testable_classes.hpp" +#include "optional_ref_assign_test_defs.hpp" + +using boost::optional; +using boost::none; + + +int main() +{ + test_copy_assignment_for_const<int>(); + test_copy_assignment_for_noconst_const<int>(); + test_rebinding_assignment_semantics_const<int>(); + test_rebinding_assignment_semantics_noconst_const<int>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_assign_mutable_int.cpp b/libs/optional/test/optional_test_ref_assign_mutable_int.cpp new file mode 100644 index 000000000..1c674dac7 --- /dev/null +++ b/libs/optional/test/optional_test_ref_assign_mutable_int.cpp @@ -0,0 +1,31 @@ +// 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/lightweight_test.hpp" +#include "testable_classes.hpp" +#include "optional_ref_assign_test_defs.hpp" + +using boost::optional; +using boost::none; + +int main() +{ + test_copy_assignment_for<int>(); + test_rebinding_assignment_semantics<int>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_assign_portable_minimum.cpp b/libs/optional/test/optional_test_ref_assign_portable_minimum.cpp new file mode 100644 index 000000000..2a548abe3 --- /dev/null +++ b/libs/optional/test/optional_test_ref_assign_portable_minimum.cpp @@ -0,0 +1,44 @@ +// 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/lightweight_test.hpp" +#include "testable_classes.hpp" +#include "optional_ref_assign_test_defs.hpp" + +using boost::optional; +using boost::none; + + +template <typename T> +void test_optional_ref_assignment() +{ + test_copy_assignment_for<T>(); + test_rebinding_assignment_semantics<T>(); + + test_copy_assignment_for_const<T>(); + test_copy_assignment_for_noconst_const<T>(); + test_rebinding_assignment_semantics_const<T>(); + test_rebinding_assignment_semantics_noconst_const<T>(); +} + +int main() +{ + test_optional_ref_assignment<ScopeGuard>(); + //test_optional_ref_assignment<Abstract>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_convert_assign_const_int.cpp b/libs/optional/test/optional_test_ref_convert_assign_const_int.cpp new file mode 100644 index 000000000..30d37a6d9 --- /dev/null +++ b/libs/optional/test/optional_test_ref_convert_assign_const_int.cpp @@ -0,0 +1,30 @@ +// Copyright (C) 2015 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" +#include "optional_ref_assign_test_defs.hpp" + +int main() +{ + test_converting_assignment<const int>(); + test_converting_assignment_for_noconst_const<int>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_convert_assign_mutable_int.cpp b/libs/optional/test/optional_test_ref_convert_assign_mutable_int.cpp new file mode 100644 index 000000000..4338e5297 --- /dev/null +++ b/libs/optional/test/optional_test_ref_convert_assign_mutable_int.cpp @@ -0,0 +1,29 @@ +// Copyright (C) 2015 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" +#include "optional_ref_assign_test_defs.hpp" + +int main() +{ + test_converting_assignment<int>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_convert_assign_non_int.cpp b/libs/optional/test/optional_test_ref_convert_assign_non_int.cpp new file mode 100644 index 000000000..d59e46e54 --- /dev/null +++ b/libs/optional/test/optional_test_ref_convert_assign_non_int.cpp @@ -0,0 +1,39 @@ +// Copyright (C) 2015 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" +#include "optional_ref_assign_test_defs.hpp" + + +template <typename T> +void test_all_const_cases() +{ + test_converting_assignment<T>(); + test_converting_assignment<const T>(); + test_converting_assignment_for_noconst_const<T>(); +} + +int main() +{ + test_all_const_cases<ScopeGuard>(); + //test_all_const_cases<Abstract>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_converting_ctor.cpp b/libs/optional/test/optional_test_ref_converting_ctor.cpp new file mode 100644 index 000000000..d7df3dcb3 --- /dev/null +++ b/libs/optional/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 <typename T> +void test_converting_ctor() +{ + typename concrete_type_of<T>::type v1(1), v2(2); + + { + optional<T&> 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<T&> 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 <typename T> +void test_converting_ctor_for_noconst_const() +{ + typename concrete_type_of<T>::type v1(1), v2(2); + + { + optional<const T&> 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<const T&> 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 <typename T> +void test_all_const_cases() +{ + test_converting_ctor<T>(); + test_converting_ctor<const T>(); + test_converting_ctor_for_noconst_const<T>(); +} + +int main() +{ + test_all_const_cases<int>(); + test_all_const_cases<ScopeGuard>(); + //test_all_const_cases<Abstract>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_move.cpp b/libs/optional/test/optional_test_ref_move.cpp new file mode 100644 index 000000000..78b7bf27a --- /dev/null +++ b/libs/optional/test/optional_test_ref_move.cpp @@ -0,0 +1,69 @@ +// 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 <string> +#include "boost/core/addressof.hpp" +#include "boost/core/lightweight_test.hpp" + +using boost::optional; + +std::string global("text"); + +optional<std::string&> make_optional_string_ref() +{ + return optional<std::string&>(global); +} + +std::string& return_global() +{ + return global; +} + +int main() +{ + optional<std::string&> opt; + opt = make_optional_string_ref(); + BOOST_TEST(bool(opt)); + BOOST_TEST(*opt == global); + BOOST_TEST(boost::addressof(*opt) == boost::addressof(global)); + + { + std::string& str = *make_optional_string_ref(); + BOOST_TEST(str == global); + BOOST_TEST(boost::addressof(str) == boost::addressof(global)); + } + + { + std::string& str = make_optional_string_ref().value(); + BOOST_TEST(str == global); + BOOST_TEST(boost::addressof(str) == boost::addressof(global)); + } + + { + std::string& str = make_optional_string_ref().value_or(global); + BOOST_TEST(str == global); + BOOST_TEST(boost::addressof(str) == boost::addressof(global)); + } + + { + std::string& str = make_optional_string_ref().value_or_eval(&return_global); + BOOST_TEST(str == global); + BOOST_TEST(boost::addressof(str) == boost::addressof(global)); + } + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_ref_portable_minimum.cpp b/libs/optional/test/optional_test_ref_portable_minimum.cpp new file mode 100644 index 000000000..e8439c92d --- /dev/null +++ b/libs/optional/test/optional_test_ref_portable_minimum.cpp @@ -0,0 +1,448 @@ +// 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; + +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<CountingClass&> oA(v1); + optional<CountingClass&> oB; + optional<CountingClass&> oC = oA; + oB = oA; + *oB = v2; + oC = none; + oC = optional<CountingClass&>(v2); + oB = none; + oA = oB; + } + BOOST_TEST_EQ(4, CountingClass::count); + BOOST_TEST_EQ(1, CountingClass::assign_count); +} + +template <typename T> +typename boost::enable_if< has_arrow<T> >::type +test_arrow_const() +{ + const typename concrete_type_of<T>::type v(2); + optional<const T&> o(v); + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 2); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); +} + +template <typename T> +typename boost::disable_if< has_arrow<T> >::type +test_arrow_const() +{ +} + +template <typename T> +typename boost::enable_if< has_arrow<T> >::type +test_arrow_noconst_const() +{ + typename concrete_type_of<T>::type v(2); + optional<const T&> o(v); + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 2); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + + v.val() = 1; + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 1); + BOOST_TEST_EQ(v.val(), 1); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); +} + +template <typename T> +typename boost::disable_if< has_arrow<T> >::type +test_arrow_noconst_const() +{ +} + +template <typename T> +typename boost::enable_if< has_arrow<T> >::type +test_arrow() +{ + typename concrete_type_of<T>::type v(2); + optional<T&> o(v); + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 2); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + + v.val() = 1; + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 1); + BOOST_TEST_EQ(v.val(), 1); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + + o->val() = 3; + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 3); + BOOST_TEST_EQ(v.val(), 3); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + +} + +template <typename T> +typename boost::disable_if< has_arrow<T> >::type +test_arrow() +{ +} + +template <typename T> +void test_not_containing_value_for() +{ + optional<T&> o1; + optional<T&> o2 = none; + optional<T&> o3 = o1; + + BOOST_TEST(!o1); + BOOST_TEST(!o2); + BOOST_TEST(!o3); + + BOOST_TEST(o1 == none); + BOOST_TEST(o2 == none); + BOOST_TEST(o3 == none); +} + +template <typename T> +void test_direct_init_for_const() +{ + const typename concrete_type_of<T>::type v(2); + optional<const T&> o(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); +} + +template <typename T> +void test_direct_init_for_noconst_const() +{ + typename concrete_type_of<T>::type v(2); + optional<const T&> o(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + val(v) = 9; + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 9); + BOOST_TEST_EQ(val(v), 9); +} + +template <typename T> +void test_direct_init_for() +{ + typename concrete_type_of<T>::type v(2); + optional<T&> o(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + val(v) = 9; + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 9); + BOOST_TEST_EQ(val(v), 9); + + val(*o) = 7; + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 7); + BOOST_TEST_EQ(val(v), 7); +} + +template <typename T> +void test_clearing_the_value() +{ + typename concrete_type_of<T>::type v(2); + optional<T&> o1(v), o2(v); + + BOOST_TEST(o1); + BOOST_TEST(o1 != none); + BOOST_TEST(o2); + BOOST_TEST(o2 != none); + + o1 = none; + BOOST_TEST(!o1); + BOOST_TEST(o1 == none); + BOOST_TEST(o2); + BOOST_TEST(o2 != none); + BOOST_TEST_EQ(val(*o2), 2); + BOOST_TEST(boost::addressof(*o2) == boost::addressof(v)); + BOOST_TEST_EQ(val(v), 2); +} + +template <typename T> +void test_equality() +{ + typename concrete_type_of<T>::type v1(1), v2(2), v2_(2), v3(3); + optional<T&> o1(v1), o2(v2), o2_(v2_), o3(v3), o3_(v3), oN, oN_; + // o2 and o2_ point to different objects; o3 and o3_ point to the same object + + BOOST_TEST(oN == oN); + BOOST_TEST(oN == oN_); + BOOST_TEST(oN_ == oN); + BOOST_TEST(o1 == o1); + BOOST_TEST(o2 == o2); + BOOST_TEST(o2 == o2_); + BOOST_TEST(o2_ == o2); + BOOST_TEST(o3 == o3); + BOOST_TEST(o3 == o3_); + BOOST_TEST(!(oN == o1)); + BOOST_TEST(!(o1 == oN)); + BOOST_TEST(!(o2 == o1)); + BOOST_TEST(!(o2 == oN)); + + BOOST_TEST(!(oN != oN)); + BOOST_TEST(!(oN != oN_)); + BOOST_TEST(!(oN_ != oN)); + BOOST_TEST(!(o1 != o1)); + BOOST_TEST(!(o2 != o2)); + BOOST_TEST(!(o2 != o2_)); + BOOST_TEST(!(o2_ != o2)); + BOOST_TEST(!(o3 != o3)); + BOOST_TEST(!(o3 != o3_)); + BOOST_TEST( (oN != o1)); + BOOST_TEST( (o1 != oN)); + BOOST_TEST( (o2 != o1)); + BOOST_TEST( (o2 != oN)); +} + +template <typename T> +void test_order() +{ + typename concrete_type_of<T>::type v1(1), v2(2), v2_(2), v3(3); + optional<T&> o1(v1), o2(v2), o2_(v2_), o3(v3), o3_(v3), oN, oN_; + // o2 and o2_ point to different objects; o3 and o3_ point to the same object + + BOOST_TEST(!(oN < oN)); + BOOST_TEST(!(oN < oN_)); + BOOST_TEST(!(oN_ < oN)); + BOOST_TEST(!(o1 < o1)); + BOOST_TEST(!(o2 < o2)); + BOOST_TEST(!(o2 < o2_)); + BOOST_TEST(!(o2_ < o2)); + BOOST_TEST(!(o3 < o3)); + BOOST_TEST(!(o3 < o3_)); + + BOOST_TEST( (oN <= oN)); + BOOST_TEST( (oN <= oN_)); + BOOST_TEST( (oN_ <= oN)); + BOOST_TEST( (o1 <= o1)); + BOOST_TEST( (o2 <= o2)); + BOOST_TEST( (o2 <= o2_)); + BOOST_TEST( (o2_ <= o2)); + BOOST_TEST( (o3 <= o3)); + BOOST_TEST( (o3 <= o3_)); + + BOOST_TEST(!(oN > oN)); + BOOST_TEST(!(oN > oN_)); + BOOST_TEST(!(oN_ > oN)); + BOOST_TEST(!(o1 > o1)); + BOOST_TEST(!(o2 > o2)); + BOOST_TEST(!(o2 > o2_)); + BOOST_TEST(!(o2_ > o2)); + BOOST_TEST(!(o3 > o3)); + BOOST_TEST(!(o3 > o3_)); + + BOOST_TEST( (oN >= oN)); + BOOST_TEST( (oN >= oN_)); + BOOST_TEST( (oN_ >= oN)); + BOOST_TEST( (o1 >= o1)); + BOOST_TEST( (o2 >= o2)); + BOOST_TEST( (o2 >= o2_)); + BOOST_TEST( (o2_ >= o2)); + BOOST_TEST( (o3 >= o3)); + BOOST_TEST( (o3 >= o3_)); + + BOOST_TEST( (oN < o1)); + BOOST_TEST( (oN_ < o1)); + BOOST_TEST( (oN < o2)); + BOOST_TEST( (oN_ < o2)); + BOOST_TEST( (oN < o2_)); + BOOST_TEST( (oN_ < o2_)); + BOOST_TEST( (oN < o3)); + BOOST_TEST( (oN_ < o3)); + BOOST_TEST( (oN < o3_)); + BOOST_TEST( (oN_ < o3_)); + BOOST_TEST( (o1 < o2)); + BOOST_TEST( (o1 < o2_)); + BOOST_TEST( (o1 < o3)); + BOOST_TEST( (o1 < o3_)); + BOOST_TEST( (o2 < o3)); + BOOST_TEST( (o2_ < o3)); + BOOST_TEST( (o2 < o3_)); + BOOST_TEST( (o2_ < o3_)); + + BOOST_TEST( (oN <= o1)); + BOOST_TEST( (oN_ <= o1)); + BOOST_TEST( (oN <= o2)); + BOOST_TEST( (oN_ <= o2)); + BOOST_TEST( (oN <= o2_)); + BOOST_TEST( (oN_ <= o2_)); + BOOST_TEST( (oN <= o3)); + BOOST_TEST( (oN_ <= o3)); + BOOST_TEST( (oN <= o3_)); + BOOST_TEST( (oN_ <= o3_)); + BOOST_TEST( (o1 <= o2)); + BOOST_TEST( (o1 <= o2_)); + BOOST_TEST( (o1 <= o3)); + BOOST_TEST( (o1 <= o3_)); + BOOST_TEST( (o2 <= o3)); + BOOST_TEST( (o2_ <= o3)); + BOOST_TEST( (o2 <= o3_)); + BOOST_TEST( (o2_ <= o3_)); + + BOOST_TEST(!(oN > o1)); + BOOST_TEST(!(oN_ > o1)); + BOOST_TEST(!(oN > o2)); + BOOST_TEST(!(oN_ > o2)); + BOOST_TEST(!(oN > o2_)); + BOOST_TEST(!(oN_ > o2_)); + BOOST_TEST(!(oN > o3)); + BOOST_TEST(!(oN_ > o3)); + BOOST_TEST(!(oN > o3_)); + BOOST_TEST(!(oN_ > o3_)); + BOOST_TEST(!(o1 > o2)); + BOOST_TEST(!(o1 > o2_)); + BOOST_TEST(!(o1 > o3)); + BOOST_TEST(!(o1 > o3_)); + BOOST_TEST(!(o2 > o3)); + BOOST_TEST(!(o2_ > o3)); + BOOST_TEST(!(o2 > o3_)); + BOOST_TEST(!(o2_ > o3_)); + + BOOST_TEST(!(oN >= o1)); + BOOST_TEST(!(oN_ >= o1)); + BOOST_TEST(!(oN >= o2)); + BOOST_TEST(!(oN_ >= o2)); + BOOST_TEST(!(oN >= o2_)); + BOOST_TEST(!(oN_ >= o2_)); + BOOST_TEST(!(oN >= o3)); + BOOST_TEST(!(oN_ >= o3)); + BOOST_TEST(!(oN >= o3_)); + BOOST_TEST(!(oN_ >= o3_)); + BOOST_TEST(!(o1 >= o2)); + BOOST_TEST(!(o1 >= o2_)); + BOOST_TEST(!(o1 >= o3)); + BOOST_TEST(!(o1 >= o3_)); + BOOST_TEST(!(o2 >= o3)); + BOOST_TEST(!(o2_ >= o3)); + BOOST_TEST(!(o2 >= o3_)); + BOOST_TEST(!(o2_ >= o3_)); + + BOOST_TEST(!(o1 < oN)); + BOOST_TEST(!(o1 < oN_)); + BOOST_TEST(!(o2 < oN)); + BOOST_TEST(!(o2 < oN_)); + BOOST_TEST(!(o2_ < oN)); + BOOST_TEST(!(o2_ < oN_)); + BOOST_TEST(!(o3 < oN)); + BOOST_TEST(!(o3 < oN_)); + BOOST_TEST(!(o3_ < oN)); + BOOST_TEST(!(o3_ < oN_)); + BOOST_TEST(!(o2 < oN)); + BOOST_TEST(!(o2_ < oN_)); + BOOST_TEST(!(o3 < oN)); + BOOST_TEST(!(o3_ < oN_)); + BOOST_TEST(!(o3 < oN)); + BOOST_TEST(!(o3 < oN_)); + BOOST_TEST(!(o3_ < oN)); + BOOST_TEST(!(o3_ < oN_)); +} + +template <typename T> +void test_swap() +{ + typename concrete_type_of<T>::type v1(1), v2(2); + optional<T&> o1(v1), o1_(v1), o2(v2), o2_(v2), oN, oN_; + + // swap(o1, o1); DOESN'T WORK +} + +template <typename T> +void test_optional_ref() +{ + test_not_containing_value_for<T>(); + test_direct_init_for<T>(); + test_clearing_the_value<T>(); + test_arrow<T>(); + test_equality<T>(); + test_order<T>(); + test_swap<T>(); +} + +template <typename T> +void test_optional_const_ref() +{ + test_not_containing_value_for<const T>(); + test_direct_init_for_const<T>(); + test_direct_init_for_noconst_const<T>(); + test_clearing_the_value<const T>(); + test_arrow_const<T>(); + test_arrow_noconst_const<T>(); + test_equality<const T>(); + test_order<const T>(); + //test_swap<T>(); +} + +int main() +{ + test_optional_ref<int>(); + test_optional_ref<ScopeGuard>(); + //test_optional_ref<Abstract>(); + + test_optional_const_ref<int>(); + test_optional_const_ref<ScopeGuard>(); + //test_optional_const_ref<Abstract>(); + + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_swap.cpp b/libs/optional/test/optional_test_swap.cpp new file mode 100644 index 000000000..b6802b18a --- /dev/null +++ b/libs/optional/test/optional_test_swap.cpp @@ -0,0 +1,360 @@ +// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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: +// fernando_cacciola@hotmail.com +// +// Revisions: +// 12 May 2008 (added more swap tests) +// + +#include "boost/optional/optional.hpp" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#include "boost/core/lightweight_test.hpp" + + +using boost::optional; +using boost::none; + +#define ARG(T) (static_cast< T const* >(0)) + +namespace optional_swap_test +{ + class default_ctor_exception : public std::exception {} ; + class copy_ctor_exception : public std::exception {} ; + class assignment_exception : public std::exception {} ; + + // + // Base class for swap test classes. Its assignment should not be called, when swapping + // optional<T> objects. (The default std::swap would do so.) + // + class base_class_with_forbidden_assignment + { + public: + base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &) + { + BOOST_TEST(!"The assignment should not be used while swapping!"); + throw assignment_exception(); + } + + virtual ~base_class_with_forbidden_assignment() {} + }; + + // + // Class without default constructor + // + class class_without_default_ctor : public base_class_with_forbidden_assignment + { + public: + char data; + explicit class_without_default_ctor(char arg) : data(arg) {} + }; + + // + // Class whose default constructor should not be used by optional::swap! + // + class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment + { + public: + char data; + explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {} + + class_whose_default_ctor_should_not_be_used() + { + BOOST_TEST(!"This default constructor should not be used while swapping!"); + throw default_ctor_exception(); + } + }; + + // + // Class whose default constructor should be used by optional::swap. + // Its copy constructor should be avoided! + // + class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment + { + public: + char data; + explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { } + + class_whose_default_ctor_should_be_used() : data('\0') { } + + class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &) + { + BOOST_TEST(!"This copy constructor should not be used while swapping!"); + throw copy_ctor_exception(); + } + }; + + // + // Class template whose default constructor should be used by optional::swap. + // Its copy constructor should be avoided! + // + template <class T> + class template_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment + { + public: + T data; + explicit template_whose_default_ctor_should_be_used(T arg) : data(arg) { } + + template_whose_default_ctor_should_be_used() : data('\0') { } + + template_whose_default_ctor_should_be_used(const template_whose_default_ctor_should_be_used &) + { + BOOST_TEST(!"This copy constructor should not be used while swapping!"); + throw copy_ctor_exception(); + } + }; + + // + // Class whose explicit constructor should be used by optional::swap. + // Its other constructors should be avoided! + // + class class_whose_explicit_ctor_should_be_used : public base_class_with_forbidden_assignment + { + public: + char data; + explicit class_whose_explicit_ctor_should_be_used(char arg) : data(arg) { } + + class_whose_explicit_ctor_should_be_used() + { + BOOST_TEST(!"This default constructor should not be used while swapping!"); + throw default_ctor_exception(); + } + + class_whose_explicit_ctor_should_be_used(const class_whose_explicit_ctor_should_be_used &) + { + BOOST_TEST(!"This copy constructor should not be used while swapping!"); + throw copy_ctor_exception(); + } + }; + + void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs) + { + std::swap(lhs.data, rhs.data); + } + + void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs) + { + std::swap(lhs.data, rhs.data); + } + + void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs) + { + std::swap(lhs.data, rhs.data); + } + + void swap(class_whose_explicit_ctor_should_be_used & lhs, class_whose_explicit_ctor_should_be_used & rhs) + { + std::swap(lhs.data, rhs.data); + } + + template <class T> + void swap(template_whose_default_ctor_should_be_used<T> & lhs, template_whose_default_ctor_should_be_used<T> & rhs) + { + std::swap(lhs.data, rhs.data); + } + + // + // optional<T>::swap should be customized when neither the copy constructor + // nor the default constructor of T are supposed to be used when swapping, e.g., + // for the following type T = class_whose_explicit_ctor_should_be_used. + // + void swap(boost::optional<class_whose_explicit_ctor_should_be_used> & x, boost::optional<class_whose_explicit_ctor_should_be_used> & y) + { + bool hasX(x); + bool hasY(y); + + if ( !hasX && !hasY ) + return; + + if( !hasX ) + x = boost::in_place('\0'); + else if ( !hasY ) + y = boost::in_place('\0'); + + optional_swap_test::swap(*x,*y); + + if( !hasX ) + y = boost::none ; + else if( !hasY ) + x = boost::none ; + } + + +} // End of namespace optional_swap_test. + + +namespace boost { + +// +// Compile time tweaking on whether or not swap should use the default constructor: +// + +template <> struct optional_swap_should_use_default_constructor< + optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ; + +template <> struct optional_swap_should_use_default_constructor< + optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ; + +template <class T> struct optional_swap_should_use_default_constructor< + optional_swap_test::template_whose_default_ctor_should_be_used<T> > : mpl::true_ {} ; + + +// +// Specialization of boost::swap: +// +template <> +void swap(optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & x, optional<optional_swap_test::class_whose_explicit_ctor_should_be_used> & y) +{ + optional_swap_test::swap(x, y); +} + +} // namespace boost + + +namespace std { + +// +// Specializations of std::swap: +// + +template <> +void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y) +{ + optional_swap_test::swap(x, y); +} + +template <> +void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y) +{ + optional_swap_test::swap(x, y); +} + +template <> +void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y) +{ + optional_swap_test::swap(x, y); +} + +template <> +void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y) +{ + optional_swap_test::swap(x, y); +} + +} // namespace std + + +// +// Tests whether the swap function works properly for optional<T>. +// Assumes that T has one data member, of type char. +// Returns true iff the test is passed. +// +template <class T> +void test_swap_function( T const* ) +{ + try + { + optional<T> obj1; + optional<T> obj2('a'); + + // Self-swap should not have any effect. + swap(obj1, obj1); + swap(obj2, obj2); + BOOST_TEST(!obj1); + BOOST_TEST(!!obj2 && obj2->data == 'a'); + + // Call non-member swap. + swap(obj1, obj2); + + // Test if obj1 and obj2 are really swapped. + BOOST_TEST(!!obj1 && obj1->data == 'a'); + BOOST_TEST(!obj2); + + // Call non-member swap one more time. + swap(obj1, obj2); + + // Test if obj1 and obj2 are swapped back. + BOOST_TEST(!obj1); + BOOST_TEST(!!obj2 && obj2->data == 'a'); + } + catch(const std::exception &) + { + // The swap function should not throw, for our test cases. + BOOST_TEST(!"throw in swap"); + } +} + +// +// Tests whether the optional<T>::swap member function works properly. +// Assumes that T has one data member, of type char. +// Returns true iff the test is passed. +// +template <class T> +void test_swap_member_function( T const* ) +{ + try + { + optional<T> obj1; + optional<T> obj2('a'); + + // Self-swap should not have any effect. + obj1.swap(obj1); + obj2.swap(obj2); + BOOST_TEST(!obj1); + BOOST_TEST(!!obj2 && obj2->data == 'a'); + + // Call member swap. + obj1.swap(obj2); + + // Test if obj1 and obj2 are really swapped. + BOOST_TEST(!!obj1 && obj1->data == 'a'); + BOOST_TEST(!obj2); + + // Call member swap one more time. + obj1.swap(obj2); + + // Test if obj1 and obj2 are swapped back. + BOOST_TEST(!obj1); + BOOST_TEST(!!obj2 && obj2->data == 'a'); + } + catch(const std::exception &) + { + BOOST_TEST(!"throw in swap"); + } +} + + +// +// Tests compile time tweaking of swap, by means of +// optional_swap_should_use_default_constructor. +// +void test_swap_tweaking() +{ + ( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) ); + ( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) ); + ( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) ); + ( test_swap_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) ); + ( test_swap_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) ); + ( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) ); + ( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) ); + ( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) ); + ( test_swap_member_function( ARG(optional_swap_test::class_whose_explicit_ctor_should_be_used) ) ); + ( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used<char>) ) ); +} + +int main() +{ + test_swap_tweaking(); + return boost::report_errors(); +} diff --git a/libs/optional/test/optional_test_the_compiler.cpp b/libs/optional/test/optional_test_the_compiler.cpp deleted file mode 100644 index dea10cb3c..000000000 --- a/libs/optional/test/optional_test_the_compiler.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// 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 -// -// Revisions: -// -#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/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ -#include "boost/static_assert.hpp" - -#include "boost/optional/optional.hpp" - -#ifdef __BORLANDC__ -#pragma hdrstop -#endif - -#include "boost/test/minimal.hpp" -#include "optional_test_common.cpp" - - -const int global_i = 0; - -class TestingReferenceBinding -{ -public: - TestingReferenceBinding(const int& ii) - { - BOOST_CHECK(&ii == &global_i); - } - - void operator=(const int& ii) - { - BOOST_CHECK(&ii == &global_i); - } - #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - void operator=(int&&) - { - BOOST_CHECK(false); - } - #endif -}; - -class TestingReferenceBinding2 // same definition as above, I need a different type -{ -public: - TestingReferenceBinding2(const int& ii) - { - BOOST_CHECK(&ii == &global_i); - } - - void operator=(const int& ii) - { - BOOST_CHECK(&ii == &global_i); - } - #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - void operator=(int&&) - { - BOOST_CHECK(false); - } - #endif -}; - - -void test_broken_compiler() -{ -// we are not testing boost::optional here, but the c++ compiler -// if this test fails, optional references will obviously fail too - - const int& iref = global_i; - BOOST_CHECK(&iref == &global_i); - - TestingReferenceBinding ttt = global_i; - ttt = global_i; - - TestingReferenceBinding2 ttt2 = iref; - ttt2 = iref; -} - - -int test_main( int, char* [] ) -{ - try - { - test_broken_compiler(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } - - return 0; -} - - diff --git a/libs/optional/test/optional_test_tie.cpp b/libs/optional/test/optional_test_tie.cpp index c4fc4ed33..b5c5818f1 100644 --- a/libs/optional/test/optional_test_tie.cpp +++ b/libs/optional/test/optional_test_tie.cpp @@ -1,4 +1,5 @@ // Copyright (C) 2003, Fernando Luis Cacciola Carballal. +// Copyright (C) 2015 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 @@ -8,57 +9,66 @@ // // 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" -#include "boost/tuple/tuple.hpp" +#include "boost/optional/optional.hpp" #ifdef __BORLANDC__ #pragma hdrstop #endif -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" +#include "boost/core/lightweight_test.hpp" +#include "boost/none.hpp" +#include "boost/tuple/tuple.hpp" -// Test boost::tie() interoperabiliy. -int test_main( int, char* [] ) +struct counting_oracle { - typedef X T ; - - try - { - TRACE( std::endl << BOOST_CURRENT_FUNCTION ); + int val; + counting_oracle() : val() { ++default_ctor_count; } + counting_oracle(int v) : val(v) { ++val_ctor_count; } + counting_oracle(const counting_oracle& rhs) : val(rhs.val) { ++copy_ctor_count; } + counting_oracle& operator=(const counting_oracle& rhs) { val = rhs.val; ++copy_assign_count; return *this; } + ~counting_oracle() { ++dtor_count; } - T z(0); - T a(1); - T b(2); + static int dtor_count; + static int default_ctor_count; + static int val_ctor_count; + static int copy_ctor_count; + static int copy_assign_count; + static int equals_count; - optional<T> oa, ob ; + friend bool operator==(const counting_oracle& lhs, const counting_oracle& rhs) { ++equals_count; return lhs.val == rhs.val; } - // T::T( T const& x ) is used - set_pending_dtor( ARG(T) ) ; - set_pending_copy( ARG(T) ) ; - boost::tie(oa,ob) = std::make_pair(a,b) ; - check_is_not_pending_dtor( ARG(T) ) ; - check_is_not_pending_copy( ARG(T) ) ; - check_initialized(oa); - check_initialized(ob); - check_value(oa,a,z); - check_value(ob,b,z); - - } - catch ( ... ) + static void clear_count() { - BOOST_ERROR("Unexpected Exception caught!"); + dtor_count = default_ctor_count = val_ctor_count = copy_ctor_count = copy_assign_count = equals_count = 0; } +}; + +int counting_oracle::dtor_count = 0; +int counting_oracle::default_ctor_count = 0; +int counting_oracle::val_ctor_count = 0; +int counting_oracle::copy_ctor_count = 0; +int counting_oracle::copy_assign_count = 0; +int counting_oracle::equals_count = 0; + +// Test boost::tie() interoperability. +int main() +{ + const std::pair<counting_oracle, counting_oracle> pair(1, 2); + counting_oracle::clear_count(); + + boost::optional<counting_oracle> o1, o2; + boost::tie(o1, o2) = pair; + + BOOST_TEST(o1); + BOOST_TEST(o2); + BOOST_TEST(*o1 == counting_oracle(1)); + BOOST_TEST(*o2 == counting_oracle(2)); + BOOST_TEST_EQ(2, counting_oracle::copy_ctor_count); + BOOST_TEST_EQ(0, counting_oracle::copy_assign_count); + BOOST_TEST_EQ(0, counting_oracle::default_ctor_count); - return 0; + return boost::report_errors(); } diff --git a/libs/optional/test/optional_test_value_access.cpp b/libs/optional/test/optional_test_value_access.cpp index 63d65b9e2..1759588bf 100644 --- a/libs/optional/test/optional_test_value_access.cpp +++ b/libs/optional/test/optional_test_value_access.cpp @@ -8,18 +8,6 @@ // // You are welcome to contact the author at: // akrzemi1@gmail.com -// -// Revisions: -// -#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/mpl/bool.hpp" -#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_ #include "boost/optional/optional.hpp" @@ -27,11 +15,10 @@ #pragma hdrstop #endif -#include "boost/none.hpp" +#include "boost/core/ignore_unused.hpp" +#include "boost/core/lightweight_test.hpp" -#include "boost/test/minimal.hpp" - -#include "optional_test_common.cpp" +using boost::optional; struct IntWrapper { @@ -48,10 +35,10 @@ void test_function_value_or_for() optional<T> oM1(1); const optional<T> oC2(2); - BOOST_CHECK(oM0.value_or(5) == 5); - BOOST_CHECK(oC0.value_or(5) == 5); - BOOST_CHECK(oM1.value_or(5) == 1); - BOOST_CHECK(oC2.value_or(5) == 2); + BOOST_TEST(oM0.value_or(5) == 5); + BOOST_TEST(oC0.value_or(5) == 5); + BOOST_TEST(oM1.value_or(5) == 1); + BOOST_TEST(oC2.value_or(5) == 2); } template <typename T> @@ -64,36 +51,24 @@ void test_function_value_for() try { T& v = o1.value(); - BOOST_CHECK(v == 1); + BOOST_TEST(v == 1); } catch(...) { - BOOST_CHECK(false); + BOOST_TEST(false); } try { T const& v = oC.value(); - BOOST_CHECK(v == 2); + BOOST_TEST(v == 2); } catch(...) { - BOOST_CHECK(false); + BOOST_TEST(false); } - try - { - T& v = o0.value(); - BOOST_CHECK(false); - boost::ignore_unused(v); - } - catch(boost::bad_optional_access const&) - { - } - catch(...) - { - BOOST_CHECK(false); - } + BOOST_TEST_THROWS(o0.value(), boost::bad_optional_access); } void test_function_value() @@ -120,12 +95,12 @@ void test_function_value_or() test_function_value_or_for<IntWrapper>(); optional<int> oi(1); - BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 1); - BOOST_CHECK(FatToIntConverter::conversions == 0); + BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 1); + BOOST_TEST(FatToIntConverter::conversions == 0); oi = boost::none; - BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 2); - BOOST_CHECK(FatToIntConverter::conversions == 1); + BOOST_TEST(oi.value_or(FatToIntConverter(2)) == 2); + BOOST_TEST(FatToIntConverter::conversions == 1); } @@ -156,42 +131,34 @@ void test_function_value_or_eval() FunM funM; FunC funC; - BOOST_CHECK(o1.value_or_eval(funM) == 1); - BOOST_CHECK(oN.value_or_eval(funM) == 5); - BOOST_CHECK(o1.value_or_eval(FunM()) == 1); - BOOST_CHECK(oN.value_or_eval(FunM()) == 5); + BOOST_TEST_EQ(o1.value_or_eval(funM), 1); + BOOST_TEST_EQ(oN.value_or_eval(funM), 5); + BOOST_TEST_EQ(o1.value_or_eval(FunM()), 1); + BOOST_TEST_EQ(oN.value_or_eval(FunM()), 5); - BOOST_CHECK(o1.value_or_eval(funC) == 1); - BOOST_CHECK(oN.value_or_eval(funC) == 6); - BOOST_CHECK(o1.value_or_eval(FunC()) == 1); - BOOST_CHECK(oN.value_or_eval(FunC()) == 6); + BOOST_TEST_EQ(o1.value_or_eval(funC), 1); + BOOST_TEST_EQ(oN.value_or_eval(funC), 6); + BOOST_TEST_EQ(o1.value_or_eval(FunC()), 1); + BOOST_TEST_EQ(oN.value_or_eval(FunC()), 6); - BOOST_CHECK(o1.value_or_eval(funP) == 1); - BOOST_CHECK(oN.value_or_eval(funP) == 7); + BOOST_TEST_EQ(o1.value_or_eval(funP), 1); + BOOST_TEST_EQ(oN.value_or_eval(funP), 7); #ifndef BOOST_NO_CXX11_LAMBDAS - BOOST_CHECK(o1.value_or_eval([](){return 8;}) == 1); - BOOST_CHECK(oN.value_or_eval([](){return 8;}) == 8); + BOOST_TEST_EQ(o1.value_or_eval([](){return 8;}), 1); + BOOST_TEST_EQ(oN.value_or_eval([](){return 8;}), 8); #endif try { - BOOST_CHECK(o1.value_or_eval(throw_) == 1); + BOOST_TEST_EQ(o1.value_or_eval(throw_), 1); } catch(...) { - BOOST_CHECK(false); + BOOST_TEST(false); } - try - { - BOOST_CHECK(oN.value_or_eval(throw_) == 1); - BOOST_CHECK(false); - } - catch(...) - { - BOOST_CHECK(true); - } + BOOST_TEST_THROWS(oN.value_or_eval(throw_), int); } const optional<std::string> makeConstOptVal() @@ -244,21 +211,12 @@ void test_move_only_getters() #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS -int test_main( int, char* [] ) +int main() { - try - { - test_function_value(); - test_function_value_or(); - test_function_value_or_eval(); - test_const_move(); - } - catch ( ... ) - { - BOOST_ERROR("Unexpected Exception caught!"); - } + test_function_value(); + test_function_value_or(); + test_function_value_or_eval(); + test_const_move(); - return 0; + return boost::report_errors(); } - - diff --git a/libs/optional/test/testable_classes.hpp b/libs/optional/test/testable_classes.hpp new file mode 100644 index 000000000..e18359f93 --- /dev/null +++ b/libs/optional/test/testable_classes.hpp @@ -0,0 +1,91 @@ +// 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/libs/optional for documentation. +// +// You are welcome to contact the author at: +// akrzemi1@gmail.com + +#ifndef BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP +#define BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP + +struct ScopeGuard // no copy/move ctor/assign +{ + int val_; + explicit ScopeGuard(int v) : val_(v) {} + int& val() { return val_; } + const int& val() const { return val_; } + +private: + ScopeGuard(ScopeGuard const&); + void operator=(ScopeGuard const&); +}; + +struct Abstract +{ + virtual int& val() = 0; + virtual const int& val() const = 0; + virtual ~Abstract() {} + Abstract(){} + +private: + Abstract(Abstract const&); + void operator=(Abstract const&); +}; + +struct Impl : Abstract +{ + int val_; + Impl(int v) : val_(v) {} + int& val() { return val_; } + const int& val() const { return val_; } +}; + +template <typename T> +struct concrete_type_of +{ + typedef T type; +}; + +template <> +struct concrete_type_of<Abstract> +{ + typedef Impl type; +}; + +template <> +struct concrete_type_of<const Abstract> +{ + typedef const Impl type; +}; + +template <typename T> +struct has_arrow +{ + static const bool value = true; +}; + +template <> +struct has_arrow<int> +{ + static const bool value = false; +}; + +int& val(int& i) { return i; } +int& val(Abstract& a) { return a.val(); } +int& val(ScopeGuard& g) { return g.val(); } + +const int& val(const int& i) { return i; } +const int& val(const Abstract& a) { return a.val(); } +const int& val(const ScopeGuard& g) { return g.val(); } + +bool operator==(const Abstract& l, const Abstract& r) { return l.val() == r.val(); } +bool operator==(const ScopeGuard& l, const ScopeGuard& r) { return l.val() == r.val(); } + +bool operator<(const Abstract& l, const Abstract& r) { return l.val() < r.val(); } +bool operator<(const ScopeGuard& l, const ScopeGuard& r) { return l.val() < r.val(); } + +#endif //BOOST_OPTIONAL_TEST_TESTABKE_CLASSES_AK_07JAN2015_HPP |
