diff --git a/include/boost/optional/detail/optional_config.hpp b/include/boost/optional/detail/optional_config.hpp index 648744e..5c388fb 100644 --- a/include/boost/optional/detail/optional_config.hpp +++ b/include/boost/optional/detail/optional_config.hpp @@ -96,4 +96,17 @@ #endif // defined(__GNUC__) +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) && !defined(__SUNPRO_CC) + // this condition is a copy paste from is_constructible.hpp + // I also disable SUNPRO, as it seems not to support type_traits correctly +#else +# define BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT +#endif + +#if defined __SUNPRO_CC +# define BOOST_OPTIONAL_DETAIL_USE_SFINAE_FRIENDLY_CONSTRUCTORS +#elif (defined _MSC_FULL_VER) && (_MSC_FULL_VER < 190023026) +# define BOOST_OPTIONAL_DETAIL_USE_SFINAE_FRIENDLY_CONSTRUCTORS +#endif + #endif // header guard diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 22c53a2..e450898 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -733,9 +733,7 @@ struct is_optional_related boost::true_type, boost::false_type>::type {}; -#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500) && !defined(__SUNPRO_CC) - // this condition is a copy paste from is_constructible.hpp - // I also disable SUNPRO, as it seems not to support type_traits correctly +#if !defined(BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT) template struct is_convertible_to_T_or_factory @@ -751,8 +749,6 @@ struct is_optional_constructible : boost::is_constructible #else -#define BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT - template struct is_convertible_to_T_or_factory : boost::true_type {}; @@ -820,8 +816,11 @@ class optional : public optional_detail::optional_base // Requires a valid conversion from U to T. // Can throw if T::T(U const&) does template - explicit optional ( optional const& rhs, - typename boost::enable_if< optional_detail::is_optional_constructible >::type* = 0) + explicit optional ( optional const& rhs +#ifdef BOOST_OPTIONAL_DETAIL_USE_SFINAE_FRIENDLY_CONSTRUCTORS + ,typename boost::enable_if< optional_detail::is_optional_constructible >::type* = 0 +#endif + ) : base() { @@ -834,8 +833,11 @@ class optional : public optional_detail::optional_base // Requires a valid conversion from U to T. // Can throw if T::T(U&&) does template - explicit optional ( optional && rhs, - typename boost::enable_if< optional_detail::is_optional_constructible >::type* = 0 ) + explicit optional ( optional && rhs +#ifdef BOOST_OPTIONAL_DETAIL_USE_SFINAE_FRIENDLY_CONSTRUCTORS + ,typename boost::enable_if< optional_detail::is_optional_constructible >::type* = 0 +#endif + ) : base() { @@ -954,8 +956,7 @@ class optional : public optional_detail::optional_base } #endif - -#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX // Assigns from a T (deep-moves/copies the rhs value) template @@ -965,6 +966,7 @@ class optional : public optional_detail::optional_base this->assign( boost::forward(val) ) ; return *this ; } + #else // Assigns from a T (deep-copies the rhs value) @@ -975,8 +977,17 @@ class optional : public optional_detail::optional_base return *this ; } +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + // Assigns from a T (deep-moves the rhs value) + optional& operator= ( rval_reference_type val ) + { + this->assign( boost::move(val) ) ; + return *this ; + } #endif +#endif // BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + // Assigns from a "none" // Which destroys the current value, if any, leaving this UNINITIALIZED // No-throw (assuming T::~T() doesn't) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 919ba67..1820ba4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -42,7 +42,7 @@ import testing ; [ run optional_test_emplace.cpp ] [ run optional_test_minimum_requirements.cpp ] [ run optional_test_msvc_bug_workaround.cpp ] - [ compile optional_test_sfinae_friendly_value_ctor.cpp ] + [ compile optional_test_sfinae_friendly_ctor.cpp ] [ compile-fail optional_test_ref_convert_assign_const_int_prevented.cpp ] [ compile-fail optional_test_fail1.cpp ] [ compile-fail optional_test_fail3a.cpp ] diff --git a/test/optional_test_sfinae_friendly_value_ctor.cpp b/test/optional_test_sfinae_friendly_ctor.cpp similarity index 95% rename from test/optional_test_sfinae_friendly_value_ctor.cpp rename to test/optional_test_sfinae_friendly_ctor.cpp index 6c2abda..3fefc0e 100644 --- a/test/optional_test_sfinae_friendly_value_ctor.cpp +++ b/test/optional_test_sfinae_friendly_ctor.cpp @@ -33,6 +33,7 @@ BOOST_STATIC_ASSERT(( !boost::is_constructible::value )); BOOST_STATIC_ASSERT(( boost::is_constructible, const X&>::value )); BOOST_STATIC_ASSERT(( !boost::is_constructible, const Y&>::value )); +#ifdef BOOST_OPTIONAL_DETAIL_USE_SFINAE_FRIENDLY_CONSTRUCTORS BOOST_STATIC_ASSERT(( boost::is_constructible< optional< optional >, optional >::value )); BOOST_STATIC_ASSERT(( !boost::is_constructible< optional, optional< optional > >::value )); @@ -41,6 +42,7 @@ BOOST_STATIC_ASSERT(( !boost::is_constructible< optional, const optional< o BOOST_STATIC_ASSERT(( boost::is_constructible, const optional&>::value )); BOOST_STATIC_ASSERT(( !boost::is_constructible, const optional&>::value )); +#endif #endif