You can now manually disable move semantics.

This may be useful in MSVC to work around a bug described in Trac #10399
This commit is contained in:
Andrzej Krzemienski
2015-01-21 15:03:17 +01:00
parent 726b227aa9
commit f229257f30
6 changed files with 90 additions and 38 deletions

View File

@ -16,6 +16,7 @@
* `boost::none_t` is no longer convertible from literal `0`. This avoids a bug where `optional<rational<int>> oi = 0;` would initialize an optional object with no contained value. * `boost::none_t` is no longer convertible from literal `0`. This avoids a bug where `optional<rational<int>> oi = 0;` would initialize an optional object with no contained value.
* Improved the trick that prevents streaming out `optional` without header `optional_io.hpp` by using safe-bool idiom. This addresses [@https://svn.boost.org/trac/boost/ticket/10825 Trac #10825] * Improved the trick that prevents streaming out `optional` without header `optional_io.hpp` by using safe-bool idiom. This addresses [@https://svn.boost.org/trac/boost/ticket/10825 Trac #10825]
* IOStream operators are now mentioned in documentation. * IOStream operators are now mentioned in documentation.
* Added a way to manually disable move semantics: just define macro `BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES`. This can be used to work around [@https://svn.boost.org/trac/boost/ticket/10399 Trac #10399]
[heading Boost Release 1.57] [heading Boost Release 1.57]

View File

@ -47,6 +47,11 @@
<li class="listitem"> <li class="listitem">
IOStream operators are now mentioned in documentation. IOStream operators are now mentioned in documentation.
</li> </li>
<li class="listitem">
Added a way to manually disable move semantics: just define macro <code class="computeroutput"><span class="identifier">BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES</span></code>.
This can be used to work around <a href="https://svn.boost.org/trac/boost/ticket/10399" target="_top">Trac
#10399</a>
</li>
</ul></div> </ul></div>
<h4> <h4>
<a name="boost_optional.relnotes.h1"></a> <a name="boost_optional.relnotes.h1"></a>

View File

@ -138,7 +138,7 @@
</div> </div>
</div> </div>
<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr> <table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision" width="100%"><tr>
<td align="left"><p><small>Last revised: January 20, 2015 at 23:06:39 GMT</small></p></td> <td align="left"><p><small>Last revised: January 21, 2015 at 13:59:23 GMT</small></p></td>
<td align="right"><div class="copyright-footer"></div></td> <td align="right"><div class="copyright-footer"></div></td>
</tr></table> </tr></table>
<hr> <hr>

View File

@ -1,5 +1,5 @@
// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal. // Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
// Copyright (C) 2014 Andrzej Krzemienski. // Copyright (C) 2014, 2015 Andrzej Krzemienski.
// //
// Use, modification, and distribution is subject to the Boost Software // Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@ -57,6 +57,10 @@
#include <boost/optional/optional_fwd.hpp> #include <boost/optional/optional_fwd.hpp>
#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES)
#define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
#endif
#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700) #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
// AFAICT only Intel 7 correctly resolves the overload set // AFAICT only Intel 7 correctly resolves the overload set
// that includes the in-place factory taking functions, // that includes the in-place factory taking functions,
@ -148,7 +152,7 @@ struct types_when_isnt_ref
{ {
typedef T const& reference_const_type ; typedef T const& reference_const_type ;
typedef T & reference_type ; typedef T & reference_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
typedef T && rval_reference_type ; typedef T && rval_reference_type ;
typedef T && reference_type_of_temporary_wrapper; typedef T && reference_type_of_temporary_wrapper;
#ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES #ifdef BOOST_MOVE_OLD_RVALUE_REF_BINDING_RULES
@ -171,7 +175,7 @@ struct types_when_is_ref
typedef raw_type& reference_const_type ; typedef raw_type& reference_const_type ;
typedef raw_type& reference_type ; typedef raw_type& reference_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
typedef BOOST_DEDUCED_TYPENAME remove_const<raw_type>::type&& rval_reference_type ; typedef BOOST_DEDUCED_TYPENAME remove_const<raw_type>::type&& rval_reference_type ;
typedef raw_type& reference_type_of_temporary_wrapper; typedef raw_type& reference_type_of_temporary_wrapper;
static reference_type move(reference_type r) { return r; } static reference_type move(reference_type r) { return r; }
@ -226,7 +230,7 @@ class optional_base : public optional_tag
protected: protected:
typedef BOOST_DEDUCED_TYPENAME types::reference_type reference_type ; 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::reference_const_type reference_const_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ; typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ; typedef BOOST_DEDUCED_TYPENAME types::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
#endif #endif
@ -255,7 +259,7 @@ class optional_base : public optional_tag
construct(val); construct(val);
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// move-construct an optional<T> initialized from an rvalue-ref to 'val'. // move-construct an optional<T> initialized from an rvalue-ref to 'val'.
// Can throw if T::T(T&&) does // Can throw if T::T(T&&) does
optional_base ( rval_reference_type val ) optional_base ( rval_reference_type val )
@ -286,7 +290,7 @@ class optional_base : public optional_tag
construct(rhs.get_impl()); construct(rhs.get_impl());
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates a deep move of another optional<T> // Creates a deep move of another optional<T>
// Can throw if T::T(T&&) does // Can throw if T::T(T&&) does
optional_base ( optional_base&& rhs ) optional_base ( optional_base&& rhs )
@ -298,7 +302,7 @@ class optional_base : public optional_tag
} }
#endif #endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template<class Expr, class PtrExpr> template<class Expr, class PtrExpr>
explicit optional_base ( Expr&& expr, PtrExpr const* tag ) explicit optional_base ( Expr&& expr, PtrExpr const* tag )
@ -342,7 +346,7 @@ class optional_base : public optional_tag
} }
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from another optional<T> (deep-moves the rhs value) // Assigns from another optional<T> (deep-moves the rhs value)
void assign ( optional_base&& rhs ) void assign ( optional_base&& rhs )
{ {
@ -377,7 +381,7 @@ class optional_base : public optional_tag
} }
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value) // move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
template<class U> template<class U>
void assign ( optional<U>&& rhs ) void assign ( optional<U>&& rhs )
@ -405,7 +409,7 @@ class optional_base : public optional_tag
else construct(val); else construct(val);
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from a T (deep-moves the rhs value) // Assigns from a T (deep-moves the rhs value)
void assign ( rval_reference_type val ) void assign ( rval_reference_type val )
{ {
@ -421,7 +425,7 @@ class optional_base : public optional_tag
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template<class Expr, class ExprPtr> template<class Expr, class ExprPtr>
void assign_expr ( Expr&& expr, ExprPtr const* tag ) void assign_expr ( Expr&& expr, ExprPtr const* tag )
{ {
@ -466,7 +470,7 @@ class optional_base : public optional_tag
m_initialized = true ; m_initialized = true ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
void construct ( rval_reference_type val ) void construct ( rval_reference_type val )
{ {
::new (m_storage.address()) internal_type( types::move(val) ) ; ::new (m_storage.address()) internal_type( types::move(val) ) ;
@ -475,7 +479,7 @@ class optional_base : public optional_tag
#endif #endif
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// Constructs in-place // Constructs in-place
// upon exception *this is always uninitialized // upon exception *this is always uninitialized
template<class... Args> template<class... Args>
@ -485,7 +489,7 @@ class optional_base : public optional_tag
::new (m_storage.address()) internal_type( boost::forward<Args>(args)... ); ::new (m_storage.address()) internal_type( boost::forward<Args>(args)... );
m_initialized = true ; m_initialized = true ;
} }
#elif (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
template<class Arg> template<class Arg>
void emplace_assign ( Arg&& arg ) void emplace_assign ( Arg&& arg )
{ {
@ -513,7 +517,7 @@ class optional_base : public optional_tag
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Constructs in-place using the given factory // Constructs in-place using the given factory
template<class Expr> template<class Expr>
void construct ( Expr&& factory, in_place_factory_base const* ) void construct ( Expr&& factory, in_place_factory_base const* )
@ -584,7 +588,7 @@ class optional_base : public optional_tag
#endif #endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Constructs using any expression implicitly convertible to the single argument // Constructs using any expression implicitly convertible to the single argument
// of a one-argument T constructor. // of a one-argument T constructor.
// Converting constructions of optional<T> from optional<U> uses this function with // Converting constructions of optional<T> from optional<U> uses this function with
@ -642,7 +646,7 @@ class optional_base : public optional_tag
// For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error // For VC<=70 compilers this workaround dosen't work becasue the comnpiler issues and error
// instead of choosing the wrong overload // instead of choosing the wrong overload
// //
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>) // Notice that 'Expr' will be optional<T> or optional<U> (but not optional_base<..>)
template<class Expr> template<class Expr>
void construct ( Expr&& expr, optional_tag const* ) void construct ( Expr&& expr, optional_tag const* )
@ -673,7 +677,7 @@ class optional_base : public optional_tag
void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; } void assign_value ( argument_type val, is_not_reference_tag ) { get_impl() = val; }
void assign_value ( argument_type val, is_reference_tag ) { construct(val); } void assign_value ( argument_type val, is_reference_tag ) { construct(val); }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast<rval_reference_type>(val); } void assign_value ( rval_reference_type val, is_not_reference_tag ) { get_impl() = static_cast<rval_reference_type>(val); }
void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast<rval_reference_type>(val) ); } void assign_value ( rval_reference_type val, is_reference_tag ) { construct( static_cast<rval_reference_type>(val) ); }
#endif #endif
@ -750,7 +754,7 @@ class optional : public optional_detail::optional_base<T>
typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ; typedef BOOST_DEDUCED_TYPENAME base::value_type value_type ;
typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_type reference_type ;
typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ; typedef BOOST_DEDUCED_TYPENAME base::reference_const_type reference_const_type ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ; typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ; typedef BOOST_DEDUCED_TYPENAME base::reference_type_of_temporary_wrapper reference_type_of_temporary_wrapper ;
#endif #endif
@ -770,7 +774,7 @@ class optional : public optional_detail::optional_base<T>
// Can throw if T::T(T const&) does // Can throw if T::T(T const&) does
optional ( argument_type val ) : base(val) {} optional ( argument_type val ) : base(val) {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates an optional<T> initialized with 'move(val)'. // Creates an optional<T> initialized with 'move(val)'.
// Can throw if T::T(T &&) does // Can throw if T::T(T &&) does
optional ( rval_reference_type val ) : base( boost::forward<T>(val) ) optional ( rval_reference_type val ) : base( boost::forward<T>(val) )
@ -795,7 +799,7 @@ class optional : public optional_detail::optional_base<T>
this->construct(rhs.get()); this->construct(rhs.get());
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates a deep move of another convertible optional<U> // Creates a deep move of another convertible optional<U>
// Requires a valid conversion from U to T. // Requires a valid conversion from U to T.
// Can throw if T::T(U&&) does // Can throw if T::T(U&&) does
@ -819,7 +823,7 @@ class optional : public optional_detail::optional_base<T>
// even though explicit overloads are present for these. // even though explicit overloads are present for these.
// Depending on the above some T ctor is called. // Depending on the above some T ctor is called.
// Can throw if the resolved T ctor throws. // Can throw if the resolved T ctor throws.
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template<class Expr> template<class Expr>
@ -834,14 +838,14 @@ class optional : public optional_detail::optional_base<T>
#else #else
template<class Expr> template<class Expr>
explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {} explicit optional ( Expr const& expr ) : base(expr,boost::addressof(expr)) {}
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
#endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT #endif // !defined BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
// Creates a deep copy of another optional<T> // Creates a deep copy of another optional<T>
// Can throw if T::T(T const&) does // Can throw if T::T(T const&) does
optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {} optional ( optional const& rhs ) : base( static_cast<base const&>(rhs) ) {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Creates a deep move of another optional<T> // Creates a deep move of another optional<T>
// Can throw if T::T(T&&) does // Can throw if T::T(T&&) does
optional ( optional && rhs ) optional ( optional && rhs )
@ -856,7 +860,7 @@ class optional : public optional_detail::optional_base<T>
#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) #if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
// Assigns from an expression. See corresponding constructor. // Assigns from an expression. See corresponding constructor.
// Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED // Basic Guarantee: If the resolved T ctor throws, this is left UNINITIALIZED
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template<class Expr> template<class Expr>
BOOST_DEDUCED_TYPENAME boost::disable_if_c< BOOST_DEDUCED_TYPENAME boost::disable_if_c<
@ -878,7 +882,7 @@ class optional : public optional_detail::optional_base<T>
this->assign_expr(expr,boost::addressof(expr)); this->assign_expr(expr,boost::addressof(expr));
return *this ; return *this ;
} }
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
#endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION) #endif // !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) && !defined(BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION)
// Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value) // Copy-assigns from another convertible optional<U> (converts && deep-copies the rhs value)
@ -891,7 +895,7 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value) // Move-assigns from another convertible optional<U> (converts && deep-moves the rhs value)
// Requires a valid conversion from U to T. // Requires a valid conversion from U to T.
// Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED // Basic Guarantee: If T::T( U && ) throws, this is left UNINITIALIZED
@ -912,7 +916,7 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from another optional<T> (deep-moves the rhs value) // Assigns from another optional<T> (deep-moves the rhs value)
optional& operator= ( optional && rhs ) optional& operator= ( optional && rhs )
BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value) BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible<T>::value && ::boost::is_nothrow_move_assignable<T>::value)
@ -930,7 +934,7 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
// Assigns from a T (deep-moves the rhs value) // Assigns from a T (deep-moves the rhs value)
optional& operator= ( rval_reference_type val ) optional& operator= ( rval_reference_type val )
{ {
@ -949,7 +953,7 @@ class optional : public optional_detail::optional_base<T>
return *this ; return *this ;
} }
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES) #if (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES) && (!defined BOOST_NO_CXX11_VARIADIC_TEMPLATES)
// Constructs in-place // Constructs in-place
// upon exception *this is always uninitialized // upon exception *this is always uninitialized
template<class... Args> template<class... Args>
@ -957,7 +961,7 @@ class optional : public optional_detail::optional_base<T>
{ {
this->emplace_assign( boost::forward<Args>(args)... ); this->emplace_assign( boost::forward<Args>(args)... );
} }
#elif (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) #elif (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
template<class Arg> template<class Arg>
void emplace ( Arg&& arg ) void emplace ( Arg&& arg )
{ {
@ -1004,7 +1008,7 @@ class optional : public optional_detail::optional_base<T>
// Returns a reference to the value if this is initialized, otherwise, // Returns a reference to the value if this is initialized, otherwise,
// the behaviour is UNDEFINED // the behaviour is UNDEFINED
// No-throw // No-throw
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
reference_const_type operator *() const& { return this->get() ; } reference_const_type operator *() const& { return this->get() ; }
reference_type operator *() & { return this->get() ; } reference_type operator *() & { return this->get() ; }
reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; } reference_type_of_temporary_wrapper operator *() && { return boost::move(this->get()) ; }
@ -1013,7 +1017,7 @@ class optional : public optional_detail::optional_base<T>
reference_type operator *() { return this->get() ; } reference_type operator *() { return this->get() ; }
#endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS #endif // !defined BOOST_NO_CXX11_REF_QUALIFIERS
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS #if (!defined BOOST_NO_CXX11_REF_QUALIFIERS) && (!defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES)
reference_const_type value() const& reference_const_type value() const&
{ {
if (this->is_initialized()) if (this->is_initialized())
@ -1075,7 +1079,7 @@ class optional : public optional_detail::optional_base<T>
else else
return boost::forward<U>(v); return boost::forward<U>(v);
} }
#elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES #elif !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template <class U> template <class U>
value_type value_or ( U&& v ) const value_type value_or ( U&& v ) const
{ {
@ -1130,7 +1134,7 @@ class optional : public optional_detail::optional_base<T>
BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT() BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
} ; } ;
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template<class T> template<class T>
class optional<T&&> class optional<T&&>
{ {
@ -1440,7 +1444,7 @@ struct swap_selector<true>
} }
}; };
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
template<> template<>
struct swap_selector<false> struct swap_selector<false>
{ {
@ -1497,7 +1501,7 @@ struct swap_selector<false>
} }
} }
}; };
#endif // !defined BOOST_NO_CXX11_RVALUE_REFERENCES #endif // !defined BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
} // namespace optional_detail } // namespace optional_detail

View File

@ -33,6 +33,7 @@ import testing ;
[ run optional_test_value_access.cpp ] [ run optional_test_value_access.cpp ]
[ run optional_test_emplace.cpp ] [ run optional_test_emplace.cpp ]
[ run optional_test_minimum_requirements.cpp ] [ run optional_test_minimum_requirements.cpp ]
[ run optional_test_msvc_bug_workaround.cpp ]
[ compile-fail optional_test_fail1.cpp ] [ compile-fail optional_test_fail1.cpp ]
[ compile-fail optional_test_fail3a.cpp ] [ compile-fail optional_test_fail3a.cpp ]
[ compile-fail optional_test_fail3b.cpp ] [ compile-fail optional_test_fail3b.cpp ]

View File

@ -0,0 +1,41 @@
// Copyright (C) 2015 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
#define BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES
#include "boost/optional/optional.hpp"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#include "boost/core/lightweight_test.hpp"
struct Wrapper
{
operator int () { return 9; }
operator boost::optional<int> () { return 7; }
};
void test()
{
#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES)
boost::optional<int> v = Wrapper();
BOOST_TEST(v);
BOOST_TEST_EQ(*v, 7);
#endif
}
int main()
{
test();
return boost::report_errors();
}