diff --git a/doc/html/boost_optional/detailed_semantics.html b/doc/html/boost_optional/detailed_semantics.html index dbfe0cb..8495d41 100644 --- a/doc/html/boost_optional/detailed_semantics.html +++ b/doc/html/boost_optional/detailed_semantics.html @@ -1235,6 +1235,30 @@ asert ( true ); } + space + + +

+ template<class U> T optional<T>::value_or(U && + v) const ; +

+

@@ -1264,6 +1288,9 @@ o, T& default ) ;

- +

Last revised: May 22, 2014 at 21:28:38 GMT

Last revised: May 23, 2014 at 14:35:08 GMT


diff --git a/doc/reference.qbk b/doc/reference.qbk index 80c6927..cd2e354 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -66,9 +66,6 @@ T const& get() const ; ``[link reference_optional_get __GO_TO__]`` T& get() ; ``[link reference_optional_get __GO_TO__]`` - // [new in 1.34] - T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]`` - T const* operator ->() const ; ``[link reference_optional_operator_arrow __GO_TO__]`` T* operator ->() ; ``[link reference_optional_operator_arrow __GO_TO__]`` @@ -77,6 +74,8 @@ T const& value() const ; ``[link reference_optional_value __GO_TO__]`` T& value() ; ``[link reference_optional_value __GO_TO__]`` + + template T value_or( U && v ) const ; ``[link reference_optional_value_or __GO_TO__]`` T const* get_ptr() const ; ``[link reference_optional_get_ptr __GO_TO__]`` T* get_ptr() ; ``[link reference_optional_get_ptr __GO_TO__]`` @@ -96,6 +95,8 @@ // (deprecated) bool is_initialized() const ; ``[link reference_optional_is_initialized __GO_TO__]`` + // (deprecated) + T const& get_value_or( T const& default ) const ; ``[link reference_optional_get_value_or_value __GO_TO__]`` }; template inline bool operator == ( optional const& x, optional const& y ) ; ``[link reference_operator_compare_equal_optional_optional __GO_TO__]`` @@ -114,13 +115,10 @@ template inline bool operator != ( optional const& x, none_t ) noexcept ; ``[link reference_operator_compare_not_equal_optional_none __GO_TO__]`` - // [new in 1.34] template inline optional make_optional ( T const& v ) ; ``[link reference_make_optional_value __GO_TO__]`` - // [new in 1.34] template inline optional make_optional ( bool condition, T const& v ) ; ``[link reference_make_optional_bool_value __GO_TO__]`` - // [new in 1.34] template inline T const& get_optional_value_or ( optional const& opt, T const& default ) ; ``[link reference_optional_get_value_or_value __GO_TO__]`` template inline T const& get ( optional const& opt ) ; ``[link reference_optional_get __GO_TO__]`` @@ -828,6 +826,17 @@ catch(bad_optional_access&) { asert ( true ); } `` +__SPACE__ + + +[#reference_optional_value_or] + +[: `template T optional::value_or(U && v) const ;`] + +* [*Requires:] `T` is CopyConstructible. +* [*Returns:] `bool(*this) ? **this : static_cast(forward(v))`. +* [*Throws:] Any exception thrown by the selected constructor of `T`. +* [*Notes:] On compilers without rvalue reference support the type of `v` becomes `U const&`. __SPACE__ @@ -839,6 +848,7 @@ __SPACE__ [: `inline T const& get_optional_value_or ( optional const& o, T const& default ) ;`] [: `inline T& get_optional_value_or ( optional& o, T& default ) ;`] +* [*Deprecated:] Use `value_or()` instead. * [*Returns:] A reference to the contained value, if any, or `default`. * [*Throws:] Nothing. * [*Example:] diff --git a/include/boost/bad_optional_access.hpp b/include/boost/optional/bad_optional_access.hpp similarity index 100% rename from include/boost/bad_optional_access.hpp rename to include/boost/optional/bad_optional_access.hpp diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index b6ca7e9..5a9cc46 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include @@ -441,11 +441,11 @@ class optional_base : public optional_tag public : - // Destroys the current value, if any, leaving this UNINITIALIZED + // **DEPPRECATED** Destroys the current value, if any, leaving this UNINITIALIZED // No-throw (assuming T::~T() doesn't) void reset() BOOST_NOEXCEPT { destroy(); } - // Replaces the current value -if any- with 'val' + // **DEPPRECATED** Replaces the current value -if any- with 'val' void reset ( argument_type val ) { assign(val); } // Returns a pointer to the value if this is initialized, otherwise, @@ -954,6 +954,14 @@ class optional : public optional_detail::optional_base throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object.")); } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + template + value_type value_or ( U&& v ) const { 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); } +#endif + bool operator!() const BOOST_NOEXCEPT { return !this->is_initialized() ; } BOOST_EXPLICIT_OPERATOR_BOOL() diff --git a/test/optional_test_value_access.cpp b/test/optional_test_value_access.cpp index 5cff1b7..73dc3fd 100644 --- a/test/optional_test_value_access.cpp +++ b/test/optional_test_value_access.cpp @@ -40,6 +40,20 @@ struct IntWrapper bool operator==(IntWrapper const& rhs) const { return _i == rhs._i; } }; +template +void test_function_value_or_for() +{ + optional oM0; + const optional oC0; + optional oM1(1); + const optional oC2(2); + + BOOST_CHECK(oM0.value_or(5) == 5); + BOOST_CHECK(oC0.value_or(5) == 5); + BOOST_CHECK(oM1.value_or(5) == 1); + BOOST_CHECK(oC2.value_or(5) == 2); +} + template void test_function_value_for() { @@ -85,16 +99,41 @@ void test_function_value_for() void test_function_value() { test_function_value_for(); - test_function_value_for(); + test_function_value_for(); test_function_value_for(); } +struct FatToIntConverter +{ + static int conversions; + int _val; + FatToIntConverter(int val) : _val(val) {} + operator int() { conversions += 1; return _val; } +}; + +int FatToIntConverter::conversions = 0; + +void test_function_value_or() +{ + test_function_value_or_for(); + test_function_value_or_for(); + test_function_value_or_for(); + + optional oi(1); + BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 1); + BOOST_CHECK(FatToIntConverter::conversions == 0); + + oi = boost::none; + BOOST_CHECK(oi.value_or(FatToIntConverter(2)) == 2); + BOOST_CHECK(FatToIntConverter::conversions == 1); +} + int test_main( int, char* [] ) { try { test_function_value(); - + test_function_value_or(); } catch ( ... ) {