diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk
index 4af88a5..ec6aaed 100644
--- a/doc/91_relnotes.qbk
+++ b/doc/91_relnotes.qbk
@@ -20,6 +20,7 @@
* you can swap optional references: it is like swapping pointers: shalow, underlying objects are not affected,
* optional references to abstract types work.
* Documented nested typedefs ([@https://svn.boost.org/trac/boost/ticket/5193 Trac #5193]).
+* Made the optional value constructor SFINAE-friendly, which fixes [@https://svn.boost.org/trac/boost/ticket/12002 Trac #12002].
[heading Boost Release 1.60]
diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html
index 0f05f9e..b505936 100644
--- a/doc/html/boost_optional/relnotes.html
+++ b/doc/html/boost_optional/relnotes.html
@@ -60,6 +60,9 @@
Documented nested typedefs (Trac
#5193).
+
+ Made the optional value constructor SFINAE-friendly, which fixes Trac #12002.
+
diff --git a/doc/html/index.html b/doc/html/index.html
index 12d4f4d..74917d5 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -144,7 +144,7 @@
-Last revised: February 18, 2016 at 23:24:54 GMT |
+Last revised: February 19, 2016 at 17:38:50 GMT |
|
diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp
index 3d89928..af117bd 100644
--- a/include/boost/optional/optional.hpp
+++ b/include/boost/optional/optional.hpp
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -565,17 +566,39 @@ class optional_base : public optional_tag
storage_type m_storage ;
} ;
-
+// definition of metafunciton is_optional_val_init_candidate
template
struct is_optional_related
- : boost::conditional::type>::value
- || boost::is_same::type, none_t>::value,
+ : boost::conditional< boost::is_base_of::type>::value
+ || boost::is_same::type, none_t>::value,
boost::true_type, boost::false_type>::type
{};
-
-template
+
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && !defined(BOOST_NO_CXX11_DECLTYPE) && !BOOST_WORKAROUND(BOOST_MSVC, < 1800) && !BOOST_WORKAROUND(BOOST_GCC_VERSION, < 40500)
+ // this condition is a copy paste from is_constructible.hpp
+
+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::true_type, boost::false_type>::type
+{};
+
+#else
+
+#define BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT
+
+template
+struct is_convertible_to_T_or_factory : boost::true_type
+{};
+
+#endif // is_convertible condition
+
+template
struct is_optional_val_init_candidate
- : boost::conditional::value, boost::true_type, boost::false_type>::type
+ : boost::conditional< !is_optional_related::value && is_convertible_to_T_or_factory::value
+ , boost::true_type, boost::false_type>::type
{};
} // namespace optional_detail
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index e085c29..1800142 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -39,6 +39,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-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_value_ctor.cpp
new file mode 100644
index 0000000..d7af15d
--- /dev/null
+++ b/test/optional_test_sfinae_friendly_value_ctor.cpp
@@ -0,0 +1,38 @@
+// 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
+
+using boost::optional;
+
+#if (!defined BOOST_OPTIONAL_DETAIL_NO_IS_CONSTRUCTIBLE_TRAIT)
+
+struct X {};
+struct Y {};
+
+struct Resource
+{
+ explicit Resource(const X&) {}
+};
+
+BOOST_STATIC_ASSERT(( boost::is_constructible::value));
+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));
+
+#endif
+
+int main() { }