diff --git a/doc/00_optional.qbk b/doc/00_optional.qbk index fb5d584..6b41c88 100644 --- a/doc/00_optional.qbk +++ b/doc/00_optional.qbk @@ -26,8 +26,8 @@ Distributed under the Boost Software License, Version 1.0. [def __BOOST_TUPLE__ [@../../../tuple/index.html Boost.Tuple]] [def __BOOST_TRIBOOL__ [@../../../../doc/html/tribool.html boost::tribool]] -[def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html OptionalPointee]] -[def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html Copy Constructible]] +[def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html `OptionalPointee`]] +[def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html `CopyConstructible`]] [def __FUNCTION_EQUAL_POINTEES__ [@../../../utility/OptionalPointee.html#equal `equal_pointees()`]] [def __FUNCTION_LESS_POINTEES__ [@../../../utility/OptionalPointee.html#less `less_pointees()`]] diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk index 691f475..bac369a 100644 --- a/doc/20_reference.qbk +++ b/doc/20_reference.qbk @@ -908,7 +908,7 @@ __SPACE__ [: `template T optional::value_or(U && v) const& ;`] [: `template T optional::value_or(U && v) && ;`] -* [*Requires:] `T` is CopyConstructible. +* [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `U &&` is convertible to `T`. * [*Returns:] First overload: `bool(*this) ? **this : static_cast(forward(v))`. second overload: `bool(*this) ? std::move(**this) : static_cast(forward(v))`. * [*Throws:] Any exception thrown by the selected constructor of `T`. * [*Notes:] On compilers that do not support ref-qualifiers on member functions these three overloads are replaced with the classical two: a `const` and non-`const` member functions. On compilers without rvalue reference support the type of `v` becomes `U const&`. diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html index 05ad5da..21aebff 100644 --- a/doc/html/boost_optional/reference/detailed_semantics.html +++ b/doc/html/boost_optional/reference/detailed_semantics.html @@ -1408,7 +1408,8 @@
  • Requires: T - is CopyConstructible. + is CopyConstructible and U && + is convertible to T.
  • Returns: First overload: bool(*this) ? **this diff --git a/doc/html/boost_optional/tutorial/design_overview/the_interface.html b/doc/html/boost_optional/tutorial/design_overview/the_interface.html index 8fa2707..984ae4b 100644 --- a/doc/html/boost_optional/tutorial/design_overview/the_interface.html +++ b/doc/html/boost_optional/tutorial/design_overview/the_interface.html @@ -98,10 +98,11 @@

    Such a de facto idiom for referring to optional objects - can be formalized in the form of a concept: the OptionalPointee - concept. This concept captures the syntactic usage of operators *, -> - and contextual conversion to bool - to convey the notion of optionality. + can be formalized in the form of a concept: the OptionalPointee concept. This + concept captures the syntactic usage of operators *, + -> and contextual conversion + to bool to convey the notion + of optionality.

    However, pointers are good to refer @@ -127,7 +128,7 @@ this semantics, so are inappropriate for the initialization and transport of optional values, yet are quite convenient for handling the access to the possible undefined value because of the idiomatic aid present in the - OptionalPointee + OptionalPointee concept incarnated by pointers.

    diff --git a/doc/html/boost_optional/tutorial/in_place_factories.html b/doc/html/boost_optional/tutorial/in_place_factories.html index 3c26b05..d6907b9 100644 --- a/doc/html/boost_optional/tutorial/in_place_factories.html +++ b/doc/html/boost_optional/tutorial/in_place_factories.html @@ -31,9 +31,9 @@ One of the typical problems with wrappers and containers is that their interfaces usually provide an operation to initialize or assign the contained object as a copy of some other object. This not only requires the underlying type - to be Copy Constructible, - but also requires the existence of a fully constructed object, often temporary, - just to follow the copy from: + to be CopyConstructible, but also requires + the existence of a fully constructed object, often temporary, just to follow + the copy from:

    struct X
     {
    diff --git a/doc/html/index.html b/doc/html/index.html
    index 74b30e5..4495d9b 100644
    --- a/doc/html/index.html
    +++ b/doc/html/index.html
    @@ -133,7 +133,7 @@
     
- +

Last revised: June 13, 2014 at 21:36:29 GMT

Last revised: June 14, 2014 at 20:46:55 GMT


diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index d5e3394..c742570 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -1060,18 +1061,31 @@ class optional : public optional_detail::optional_base #ifndef BOOST_NO_CXX11_REF_QUALIFIERS template value_type value_or ( U&& v ) const& - { return this->is_initialized() ? get() : static_cast(boost::forward(v)); } + { + BOOST_STATIC_ASSERT(is_convertible::value); + return this->is_initialized() ? get() : static_cast(boost::forward(v)); + } template value_type value_or ( U&& v ) && - { return this->is_initialized() ? boost::move(get()) : static_cast(boost::forward(v)); } + { + BOOST_STATIC_ASSERT(is_convertible::value); + return this->is_initialized() ? boost::move(get()) : static_cast(boost::forward(v)); + } #elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES template value_type value_or ( U&& v ) const - { return this->is_initialized() ? get() : static_cast(boost::forward(v)); } + { + BOOST_STATIC_ASSERT(is_convertible::value); + return this->is_initialized() ? get() : static_cast(boost::forward(v)); + } #else template - value_type value_or ( U const& v ) const { return this->is_initialized() ? get() : static_cast(v); } + value_type value_or ( U const& v ) const + { + BOOST_STATIC_ASSERT(is_convertible::value); + return this->is_initialized() ? get() : static_cast(v); + } #endif bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 9d5e856..04c6cd4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -41,5 +41,6 @@ import testing ; [ compile-fail optional_test_ref_fail_init_from_Urefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Trefref.cpp ] [ compile-fail optional_test_ref_fail_assign_from_Urefref.cpp ] + [ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ] ; } diff --git a/test/optional_test_fail_explicit_convert_in_value_or.cpp b/test/optional_test_fail_explicit_convert_in_value_or.cpp new file mode 100644 index 0000000..7b6f29c --- /dev/null +++ b/test/optional_test_fail_explicit_convert_in_value_or.cpp @@ -0,0 +1,32 @@ +// 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.hpp" + +// +// THIS TEST SHOULD FAIL TO COMPILE +// + +struct U +{}; + +struct T +{ + explicit T(U const&) {} +}; + + +void test_implicit_conversion_to_bool() +{ + boost::optional opt; + opt.value_or(U()); +} +