From f6e09fbf9c0418364d88fcc15b2c5ccf95a489ef Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Fri, 19 Feb 2016 18:41:42 +0100 Subject: [PATCH] value constructor is sfinae-friendly --- doc/91_relnotes.qbk | 1 + doc/html/boost_optional/relnotes.html | 3 ++ doc/html/index.html | 2 +- include/boost/optional/optional.hpp | 35 ++++++++++++++--- test/Jamfile.v2 | 1 + ...tional_test_sfinae_friendly_value_ctor.cpp | 38 +++++++++++++++++++ 6 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 test/optional_test_sfinae_friendly_value_ctor.cpp 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() { }