optional: Use __and_<> and __not_<> in conditions.

2013-11-05  Jonathan Wakely  <jwakely.gcc@gmail.com>
	    Paolo Carlini  <paolo.carlini@oracle.com>

	* include/experimental/optional: Use __and_<> and __not_<> in
	conditions. Style fixes.
	(__constexpr_addressof, swap): Make inline.
	* testsuite/experimental/optional/cons/copy.cc: Adjust constants for
	32-bit targets.
	* testsuite/experimental/optional/cons/move.cc: Likewise.
	* testsuite/experimental/optional/cons/value.cc: Likewise.
	* testsuite/experimental/optional/constexpr/cons/value.cc: Likewise.

Co-Authored-By: Paolo Carlini <paolo.carlini@oracle.com>

From-SVN: r204402
This commit is contained in:
Jonathan Wakely 2013-11-05 15:24:08 +00:00 committed by Jonathan Wakely
parent 33b5d6da2a
commit b1705a6388
6 changed files with 138 additions and 129 deletions

View File

@ -1,3 +1,15 @@
2013-11-05 Jonathan Wakely <jwakely.gcc@gmail.com>
Paolo Carlini <paolo.carlini@oracle.com>
* include/experimental/optional: Use __and_<> and __not_<> in
conditions. Style fixes.
(__constexpr_addressof, swap): Make inline.
* testsuite/experimental/optional/cons/copy.cc: Adjust constants for
32-bit targets.
* testsuite/experimental/optional/cons/move.cc: Likewise.
* testsuite/experimental/optional/cons/value.cc: Likewise.
* testsuite/experimental/optional/constexpr/cons/value.cc: Likewise.
2013-11-01 Michael Brune <lucdanton@free.fr>
* include/bits/enable_special_members.h: New.

View File

@ -129,7 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
struct _Has_addressof_impl<_Tp,
decltype( std::declval<const _Tp&>().operator&(), void() )>
: std::true_type { };
: std::true_type { };
/**
* @brief Trait that detects the presence of an overloaded unary operator&.
@ -157,7 +157,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
template<typename _Tp, typename enable_if<_Has_addressof<_Tp>::value,
int>::type...>
_Tp* __constexpr_addressof(_Tp& __t)
inline _Tp* __constexpr_addressof(_Tp& __t)
{ return std::__addressof(__t); }
/**
@ -235,32 +235,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = __other._M_get();
else
{
if (__other._M_engaged)
this->_M_construct(__other._M_get());
else
this->_M_reset();
}
{
if (__other._M_engaged)
this->_M_construct(__other._M_get());
else
this->_M_reset();
}
return *this;
}
_Optional_base&
operator=(_Optional_base&& __other)
noexcept(is_nothrow_move_constructible<_Tp>()
&& is_nothrow_move_assignable<_Tp>())
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>())
{
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = std::move(__other._M_get());
else
{
if (__other._M_engaged)
this->_M_construct(std::move(__other._M_get()));
else
this->_M_reset();
}
return *this;
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = std::move(__other._M_get());
else
{
if (__other._M_engaged)
this->_M_construct(std::move(__other._M_get()));
else
this->_M_reset();
}
return *this;
}
// [X.Y.4.2] Destructor.
@ -373,35 +372,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Optional_base&
operator=(const _Optional_base& __other)
{
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = __other._M_get();
else
{
if (__other._M_engaged)
this->_M_construct(__other._M_get());
else
this->_M_reset();
}
return *this;
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = __other._M_get();
else
{
if (__other._M_engaged)
this->_M_construct(__other._M_get());
else
this->_M_reset();
}
return *this;
}
_Optional_base&
operator=(_Optional_base&& __other)
noexcept(is_nothrow_move_constructible<_Tp>()
&& is_nothrow_move_assignable<_Tp>())
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
is_nothrow_move_assignable<_Tp>>())
{
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = std::move(__other._M_get());
else
{
if (__other._M_engaged)
this->_M_construct(std::move(__other._M_get()));
else
this->_M_reset();
}
return *this;
if (this->_M_engaged && __other._M_engaged)
this->_M_get() = std::move(__other._M_get());
else
{
if (__other._M_engaged)
this->_M_construct(std::move(__other._M_get()));
else
this->_M_reset();
}
return *this;
}
// Sole difference
@ -445,9 +442,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
struct _Empty_byte { };
union {
_Empty_byte _M_empty;
_Stored_type _M_payload;
union
{
_Empty_byte _M_empty;
_Stored_type _M_payload;
};
bool _M_engaged = false;
};
@ -462,22 +460,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Copy constructor.
is_copy_constructible<_Tp>::value,
// Copy assignment.
is_copy_constructible<_Tp>::value
&& is_copy_assignable<_Tp>::value,
__and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
// Move constructor.
is_move_constructible<_Tp>::value,
// Move assignment.
is_move_constructible<_Tp>::value
&& is_move_assignable<_Tp>::value,
__and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
// Unique tag type.
optional<_Tp>>
{
static_assert(!is_same<typename remove_cv<_Tp>::type,
nullopt_t>()
&& !is_same<typename remove_cv<_Tp>::type,
in_place_t>()
&& !is_reference<_Tp>(),
"Invalid instantiation of optional<T>.");
static_assert(__and_<__not_<is_same<typename remove_cv<_Tp>::type,
nullopt_t>>,
__not_<is_same<typename remove_cv<_Tp>::type,
in_place_t>>,
__not_<is_reference<_Tp>>>(),
"Invalid instantiation of optional<T>");
private:
using _Base = _Optional_base<_Tp>;
@ -503,9 +499,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>::type
operator=(_Up&& __u)
{
static_assert(is_constructible<_Tp, _Up>()
&& is_assignable<_Tp&, _Up>(),
"Cannot assign to value type from argument.");
static_assert(__and_<is_constructible<_Tp, _Up>,
is_assignable<_Tp&, _Up>>(),
"Cannot assign to value type from argument");
if (this->_M_is_engaged())
this->_M_get() = std::forward<_Up>(__u);
@ -520,7 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
emplace(_Args&&... __args)
{
static_assert(is_constructible<_Tp, _Args&&...>(),
"Cannot emplace value type from arguments.");
"Cannot emplace value type from arguments");
this->_M_reset();
this->_M_construct(std::forward<_Args>(__args)...);
@ -551,15 +547,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this->_M_is_engaged() && __other._M_is_engaged())
swap(this->_M_get(), __other._M_get());
else if (this->_M_is_engaged())
{
__other._M_construct(std::move(this->_M_get()));
this->_M_destruct();
}
{
__other._M_construct(std::move(this->_M_get()));
this->_M_destruct();
}
else if (__other._M_is_engaged())
{
this->_M_construct(std::move(__other._M_get()));
__other._M_destruct();
}
{
this->_M_construct(std::move(__other._M_get()));
__other._M_destruct();
}
}
// [X.Y.4.5] Observers.
@ -585,11 +581,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const _Tp&
value() const
{
return this->_M_is_engaged() ?
this->_M_get() :
(__throw_bad_optional_access("Attempt to access value of a disengaged"
" optional object."),
this->_M_get());
return this->_M_is_engaged()
? this->_M_get()
: (__throw_bad_optional_access("Attempt to access value of a "
"disengaged optional object"),
this->_M_get());
}
_Tp&
@ -598,34 +594,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this->_M_is_engaged())
return this->_M_get();
__throw_bad_optional_access("Attempt to access value of a disengaged"
" optional object.");
__throw_bad_optional_access("Attempt to access value of a "
"disengaged optional object");
}
template<typename _Up>
constexpr _Tp
value_or(_Up&& __u) const&
{
static_assert(is_copy_constructible<_Tp>()
&& is_convertible<_Up&&, _Tp>(),
"Cannot return value.");
static_assert(__and_<is_copy_constructible<_Tp>,
is_convertible<_Up&&, _Tp>>(),
"Cannot return value");
return this->_M_is_engaged() ?
this->_M_get() :
static_cast<_Tp>(std::forward<_Up>(__u));
return this->_M_is_engaged()
? this->_M_get()
: static_cast<_Tp>(std::forward<_Up>(__u));
}
template<typename _Up>
_Tp
value_or(_Up&& __u) &&
{
static_assert( is_move_constructible<_Tp>()
&& is_convertible<_Up&&, _Tp>(),
"Cannot return value." );
static_assert(__and_<is_move_constructible<_Tp>,
is_convertible<_Up&&, _Tp>>(),
"Cannot return value" );
return this->_M_is_engaged() ?
std::move(this->_M_get()) :
static_cast<_Tp>(std::forward<_Up>(__u));
return this->_M_is_engaged()
? std::move(this->_M_get())
: static_cast<_Tp>(std::forward<_Up>(__u));
}
};
@ -635,7 +631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
{
return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
&& (!__lhs || *__lhs == *__rhs);
&& (!__lhs || *__lhs == *__rhs);
}
template<typename _Tp>
@ -647,8 +643,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr bool
operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
{
return static_cast<bool>(__rhs)
&& (!__lhs || *__lhs < *__rhs);
return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
}
template<typename _Tp>
@ -790,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [X.Y.11]
template<typename _Tp>
void
inline void
swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
noexcept(noexcept(__lhs.swap(__rhs)))
{ __lhs.swap(__rhs); }

View File

@ -63,11 +63,12 @@ int main()
}
{
std::experimental::optional<long> o { std::experimental::in_place, 0x1234ABCDF1E2D3C4 };
const long val = 0x1234ABCD;
std::experimental::optional<long> o { std::experimental::in_place, val};
auto copy = o;
VERIFY( copy );
VERIFY( *copy == 0x1234ABCDF1E2D3C4 );
VERIFY( o && o == 0x1234ABCDF1E2D3C4 );
VERIFY( *copy == val );
VERIFY( o && o == val );
}
{

View File

@ -63,11 +63,12 @@ int main()
}
{
std::experimental::optional<long> o { std::experimental::in_place, 0x1234ABCDF1E2D3C4 };
const long val = 0x1234ABCD;
std::experimental::optional<long> o { std::experimental::in_place, val};
auto moved_to = std::move(o);
VERIFY( moved_to );
VERIFY( *moved_to == 0x1234ABCDF1E2D3C4 );
VERIFY( o && *o == 0x1234ABCDF1E2D3C4 );
VERIFY( *moved_to == val );
VERIFY( o && *o == val );
}
{

View File

@ -66,51 +66,51 @@ int main()
// [20.5.4.1] Constructors
{
auto i = 0x1234ABCDF1E2D3C4;
auto i = 0x1234ABCD;
std::experimental::optional<long> o { i };
VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 );
VERIFY( i == 0x1234ABCDF1E2D3C4 );
VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCD );
}
{
auto i = 0x1234ABCDF1E2D3C4;
auto i = 0x1234ABCD;
std::experimental::optional<long> o = i;
VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 );
VERIFY( i == 0x1234ABCDF1E2D3C4 );
VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCD );
}
{
auto i = 0x1234ABCDF1E2D3C4;
auto i = 0x1234ABCD;
std::experimental::optional<long> o = { i };
VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 );
VERIFY( i == 0x1234ABCDF1E2D3C4 );
VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCD );
}
{
auto i = 0x1234ABCDF1E2D3C4;
auto i = 0x1234ABCD;
std::experimental::optional<long> o { std::move(i) };
VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 );
VERIFY( i == 0x1234ABCDF1E2D3C4 );
VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCD );
}
{
auto i = 0x1234ABCDF1E2D3C4;
auto i = 0x1234ABCD;
std::experimental::optional<long> o = std::move(i);
VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 );
VERIFY( i == 0x1234ABCDF1E2D3C4 );
VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCD );
}
{
auto i = 0x1234ABCDF1E2D3C4;
auto i = 0x1234ABCD;
std::experimental::optional<long> o = { std::move(i) };
VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 );
VERIFY( i == 0x1234ABCDF1E2D3C4 );
VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCD );
}
{

View File

@ -26,44 +26,44 @@ int main()
// [20.5.4.1] Constructors
{
constexpr auto i = 0x1234ABCDF1E2D3C4;
constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o { i };
static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
static_assert( *o == 0x1234ABCD, "" );
}
{
constexpr auto i = 0x1234ABCDF1E2D3C4;
constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o = i;
static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
static_assert( *o == 0x1234ABCD, "" );
}
{
constexpr auto i = 0x1234ABCDF1E2D3C4;
constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o = { i };
static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
static_assert( *o == 0x1234ABCD, "" );
}
{
constexpr auto i = 0x1234ABCDF1E2D3C4;
constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o { std::move(i) };
static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
static_assert( *o == 0x1234ABCD, "" );
}
{
constexpr auto i = 0x1234ABCDF1E2D3C4;
constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o = std::move(i);
static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
static_assert( *o == 0x1234ABCD, "" );
}
{
constexpr auto i = 0x1234ABCDF1E2D3C4;
constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o = { std::move(i) };
static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" );
static_assert( *o == 0x1234ABCD, "" );
}
}