Added ref-qualifiers to some accessors

This commit is contained in:
Andrzej Krzemienski
2014-06-03 23:07:19 +02:00
parent 2e583aaf30
commit f99618f09b
3 changed files with 74 additions and 4 deletions

View File

@ -958,9 +958,40 @@ 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
reference_const_type operator *() const& { return this->get() ; }
reference_type operator *() & { return this->get() ; }
rval_reference_type operator *() && { return boost::move(this->get()) ; }
#else
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() ; }
#endif
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
reference_const_type value() const&
{
if (this->is_initialized())
return this->get() ;
else
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
}
reference_type value() &
{
if (this->is_initialized())
return this->get() ;
else
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
}
rval_reference_type value() &&
{
if (this->is_initialized())
return boost::move(this->get()) ;
else
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
}
#else
reference_const_type value() const reference_const_type value() const
{ {
if (this->is_initialized()) if (this->is_initialized())
@ -976,10 +1007,20 @@ class optional : public optional_detail::optional_base<T>
else else
throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object.")); throw_exception(bad_optional_access("Attempted to access the value of an uninitialized optional object."));
} }
#endif
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES #ifndef BOOST_NO_CXX11_REF_QUALIFIERS
template <class U> template <class U>
value_type value_or ( U&& v ) const { return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v)); } value_type value_or ( U&& v ) const&
{ return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v)); }
template <class U>
value_type value_or ( U&& v ) &&
{ return this->is_initialized() ? boost::move(get()) : static_cast<value_type>(boost::forward<U>(v)); }
#elif !defined BOOST_NO_CXX11_RVALUE_REFERENCES
template <class U>
value_type value_or ( U&& v ) const
{ return this->is_initialized() ? get() : static_cast<value_type>(boost::forward<U>(v)); }
#else #else
template <class U> template <class U>
value_type value_or ( U const& v ) const { return this->is_initialized() ? get() : static_cast<value_type>(v); } value_type value_or ( U const& v ) const { return this->is_initialized() ? get() : static_cast<value_type>(v); }

View File

@ -37,7 +37,7 @@ void assertion_failed (char const * expr, char const * func, char const * file,
using boost::optional ; using boost::optional ;
template<class T> inline void unused_variable ( T ) {} template<class T> inline void unused_variable ( const T& ) {}
#ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP #ifdef BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
using boost::swap ; using boost::swap ;

View File

@ -128,6 +128,35 @@ void test_function_value_or()
BOOST_CHECK(FatToIntConverter::conversions == 1); BOOST_CHECK(FatToIntConverter::conversions == 1);
} }
#ifndef BOOST_NO_CXX11_REF_QUALIFIERS
struct MoveOnly
{
explicit MoveOnly(int){}
MoveOnly(MoveOnly &&){}
void operator=(MoveOnly &&);
private:
MoveOnly(MoveOnly const&);
void operator=(MoveOnly const&);
};
optional<MoveOnly> makeMoveOnly()
{
return MoveOnly(1);
}
// compile-time test
void test_move_only_getters()
{
MoveOnly m1 = *makeMoveOnly();
MoveOnly m2 = makeMoveOnly().value();
MoveOnly m3 = makeMoveOnly().value_or(MoveOnly(1));
unused_variable(m1);
unused_variable(m2);
unused_variable(m3);
}
#endif
int test_main( int, char* [] ) int test_main( int, char* [] )
{ {
try try