mirror of
https://github.com/boostorg/optional.git
synced 2025-07-23 17:17:17 +02:00
Added 'raw' move semantics; no unit-tests
This commit is contained in:
@ -131,6 +131,9 @@ 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
|
||||||
|
typedef T && rval_reference_type ;
|
||||||
|
#endif
|
||||||
typedef T const* pointer_const_type ;
|
typedef T const* pointer_const_type ;
|
||||||
typedef T * pointer_type ;
|
typedef T * pointer_type ;
|
||||||
typedef T const& argument_type ;
|
typedef T const& argument_type ;
|
||||||
@ -140,11 +143,14 @@ struct types_when_is_ref
|
|||||||
{
|
{
|
||||||
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
|
typedef BOOST_DEDUCED_TYPENAME remove_reference<T>::type raw_type ;
|
||||||
|
|
||||||
typedef raw_type& reference_const_type ;
|
typedef raw_type& reference_const_type ;
|
||||||
typedef raw_type& reference_type ;
|
typedef raw_type& reference_type ;
|
||||||
typedef raw_type* pointer_const_type ;
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
typedef raw_type* pointer_type ;
|
typedef raw_type&& rval_reference_type ;
|
||||||
typedef raw_type& argument_type ;
|
#endif
|
||||||
|
typedef raw_type* pointer_const_type ;
|
||||||
|
typedef raw_type* pointer_type ;
|
||||||
|
typedef raw_type& argument_type ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
struct optional_tag {} ;
|
struct optional_tag {} ;
|
||||||
@ -184,6 +190,9 @@ class optional_base : public optional_tag
|
|||||||
|
|
||||||
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
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME types::rval_reference_type rval_reference_type ;
|
||||||
|
#endif
|
||||||
typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
|
typedef BOOST_DEDUCED_TYPENAME types::pointer_type pointer_type ;
|
||||||
typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
|
typedef BOOST_DEDUCED_TYPENAME types::pointer_const_type pointer_const_type ;
|
||||||
typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
|
typedef BOOST_DEDUCED_TYPENAME types::argument_type argument_type ;
|
||||||
@ -209,6 +218,17 @@ class optional_base : public optional_tag
|
|||||||
construct(val);
|
construct(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// move-construct an optional<T> initialized from an rvalue-ref to 'val'.
|
||||||
|
// Can throw if T::T(T&&) does
|
||||||
|
optional_base ( rval_reference_type val )
|
||||||
|
:
|
||||||
|
m_initialized(false)
|
||||||
|
{
|
||||||
|
construct( static_cast<T&&>(val) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
|
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialzed optional<T>.
|
||||||
// Can throw if T::T(T const&) does
|
// Can throw if T::T(T const&) does
|
||||||
optional_base ( bool cond, argument_type val )
|
optional_base ( bool cond, argument_type val )
|
||||||
@ -229,6 +249,17 @@ class optional_base : public optional_tag
|
|||||||
construct(rhs.get_impl());
|
construct(rhs.get_impl());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// Creates a deep move of another optional<T>
|
||||||
|
// Can throw if T::T(T&&) does
|
||||||
|
optional_base ( optional_base&& rhs )
|
||||||
|
:
|
||||||
|
m_initialized(false)
|
||||||
|
{
|
||||||
|
if ( rhs.is_initialized() )
|
||||||
|
construct( static_cast<T&&>(rhs.get_impl()) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// This is used for both converting and in-place constructions.
|
// This is used for both converting and in-place constructions.
|
||||||
// Derived classes use the 'tag' to select the appropriate
|
// Derived classes use the 'tag' to select the appropriate
|
||||||
@ -279,6 +310,26 @@ class optional_base : public optional_tag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// move-assigns from another _convertible_ optional<U> (deep-moves from the rhs value)
|
||||||
|
template<class U>
|
||||||
|
void assign ( optional<U>&& rhs )
|
||||||
|
{
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type ref_type;
|
||||||
|
if (is_initialized())
|
||||||
|
{
|
||||||
|
if ( rhs.is_initialized() )
|
||||||
|
assign_value(static_cast<ref_type>(rhs.get()), is_reference_predicate() );
|
||||||
|
else destroy();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ( rhs.is_initialized() )
|
||||||
|
construct(static_cast<ref_type>(rhs.get()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Assigns from a T (deep-copies the rhs value)
|
// Assigns from a T (deep-copies the rhs value)
|
||||||
void assign ( argument_type val )
|
void assign ( argument_type val )
|
||||||
{
|
{
|
||||||
@ -286,6 +337,16 @@ class optional_base : public optional_tag
|
|||||||
assign_value(val, is_reference_predicate() );
|
assign_value(val, is_reference_predicate() );
|
||||||
else construct(val);
|
else construct(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// Assigns from a T (deep-moves the rhs value)
|
||||||
|
void assign ( rval_reference_type val )
|
||||||
|
{
|
||||||
|
if (is_initialized())
|
||||||
|
assign_value( static_cast<rval_reference_type>(val), is_reference_predicate() );
|
||||||
|
else construct( static_cast<rval_reference_type>(val) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
|
// Assigns from "none", destroying the current value, if any, leaving this UNINITIALIZED
|
||||||
// No-throw (assuming T::~T() doesn't)
|
// No-throw (assuming T::~T() doesn't)
|
||||||
@ -325,6 +386,14 @@ class optional_base : public optional_tag
|
|||||||
new (m_storage.address()) internal_type(val) ;
|
new (m_storage.address()) internal_type(val) ;
|
||||||
m_initialized = true ;
|
m_initialized = true ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
void construct ( rval_reference_type val )
|
||||||
|
{
|
||||||
|
new (m_storage.address()) internal_type( static_cast<rval_reference_type>(val) ) ;
|
||||||
|
m_initialized = true ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||||
// Constructs in-place using the given factory
|
// Constructs in-place using the given factory
|
||||||
@ -411,6 +480,10 @@ 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
|
||||||
|
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) ); }
|
||||||
|
#endif
|
||||||
|
|
||||||
void destroy()
|
void destroy()
|
||||||
{
|
{
|
||||||
@ -488,22 +561,34 @@ 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
|
||||||
|
typedef BOOST_DEDUCED_TYPENAME base::rval_reference_type rval_reference_type ;
|
||||||
|
#endif
|
||||||
typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
|
typedef BOOST_DEDUCED_TYPENAME base::pointer_type pointer_type ;
|
||||||
typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
|
typedef BOOST_DEDUCED_TYPENAME base::pointer_const_type pointer_const_type ;
|
||||||
typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
|
typedef BOOST_DEDUCED_TYPENAME base::argument_type argument_type ;
|
||||||
|
|
||||||
// Creates an optional<T> uninitialized.
|
// Creates an optional<T> uninitialized.
|
||||||
// No-throw
|
// No-throw
|
||||||
optional() : base() {}
|
optional() BOOST_NOEXCEPT : base() {}
|
||||||
|
|
||||||
// Creates an optional<T> uninitialized.
|
// Creates an optional<T> uninitialized.
|
||||||
// No-throw
|
// No-throw
|
||||||
optional( none_t none_ ) : base(none_) {}
|
optional( none_t none_ ) BOOST_NOEXCEPT : base(none_) {}
|
||||||
|
|
||||||
// Creates an optional<T> initialized with 'val'.
|
// Creates an optional<T> initialized with 'val'.
|
||||||
// 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
|
||||||
|
// Creates an optional<T> initialized with 'move(val)'.
|
||||||
|
// Can throw if T::T(T &&) does
|
||||||
|
optional ( rval_reference_type val ) BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(static_cast<T&&>(val))))
|
||||||
|
:
|
||||||
|
base( static_cast<T&&>(val) )
|
||||||
|
{}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
|
// Creates an optional<T> initialized with 'val' IFF cond is true, otherwise creates an uninitialized optional.
|
||||||
// Can throw if T::T(T const&) does
|
// Can throw if T::T(T const&) does
|
||||||
optional ( bool cond, argument_type val ) : base(cond,val) {}
|
optional ( bool cond, argument_type val ) : base(cond,val) {}
|
||||||
@ -521,6 +606,20 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
if ( rhs.is_initialized() )
|
if ( rhs.is_initialized() )
|
||||||
this->construct(rhs.get());
|
this->construct(rhs.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// Creates a deep move of another convertible optional<U>
|
||||||
|
// Requires a valid conversion from U to T.
|
||||||
|
// Can throw if T::T(U&&) does
|
||||||
|
template<class U>
|
||||||
|
explicit optional ( optional<U> && rhs )
|
||||||
|
:
|
||||||
|
base()
|
||||||
|
{
|
||||||
|
if ( rhs.is_initialized() )
|
||||||
|
this->construct( static_cast<BOOST_DEDUCED_TYPENAME optional<U>::rval_reference_type>(rhs.get()) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
#ifndef BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
|
||||||
// Creates an optional<T> with an expression which can be either
|
// Creates an optional<T> with an expression which can be either
|
||||||
@ -573,6 +672,16 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
return *this ;
|
return *this ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// Assigns from another optional<T> (deep-moves the rhs value)
|
||||||
|
optional& operator= ( optional && rhs )
|
||||||
|
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(static_cast<optional &&>(*rhs))) && BOOST_NOEXCEPT_EXPR(*rhs = static_cast<optional &&>(*rhs)))
|
||||||
|
{
|
||||||
|
this->assign( static_cast<optional &&>(rhs) ) ;
|
||||||
|
return *this ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Assigns from a T (deep-copies the rhs value)
|
// Assigns from a T (deep-copies the rhs value)
|
||||||
// Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
|
// Basic Guarantee: If T::( T const& ) throws, this is left UNINITIALIZED
|
||||||
optional& operator= ( argument_type val )
|
optional& operator= ( argument_type val )
|
||||||
@ -581,6 +690,15 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
return *this ;
|
return *this ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||||
|
// Assigns from a T (deep-moves the rhs value)
|
||||||
|
optional& operator= ( rval_reference_type val )
|
||||||
|
{
|
||||||
|
this->assign( static_cast<rval_reference_type>(val) ) ;
|
||||||
|
return *this ;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Assigns from a "none"
|
// Assigns from a "none"
|
||||||
// Which destroys the current value, if any, leaving this UNINITIALIZED
|
// Which destroys the current value, if any, leaving this UNINITIALIZED
|
||||||
// No-throw (assuming T::~T() doesn't)
|
// No-throw (assuming T::~T() doesn't)
|
||||||
@ -591,10 +709,10 @@ class optional : public optional_detail::optional_base<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void swap( optional & arg )
|
void swap( optional & arg )
|
||||||
|
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(static_cast<optional &&>(*arg))) && BOOST_NOEXCEPT_EXPR(*arg = static_cast<optional &&>(*arg)))
|
||||||
{
|
{
|
||||||
// allow for Koenig lookup
|
// allow for Koenig lookup
|
||||||
using boost::swap;
|
boost::swap(*this, arg);
|
||||||
swap(*this, arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -961,6 +1079,7 @@ template<class T>
|
|||||||
struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
|
struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
|
||||||
|
|
||||||
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
template<class T> inline void swap ( optional<T>& x, optional<T>& y )
|
||||||
|
BOOST_NOEXCEPT_IF(BOOST_NOEXCEPT_EXPR(T(static_cast<optional &&>(*x))) && BOOST_NOEXCEPT_EXPR(*y = static_cast<optional &&>(*x)))
|
||||||
{
|
{
|
||||||
optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
|
optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user