From 5c69bac12fd362242838b7c622c4552903808065 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Sat, 26 Apr 2014 00:22:39 +0200 Subject: [PATCH] Fixed unit tests (still need to add more unit tests for move semantics) --- include/boost/optional/optional.hpp | 75 +++++++++++++++++++---------- test/Jamfile.v2 | 24 ++++----- test/optional_test_move.cpp | 3 +- 3 files changed, 64 insertions(+), 38 deletions(-) diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index c063e94..6933a05 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -27,6 +27,7 @@ #include #include #include + #include #include #include #include @@ -425,6 +426,41 @@ class optional_base : public optional_tag #endif #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT + +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + // Constructs in-place using the given factory + template + void construct ( Expr&& factory, in_place_factory_base const* ) + { + BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ; + boost_optional_detail::construct(factory, m_storage.address()); + m_initialized = true ; + } + + // Constructs in-place using the given typed factory + template + void construct ( Expr&& factory, typed_in_place_factory_base const* ) + { + BOOST_STATIC_ASSERT ( ::boost::mpl::not_::value ) ; + factory.apply(m_storage.address()) ; + m_initialized = true ; + } + + template + void assign_expr_to_initialized ( Expr&& factory, in_place_factory_base const* tag ) + { + destroy(); + construct(factory,tag); + } + + // Constructs in-place using the given typed factory + template + void assign_expr_to_initialized ( Expr&& factory, typed_in_place_factory_base const* tag ) + { + destroy(); + construct(factory,tag); + } +#else // Constructs in-place using the given factory template void construct ( Expr const& factory, in_place_factory_base const* ) @@ -459,6 +495,8 @@ class optional_base : public optional_tag } #endif +#endif + #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES // Constructs using any expression implicitly convertible to the single argument // of a one-argument T constructor. @@ -683,12 +721,16 @@ class optional : public optional_detail::optional_base // Can throw if the resolved T ctor throws. #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES -#ifndef BOOST_NO_SFINAE -#else + template - explicit optional ( Expr&& expr, typename boost::disable_if::type, optional> >::type* = 0 ) + explicit optional ( Expr&& expr, + typename boost::disable_if_c< + (boost::is_base_of::type>::value) || + boost::is_same::type, optional>::value || + boost::is_same::type, none_t>::value >::type* = 0 + ) : base(boost::forward(expr),boost::addressof(expr)) {} -#endif + #else template explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {} @@ -707,11 +749,6 @@ class optional : public optional_detail::optional_base : base( boost::move(rhs) ) {} -#ifdef BOOST_NO_SFINAE - // To avoid too perfect forwarding - optional ( optional& rhs ) : base( static_cast(rhs) ) {} -#endif - #endif // No-throw (assuming T::~T() doesn't) ~optional() {} @@ -722,14 +759,10 @@ class optional : public optional_detail::optional_base #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES template -#if !defined BOOST_NO_SFINAE - typename boost::disable_if< - boost::is_same::type, optional>, + typename boost::disable_if_c< + boost::is_base_of::type>::value || boost::is_same::type, optional>::value || boost::is_same::type, none_t>::value, optional& >::type -#else - optional& -#endif operator= ( Expr&& expr ) { this->assign_expr(boost::forward(expr),boost::addressof(expr)); @@ -743,8 +776,8 @@ class optional : public optional_detail::optional_base this->assign_expr(expr,boost::addressof(expr)); return *this ; } -#endif -#endif +#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES +#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) // Assigns from another convertible optional (converts && deep-copies the rhs value) // Requires a valid conversion from U to T. @@ -773,14 +806,6 @@ class optional : public optional_detail::optional_base this->assign( static_cast(rhs) ) ; return *this ; } -#ifdef BOOST_NO_SFINAE - // to avoid too perfect forwarding - optional& operator= ( optional& rhs ) - { - this->assign( static_cast(rhs) ) ; - return *this ; - } -#endif #endif // Assigns from a T (deep-copies the rhs value) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 62ab883..a146f72 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -17,18 +17,18 @@ import testing ; { test-suite optional : [ run optional_test.cpp ] - #[ run optional_test_tie.cpp ] - #[ run optional_test_ref.cpp ] - #[ run optional_test_inplace.cpp ] - #[ run optional_test_io.cpp ] + [ run optional_test_tie.cpp ] + [ run optional_test_ref.cpp ] + [ run optional_test_inplace.cpp ] + [ run optional_test_io.cpp ] [ run optional_test_move.cpp ] - #[ compile-fail optional_test_fail1.cpp ] - #[ compile-fail optional_test_fail3a.cpp ] - #[ compile-fail optional_test_fail3b.cpp ] - #[ compile-fail optional_test_ref_fail1.cpp ] - #[ compile-fail optional_test_ref_fail3.cpp ] - #[ compile-fail optional_test_ref_fail4.cpp ] - #[ compile-fail optional_test_inplace_fail.cpp ] - #[ compile-fail optional_test_inplace_fail2.cpp ] + [ compile-fail optional_test_fail1.cpp ] + [ compile-fail optional_test_fail3a.cpp ] + [ compile-fail optional_test_fail3b.cpp ] + [ compile-fail optional_test_ref_fail1.cpp ] + [ compile-fail optional_test_ref_fail3.cpp ] + [ compile-fail optional_test_ref_fail4.cpp ] + [ compile-fail optional_test_inplace_fail.cpp ] + [ compile-fail optional_test_inplace_fail2.cpp ] ; } diff --git a/test/optional_test_move.cpp b/test/optional_test_move.cpp index 986ce43..0f52c2d 100644 --- a/test/optional_test_move.cpp +++ b/test/optional_test_move.cpp @@ -146,7 +146,8 @@ void test_move_ctor_from_optional_T() void test_move_assign_from_U() { - optional o1; + optional 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);