diff --git a/doc/20_reference.qbk b/doc/20_reference.qbk index fea6a37..32f58dd 100644 --- a/doc/20_reference.qbk +++ b/doc/20_reference.qbk @@ -326,7 +326,7 @@ __SPACE__ value is another reference to the same object referenced by `*rhs`; else `*this` is uninitialized. * [*Throws:] Nothing. -* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will reefer to the +* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will refer to the same object (they alias). * [*Example:] `` @@ -360,7 +360,8 @@ __SPACE__ * [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its value is move constructed from `rhs`; else `*this` is uninitialized. * [*Throws:] Whatever `T::T( T&& )` throws. -* [*Notes:] If `rhs` is initialized, `T::T( T && )` is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value`. +* [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value`. +* [*Notes:] If `rhs` is initialized, `T::T( T && )` is called. * [*Exception Safety:] Exceptions can only be thrown during `T::T( T&& );` in that case, `rhs` remains initialized and the value of `*rhs` is determined by exception safety of `T::T(T&&)`. * [*Example:] @@ -390,7 +391,7 @@ __SPACE__ value is another reference to the same object referenced by `*rhs`; else `*this` is uninitialized. * [*Throws:] Nothing. -* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will reefer to the +* [*Notes:] If `rhs` is initialized, both `*this` and `*rhs` will refer to the same object (they alias). * [*Example:] `` @@ -663,11 +664,12 @@ __SPACE__ * [*Effect:] Move-assigns another `optional` to an `optional`. * [*Postconditions:] If `rhs` is initialized, `*this` is initialized and its value is moved from `*rhs`, `rhs` remains initialized; else `*this` is uninitialized. -* [*Throws:] Whatever `T::operator( T&& )` or `T::T( T && )` throws. +* [*Throws:] Whatever `T::operator( T&& )` or `T::T( T && )` throws. +* [*Remarks:] The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`. * [*Notes:] If both `*this` and `rhs` are initially initialized, `T`'s ['move assignment operator] is used. If `*this` is initially initialized but `rhs` is uninitialized, `T`'s [destructor] is called. If `*this` is initially uninitialized -but `rhs` is initialized, `T`'s ['move constructor] is called. The expression inside `noexcept` is equivalent to `is_nothrow_move_constructible::value && is_nothrow_move_assignable::value`. +but `rhs` is initialized, `T`'s ['move constructor] is called. * [*Exception Safety:] In the event of an exception, the initialization state of `*this` is unchanged and its value unspecified as far as optional is concerned (it is up to `T`'s `operator=()`). If `*this` is initially uninitialized and @@ -932,8 +934,7 @@ __SPACE__ [: `template T optional::value_or(U && v) const& ;`] * [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `U &&` is convertible to `T`. -* [*Returns:] `bool(*this) ? **this : static_cast(std::forward(v))`. -* [*Throws:] Any exception thrown by the selected constructor of `T`. +* [*Effects:] `if (*this) return **this; else return std::forward(v);`. * [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function. On compilers without rvalue reference support the type of `v` becomes `U const&`. __SPACE__ @@ -943,8 +944,7 @@ __SPACE__ [: `template T optional::value_or(U && v) && ;`] * [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `U &&` is convertible to `T`. -* [*Returns:] `bool(*this) ? std::move(**this) : static_cast(std::forward(v))`. -* [*Throws:] Any exception thrown by the selected constructor of `T`. +* [*Effects:] `if (*this) return std::move(**this); else return std::forward(v);`. * [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is not present. __SPACE__ @@ -954,9 +954,8 @@ __SPACE__ [: `template T optional::value_or_eval(F f) const& ;`] * [*Requires:] `T` is __COPY_CONSTRUCTIBLE__ and `F` models a __SGI_GENERATOR__ whose result type is convertible to `T`. -* [*Returns:] `bool(*this) ? **this : static_cast(f())`. -* [*Throws:] Any exception thrown by the selected constructor of `T` or by `f`. -* [*Notes:] Function `f` is only evaluated if `bool(*this) == false`. On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function. +* [*Effects:] `if (*this) return **this; else return f();`. +* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is replaced with the `const`-qualified member function. * [*Example:] `` int complain_and_0() @@ -982,9 +981,8 @@ __SPACE__ [: `template T optional::value_or_eval(F f) && ;`] * [*Requires:] `T` is __MOVE_CONSTRUCTIBLE__ and `F` models a __SGI_GENERATOR__ whose result type is convertible to `T`. -* [*Returns:] `bool(*this) ? std::move(**this) : static_cast(f())`. -* [*Throws:] Any exception thrown by the selected constructor of `T` or by `f`. -* [*Notes:] Function `f` is only evaluated if `bool(*this) == false`. On compilers that do not support ref-qualifiers on member functions this overload is not present. +* [*Effects:] `if (*this) return std::move(**this); else return f();`. +* [*Notes:] On compilers that do not support ref-qualifiers on member functions this overload is not present. __SPACE__ diff --git a/doc/html/boost_optional/reference/detailed_semantics.html b/doc/html/boost_optional/reference/detailed_semantics.html index 78e75c8..e428dbf 100644 --- a/doc/html/boost_optional/reference/detailed_semantics.html +++ b/doc/html/boost_optional/reference/detailed_semantics.html @@ -352,7 +352,7 @@ Notes: If rhs is initialized, both *this and *rhs - will reefer to the same object (they alias). + will refer to the same object (they alias).
  • Example: @@ -402,12 +402,13 @@ Throws: Whatever T::T( T&& ) throws.
  • +
  • + Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value. +
  • Notes: If rhs is initialized, T::T( T && - ) is called. The expression inside - noexcept is equivalent to - is_nothrow_move_constructible<T>::value. + ) is called.
  • Exception Safety: Exceptions can only @@ -461,7 +462,7 @@ Notes: If rhs is initialized, both *this and *rhs - will reefer to the same object (they alias). + will refer to the same object (they alias).
  • Example: @@ -914,6 +915,10 @@ or T::T( T && ) throws.
  • +
  • + Remarks: The expression inside noexcept is equivalent to is_nothrow_move_constructible<T>::value && + is_nothrow_move_assignable<T>::value. +
  • Notes: If both *this and rhs are initially initialized, T's @@ -921,10 +926,7 @@ is initially initialized but rhs is uninitialized, T's [destructor] is called. If *this is initially uninitialized but rhs is initialized, T's - move constructor is called. The expression inside - noexcept is equivalent to - is_nothrow_move_constructible<T>::value - && is_nothrow_move_assignable<T>::value. + move constructor is called.
  • Exception Safety: In the event of an @@ -1455,11 +1457,8 @@ is convertible to T.
  • - Returns: bool(*this) ? **this : static_cast<T>(std::forward<U>(v)). -
  • -
  • - Throws: Any exception thrown by the - selected constructor of T. + Effects: if + (*this) return **this; else return std::forward<U>(v);.
  • Notes: On compilers that do not support @@ -1485,11 +1484,9 @@ is convertible to T.
  • - Returns: bool(*this) ? std::move(**this) : static_cast<T>(std::forward<U>(v)). -
  • -
  • - Throws: Any exception thrown by the - selected constructor of T. + Effects: if + (*this) return std::move(**this); else return + std::forward<U>(v);.
  • Notes: On compilers that do not support @@ -1509,16 +1506,11 @@ is convertible to T.
  • - Returns: bool(*this) ? **this : static_cast<T>(f()). + Effects: if + (*this) return **this; else return f();.
  • - Throws: Any exception thrown by the - selected constructor of T - or by f. -
  • -
  • - Notes: Function f - is only evaluated if bool(*this) == false. On compilers that do not support + Notes: On compilers that do not support ref-qualifiers on member functions this overload is replaced with the const-qualified member function.
  • @@ -1555,16 +1547,12 @@ whose result type is convertible to T.
  • - Returns: bool(*this) ? std::move(**this) : static_cast<T>(f()). + Effects: if + (*this) return std::move(**this); else return + f();.
  • - Throws: Any exception thrown by the - selected constructor of T - or by f. -
  • -
  • - Notes: Function f - is only evaluated if bool(*this) == false. On compilers that do not support + Notes: On compilers that do not support ref-qualifiers on member functions this overload is not present.
  • diff --git a/doc/html/index.html b/doc/html/index.html index b1c713c..0380423 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -133,7 +133,7 @@ - +

    Last revised: June 18, 2014 at 14:36:35 GMT

    Last revised: June 20, 2014 at 09:06:52 GMT


    diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp index 8e3a5dd..5d08606 100644 --- a/include/boost/optional/optional.hpp +++ b/include/boost/optional/optional.hpp @@ -112,28 +112,6 @@ class typed_in_place_factory_base ; template void swap ( optional& x, optional& y ); namespace optional_detail { - -// converts type U to type T using only implicit conversions/constructors -#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - template - TT convert(UU && u) - { - return forward(u); - } -#else - template - TT convert(const UU& u) - { - return u; - } - - template - TT convert(UU& u) - { - return u; - } -#endif - // This local class is used instead of that in "aligned_storage.hpp" // because I've found the 'official' class to ICE BCB5.5 // when some types are used with optional<> @@ -1082,25 +1060,37 @@ class optional : public optional_detail::optional_base template value_type value_or ( U&& v ) const& { - return this->is_initialized() ? get() : optional_detail::convert(boost::forward(v)); + if (this->is_initialized()) + return get(); + else + return boost::forward(v); } template value_type value_or ( U&& v ) && { - return this->is_initialized() ? boost::move(get()) : optional_detail::convert(boost::forward(v)); + if (this->is_initialized()) + return boost::move(get()); + else + return boost::forward(v); } #elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES template value_type value_or ( U&& v ) const - { - return this->is_initialized() ? get() : optional_detail::convert(boost::forward(v)); + { + if (this->is_initialized()) + return get(); + else + return boost::forward(v); } #else template value_type value_or ( U const& v ) const { - return this->is_initialized() ? get() : optional_detail::convert(v); + if (this->is_initialized()) + return get(); + else + return v; } #endif @@ -1109,19 +1099,28 @@ class optional : public optional_detail::optional_base template value_type value_or_eval ( F f ) const& { - return this->is_initialized() ? get() : optional_detail::convert(f()); + if (this->is_initialized()) + return get(); + else + return f(); } template value_type value_or_eval ( F f ) && { - return this->is_initialized() ? boost::move(get()) : optional_detail::convert(f()); + if (this->is_initialized()) + return boost::move(get()); + else + return f(); } #else template value_type value_or_eval ( F f ) const { - return this->is_initialized() ? get() : optional_detail::convert(f()); + if (this->is_initialized()) + return get(); + else + return f(); } #endif diff --git a/test/optional_test_value_access.cpp b/test/optional_test_value_access.cpp index bc4ed4a..c83326a 100644 --- a/test/optional_test_value_access.cpp +++ b/test/optional_test_value_access.cpp @@ -149,7 +149,7 @@ int throw_() throw int(); } -void test_function_value_or_call() +void test_function_value_or_eval() { optional o1 = 1; optional oN; @@ -237,7 +237,7 @@ int test_main( int, char* [] ) { test_function_value(); test_function_value_or(); - test_function_value_or_call(); + test_function_value_or_eval(); } catch ( ... ) {