diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index ef62aa7..22c53a2 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -741,7 +741,7 @@ template struct is_convertible_to_T_or_factory : boost::conditional< boost::is_base_of::type>::value || boost::is_base_of::type>::value - || boost::is_constructible::value + || (boost::is_constructible::value && !boost::is_same::type>::value) , boost::true_type, boost::false_type>::type {}; @@ -954,6 +954,19 @@ class optional : public optional_detail::optional_base } #endif + +#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES + + // Assigns from a T (deep-moves/copies the rhs value) + template + BOOST_DEDUCED_TYPENAME boost::enable_if::type>, optional&>::type + operator= ( T_&& val ) + { + this->assign( boost::forward(val) ) ; + return *this ; + } +#else + // Assigns from a T (deep-copies the rhs value) // Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED optional& operator= ( argument_type val ) @@ -961,16 +974,9 @@ class optional : public optional_detail::optional_base this->assign( val ) ; 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 - + // 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 ec93e18..919ba67 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -21,6 +21,7 @@ import testing ; [ run optional_test_swap.cpp ] [ run optional_test_conversions_from_U.cpp ] [ run optional_test_convert_from_T.cpp ] + [ run optional_test_empty_braces.cpp ] [ run optional_test_tie.cpp ] [ run optional_test_ref_assign_portable_minimum.cpp ] [ run optional_test_ref_assign_mutable_int.cpp ] diff --git a/test/optional_test_empty_braces.cpp b/test/optional_test_empty_braces.cpp new file mode 100644 index 0000000..593a68f --- /dev/null +++ b/test/optional_test_empty_braces.cpp @@ -0,0 +1,57 @@ +// Copyright (C) 2016 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" + +//#ifndef BOOST_OPTIONAL_NO_CONVERTING_ASSIGNMENT +//#ifndef BOOST_OPTIONAL_NO_CONVERTING_COPY_CTOR + +using boost::optional; + +struct Value +{ + explicit Value(int) {} +}; + +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX +template +void test_brace_init() +{ + optional o = {}; + BOOST_TEST(!o); +} + +template +void test_brace_assign() +{ + optional o; + o = {}; + BOOST_TEST(!o); +} +#endif + +int main() +{ +#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX + test_brace_init(); + test_brace_init(); + test_brace_assign(); + test_brace_assign(); +#endif + + return boost::report_errors(); +}