diff --git a/doc/html/boost_optional/detailed_semantics.html b/doc/html/boost_optional/detailed_semantics.html index 4ab1a29..9163af0 100644 --- a/doc/html/boost_optional/detailed_semantics.html +++ b/doc/html/boost_optional/detailed_semantics.html @@ -981,16 +981,19 @@ space

- optional<T>::operator unspecified-bool-type() const ; + explicit optional<T>::operator bool() const ;

- +

Last revised: April 11, 2014 at 13:25:26 GMT

Last revised: April 26, 2014 at 08:58:33 GMT


diff --git a/doc/reference.qbk b/doc/reference.qbk index cd0234c..d7cdfed 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -66,7 +66,7 @@ T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` - operator unspecified-bool-type() const ; ``[link reference_optional_operator_bool __GO_TO__]`` + explicit operator bool() const ; ``[link reference_optional_operator_bool __GO_TO__]`` bool operator!() const ; ``[link reference_optional_operator_not __GO_TO__]`` @@ -657,11 +657,11 @@ __SPACE__ [#reference_optional_operator_bool] -[: `optional::operator `['unspecified-bool-type]`() const ;`] +[: `explicit optional::operator bool() const ;`] -* [*Returns:] An unspecified value which if used on a boolean context -is equivalent to (`get_ptr() != 0`) +* [*Returns:] `get_ptr() != 0`. * [*Throws:] Nothing. +* [*Notes:] On compilers that do not support explicit conversion operators this falls back to safe-bool idiom. * [*Example:] `` optional def ; diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 603facd..d87b6fa 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -180,8 +181,6 @@ class optional_base : public optional_tag typedef BOOST_DEDUCED_TYPENAME mpl::if_::type types ; protected: - typedef bool (this_type::*unspecified_bool_type)() const; - typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ; typedef BOOST_DEDUCED_TYPENAME types::reference_const_type reference_const_type ; typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ; @@ -418,8 +417,6 @@ class optional_base : public optional_tag destroy_impl(is_reference_predicate()) ; } - unspecified_bool_type safe_bool() const { return m_initialized ? &this_type::is_initialized : 0 ; } - reference_const_type get_impl() const { return dereference(get_object(), is_reference_predicate() ) ; } reference_type get_impl() { return dereference(get_object(), is_reference_predicate() ) ; } @@ -479,8 +476,6 @@ class optional : public optional_detail::optional_base { typedef optional_detail::optional_base base ; - typedef BOOST_DEDUCED_TYPENAME base::unspecified_bool_type unspecified_bool_type ; - public : typedef optional this_type ; @@ -620,13 +615,9 @@ class optional : public optional_detail::optional_base reference_const_type operator *() const { return this->get() ; } reference_type operator *() { return this->get() ; } - // implicit conversion to "bool" - // No-throw - operator unspecified_bool_type() const { return this->safe_bool() ; } - - // This is provided for those compilers which don't like the conversion to bool - // on some contexts. bool operator!() const { return !this->is_initialized() ; } + + BOOST_EXPLICIT_OPERATOR_BOOL() } ; // Returns optional(v) diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 16d4f3c..290bb1b 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -29,5 +29,6 @@ import testing ; [ compile-fail optional_test_ref_fail4.cpp ] [ compile-fail optional_test_inplace_fail.cpp ] [ compile-fail optional_test_inplace_fail2.cpp ] + [ compile-fail optional_test_fail_implicit_bool_convert.cpp ] ; } diff --git a/test/optional_test.cpp b/test/optional_test.cpp index c3f9355..ba64269 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -1086,8 +1086,8 @@ namespace optional_swap_test // void swap(boost::optional & x, boost::optional & y) { - bool hasX = x; - bool hasY = y; + bool hasX(x); + bool hasY(y); if ( !hasX && !hasY ) return; diff --git a/test/optional_test_fail_implicit_bool_convert.cpp b/test/optional_test_fail_implicit_bool_convert.cpp new file mode 100644 index 0000000..5009373 --- /dev/null +++ b/test/optional_test_fail_implicit_bool_convert.cpp @@ -0,0 +1,28 @@ +// 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 +// + +#if !defined(BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS) + +bool test_implicit_conversion_to_bool() +{ + boost::optional opt; + return opt; +} + +#else +# error "Test skipped: this compiler does not support explicit conversion operators." +#endif