diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk
index fcc37f8..a29137c 100644
--- a/doc/91_relnotes.qbk
+++ b/doc/91_relnotes.qbk
@@ -15,6 +15,7 @@
* Remove deprecation mark from `reset()` method (without arguments).
* Fixed [@https://github.com/boostorg/optional/issues/59 issue #59].
+* Fixed bug with initialization of certain wrapper types in clang with -std=c++03. See [@https://github.com/boostorg/optional/pull/64 pr #64].
[heading Boost Release 1.68]
diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html
index dcf21f9..3d84696 100644
--- a/doc/html/boost_optional/relnotes.html
+++ b/doc/html/boost_optional/relnotes.html
@@ -39,6 +39,10 @@
Fixed issue
#59.
+
+ Fixed bug with initialization of certain wrapper types in clang with -std=c++03.
+ See pr #64.
+
diff --git a/doc/html/index.html b/doc/html/index.html
index 4fe8adc..39d99e7 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -145,7 +145,7 @@
-Last revised: October 29, 2018 at 21:06:01 GMT |
+Last revised: November 08, 2018 at 17:44:53 GMT |
|
diff --git a/include/boost/optional/detail/optional_trivially_copyable_base.hpp b/include/boost/optional/detail/optional_trivially_copyable_base.hpp
index 0734f62..5a37eac 100644
--- a/include/boost/optional/detail/optional_trivially_copyable_base.hpp
+++ b/include/boost/optional/detail/optional_trivially_copyable_base.hpp
@@ -30,7 +30,7 @@ class tc_optional_base : public optional_tag
:
m_initialized(false) {}
- tc_optional_base ( argument_type val )
+ tc_optional_base ( init_value_tag, argument_type val )
:
m_initialized(true), m_storage(val) {}
diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp
index 104bca4..90acd40 100644
--- a/include/boost/optional/optional.hpp
+++ b/include/boost/optional/optional.hpp
@@ -107,7 +107,9 @@ using optional_ns::in_place_init_if;
namespace optional_detail {
-struct optional_tag {} ;
+struct init_value_tag {};
+
+struct optional_tag {};
template
@@ -147,7 +149,7 @@ class optional_base : public optional_tag
// Creates an optional initialized with 'val'.
// Can throw if T::T(T const&) does
- optional_base ( argument_type val )
+ optional_base ( init_value_tag, argument_type val )
:
m_initialized(false)
{
@@ -157,7 +159,7 @@ class optional_base : public optional_tag
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// move-construct an optional initialized from an rvalue-ref to 'val'.
// Can throw if T::T(T&&) does
- optional_base ( rval_reference_type val )
+ optional_base ( init_value_tag, rval_reference_type val )
:
m_initialized(false)
{
@@ -870,12 +872,12 @@ class optional
// Creates an optional initialized with 'val'.
// Can throw if T::T(T const&) does
- optional ( argument_type val ) : base(val) {}
+ optional ( argument_type val ) : base(optional_detail::init_value_tag(), val) {}
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates an optional initialized with 'move(val)'.
// Can throw if T::T(T &&) does
- optional ( rval_reference_type val ) : base( boost::forward(val) )
+ optional ( rval_reference_type val ) : base(optional_detail::init_value_tag(), boost::forward(val))
{}
#endif
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index f6912a9..7936ad7 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -76,6 +76,7 @@ import testing ;
[ run optional_test_static_properties.cpp ]
[ compile optional_test_maybe_uninitialized_warning.cpp ]
[ compile optional_test_deleted_default_ctor.cpp ]
+ [ compile optional_test_constructible_from_other.cpp ]
#[ run optional_xconfig_HACK_TO_LIST_PREDEFINED_MACROS.cpp ]
[ run optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_pass.cpp ]
[ run-fail optional_xconfig_NO_PROPER_ASSIGN_FROM_CONST_INT_fail.cpp ]
diff --git a/test/optional_test_constructible_from_other.cpp b/test/optional_test_constructible_from_other.cpp
new file mode 100644
index 0000000..e106b69
--- /dev/null
+++ b/test/optional_test_constructible_from_other.cpp
@@ -0,0 +1,57 @@
+// Copyright (c) 2018 Andrey Semashev
+//
+// 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)
+
+// The test verifies that Boost.Optional copy constructors do not attempt to invoke
+// the element type initializing constructors from templated arguments
+
+#include
+#include
+
+struct no_type
+{
+ char data;
+};
+
+struct yes_type
+{
+ char data[2];
+};
+
+template< unsigned int Size >
+struct size_tag {};
+
+template< typename T, typename U >
+struct is_constructible
+{
+ template< typename T1, typename U1 >
+ static yes_type check_helper(size_tag< sizeof(static_cast< T1 >(U1())) >*);
+ template< typename T1, typename U1 >
+ static no_type check_helper(...);
+
+ static const bool value = sizeof(check_helper< T, U >(0)) == sizeof(yes_type);
+};
+
+template< typename T >
+class wrapper
+{
+public:
+ wrapper() {}
+ wrapper(wrapper const&) {}
+ template< typename U >
+ wrapper(U const&, typename boost::enable_if_c< is_constructible< T, U >::value, int >::type = 0) {}
+};
+
+inline boost::optional< wrapper< int > > foo()
+{
+ return boost::optional< wrapper< int > >();
+}
+
+int main()
+{
+ // Invokes boost::optional copy constructor. Should not invoke wrapper constructor from U.
+ boost::optional< wrapper< int > > res = foo();
+ return 0;
+}
diff --git a/test/optional_test_tc_base.cpp b/test/optional_test_tc_base.cpp
index 8107f7b..a1d293b 100644
--- a/test/optional_test_tc_base.cpp
+++ b/test/optional_test_tc_base.cpp
@@ -58,10 +58,20 @@ struct W
void test_value_init()
{
+#ifndef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
{
S s;
W w{s};
}
+#endif
+ {
+ S s;
+ W w(s);
+ }
+}
+
+void test_optoinal_reference_wrapper()
+{
boost::optional > o;
BOOST_TEST(boost::none == o);
}
@@ -70,6 +80,7 @@ int main()
{
test_tc_base();
test_value_init();
+ test_optoinal_reference_wrapper();
return boost::report_errors();
}