Commit b1705a63 by Jonathan Wakely Committed by Jonathan Wakely

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
parent 33b5d6da
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> 2013-11-01 Michael Brune <lucdanton@free.fr>
* include/bits/enable_special_members.h: New. * include/bits/enable_special_members.h: New.
......
...@@ -129,7 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -129,7 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp> template<typename _Tp>
struct _Has_addressof_impl<_Tp, struct _Has_addressof_impl<_Tp,
decltype( std::declval<const _Tp&>().operator&(), void() )> decltype( std::declval<const _Tp&>().operator&(), void() )>
: std::true_type { }; : std::true_type { };
/** /**
* @brief Trait that detects the presence of an overloaded unary operator&. * @brief Trait that detects the presence of an overloaded unary operator&.
...@@ -157,7 +157,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -157,7 +157,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/ */
template<typename _Tp, typename enable_if<_Has_addressof<_Tp>::value, template<typename _Tp, typename enable_if<_Has_addressof<_Tp>::value,
int>::type...> int>::type...>
_Tp* __constexpr_addressof(_Tp& __t) inline _Tp* __constexpr_addressof(_Tp& __t)
{ return std::__addressof(__t); } { return std::__addressof(__t); }
/** /**
...@@ -235,32 +235,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -235,32 +235,31 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this->_M_engaged && __other._M_engaged) if (this->_M_engaged && __other._M_engaged)
this->_M_get() = __other._M_get(); this->_M_get() = __other._M_get();
else else
{ {
if (__other._M_engaged) if (__other._M_engaged)
this->_M_construct(__other._M_get()); this->_M_construct(__other._M_get());
else else
this->_M_reset(); this->_M_reset();
} }
return *this; return *this;
} }
_Optional_base& _Optional_base&
operator=(_Optional_base&& __other) operator=(_Optional_base&& __other)
noexcept(is_nothrow_move_constructible<_Tp>() noexcept(__and_<is_nothrow_move_constructible<_Tp>,
&& is_nothrow_move_assignable<_Tp>()) is_nothrow_move_assignable<_Tp>>())
{ {
if (this->_M_engaged && __other._M_engaged) if (this->_M_engaged && __other._M_engaged)
this->_M_get() = std::move(__other._M_get()); this->_M_get() = std::move(__other._M_get());
else else
{ {
if (__other._M_engaged) if (__other._M_engaged)
this->_M_construct(std::move(__other._M_get())); this->_M_construct(std::move(__other._M_get()));
else else
this->_M_reset(); this->_M_reset();
} }
return *this;
return *this;
} }
// [X.Y.4.2] Destructor. // [X.Y.4.2] Destructor.
...@@ -373,35 +372,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -373,35 +372,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Optional_base& _Optional_base&
operator=(const _Optional_base& __other) operator=(const _Optional_base& __other)
{ {
if (this->_M_engaged && __other._M_engaged) if (this->_M_engaged && __other._M_engaged)
this->_M_get() = __other._M_get(); this->_M_get() = __other._M_get();
else else
{ {
if (__other._M_engaged) if (__other._M_engaged)
this->_M_construct(__other._M_get()); this->_M_construct(__other._M_get());
else else
this->_M_reset(); this->_M_reset();
} }
return *this;
return *this;
} }
_Optional_base& _Optional_base&
operator=(_Optional_base&& __other) operator=(_Optional_base&& __other)
noexcept(is_nothrow_move_constructible<_Tp>() noexcept(__and_<is_nothrow_move_constructible<_Tp>,
&& is_nothrow_move_assignable<_Tp>()) is_nothrow_move_assignable<_Tp>>())
{ {
if (this->_M_engaged && __other._M_engaged) if (this->_M_engaged && __other._M_engaged)
this->_M_get() = std::move(__other._M_get()); this->_M_get() = std::move(__other._M_get());
else else
{ {
if (__other._M_engaged) if (__other._M_engaged)
this->_M_construct(std::move(__other._M_get())); this->_M_construct(std::move(__other._M_get()));
else else
this->_M_reset(); this->_M_reset();
} }
return *this;
return *this;
} }
// Sole difference // Sole difference
...@@ -445,9 +442,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -445,9 +442,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private: private:
struct _Empty_byte { }; struct _Empty_byte { };
union { union
_Empty_byte _M_empty; {
_Stored_type _M_payload; _Empty_byte _M_empty;
_Stored_type _M_payload;
}; };
bool _M_engaged = false; bool _M_engaged = false;
}; };
...@@ -462,22 +460,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -462,22 +460,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Copy constructor. // Copy constructor.
is_copy_constructible<_Tp>::value, is_copy_constructible<_Tp>::value,
// Copy assignment. // Copy assignment.
is_copy_constructible<_Tp>::value __and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
&& is_copy_assignable<_Tp>::value,
// Move constructor. // Move constructor.
is_move_constructible<_Tp>::value, is_move_constructible<_Tp>::value,
// Move assignment. // Move assignment.
is_move_constructible<_Tp>::value __and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
&& is_move_assignable<_Tp>::value,
// Unique tag type. // Unique tag type.
optional<_Tp>> optional<_Tp>>
{ {
static_assert(!is_same<typename remove_cv<_Tp>::type, static_assert(__and_<__not_<is_same<typename remove_cv<_Tp>::type,
nullopt_t>() nullopt_t>>,
&& !is_same<typename remove_cv<_Tp>::type, __not_<is_same<typename remove_cv<_Tp>::type,
in_place_t>() in_place_t>>,
&& !is_reference<_Tp>(), __not_<is_reference<_Tp>>>(),
"Invalid instantiation of optional<T>."); "Invalid instantiation of optional<T>");
private: private:
using _Base = _Optional_base<_Tp>; using _Base = _Optional_base<_Tp>;
...@@ -503,9 +499,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -503,9 +499,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>::type >::type
operator=(_Up&& __u) operator=(_Up&& __u)
{ {
static_assert(is_constructible<_Tp, _Up>() static_assert(__and_<is_constructible<_Tp, _Up>,
&& is_assignable<_Tp&, _Up>(), is_assignable<_Tp&, _Up>>(),
"Cannot assign to value type from argument."); "Cannot assign to value type from argument");
if (this->_M_is_engaged()) if (this->_M_is_engaged())
this->_M_get() = std::forward<_Up>(__u); this->_M_get() = std::forward<_Up>(__u);
...@@ -520,7 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -520,7 +516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
emplace(_Args&&... __args) emplace(_Args&&... __args)
{ {
static_assert(is_constructible<_Tp, _Args&&...>(), static_assert(is_constructible<_Tp, _Args&&...>(),
"Cannot emplace value type from arguments."); "Cannot emplace value type from arguments");
this->_M_reset(); this->_M_reset();
this->_M_construct(std::forward<_Args>(__args)...); this->_M_construct(std::forward<_Args>(__args)...);
...@@ -551,15 +547,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -551,15 +547,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this->_M_is_engaged() && __other._M_is_engaged()) if (this->_M_is_engaged() && __other._M_is_engaged())
swap(this->_M_get(), __other._M_get()); swap(this->_M_get(), __other._M_get());
else if (this->_M_is_engaged()) else if (this->_M_is_engaged())
{ {
__other._M_construct(std::move(this->_M_get())); __other._M_construct(std::move(this->_M_get()));
this->_M_destruct(); this->_M_destruct();
} }
else if (__other._M_is_engaged()) else if (__other._M_is_engaged())
{ {
this->_M_construct(std::move(__other._M_get())); this->_M_construct(std::move(__other._M_get()));
__other._M_destruct(); __other._M_destruct();
} }
} }
// [X.Y.4.5] Observers. // [X.Y.4.5] Observers.
...@@ -585,11 +581,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -585,11 +581,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr const _Tp& constexpr const _Tp&
value() const value() const
{ {
return this->_M_is_engaged() ? return this->_M_is_engaged()
this->_M_get() : ? this->_M_get()
(__throw_bad_optional_access("Attempt to access value of a disengaged" : (__throw_bad_optional_access("Attempt to access value of a "
" optional object."), "disengaged optional object"),
this->_M_get()); this->_M_get());
} }
_Tp& _Tp&
...@@ -598,34 +594,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -598,34 +594,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (this->_M_is_engaged()) if (this->_M_is_engaged())
return this->_M_get(); return this->_M_get();
__throw_bad_optional_access("Attempt to access value of a disengaged" __throw_bad_optional_access("Attempt to access value of a "
" optional object."); "disengaged optional object");
} }
template<typename _Up> template<typename _Up>
constexpr _Tp constexpr _Tp
value_or(_Up&& __u) const& value_or(_Up&& __u) const&
{ {
static_assert(is_copy_constructible<_Tp>() static_assert(__and_<is_copy_constructible<_Tp>,
&& is_convertible<_Up&&, _Tp>(), is_convertible<_Up&&, _Tp>>(),
"Cannot return value."); "Cannot return value");
return this->_M_is_engaged() ? return this->_M_is_engaged()
this->_M_get() : ? this->_M_get()
static_cast<_Tp>(std::forward<_Up>(__u)); : static_cast<_Tp>(std::forward<_Up>(__u));
} }
template<typename _Up> template<typename _Up>
_Tp _Tp
value_or(_Up&& __u) && value_or(_Up&& __u) &&
{ {
static_assert( is_move_constructible<_Tp>() static_assert(__and_<is_move_constructible<_Tp>,
&& is_convertible<_Up&&, _Tp>(), is_convertible<_Up&&, _Tp>>(),
"Cannot return value." ); "Cannot return value" );
return this->_M_is_engaged() ? return this->_M_is_engaged()
std::move(this->_M_get()) : ? std::move(this->_M_get())
static_cast<_Tp>(std::forward<_Up>(__u)); : static_cast<_Tp>(std::forward<_Up>(__u));
} }
}; };
...@@ -635,7 +631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -635,7 +631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) operator==(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
{ {
return static_cast<bool>(__lhs) == static_cast<bool>(__rhs) return static_cast<bool>(__lhs) == static_cast<bool>(__rhs)
&& (!__lhs || *__lhs == *__rhs); && (!__lhs || *__lhs == *__rhs);
} }
template<typename _Tp> template<typename _Tp>
...@@ -647,8 +643,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -647,8 +643,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
constexpr bool constexpr bool
operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs) operator<(const optional<_Tp>& __lhs, const optional<_Tp>& __rhs)
{ {
return static_cast<bool>(__rhs) return static_cast<bool>(__rhs) && (!__lhs || *__lhs < *__rhs);
&& (!__lhs || *__lhs < *__rhs);
} }
template<typename _Tp> template<typename _Tp>
...@@ -790,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION ...@@ -790,7 +785,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// [X.Y.11] // [X.Y.11]
template<typename _Tp> template<typename _Tp>
void inline void
swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs) swap(optional<_Tp>& __lhs, optional<_Tp>& __rhs)
noexcept(noexcept(__lhs.swap(__rhs))) noexcept(noexcept(__lhs.swap(__rhs)))
{ __lhs.swap(__rhs); } { __lhs.swap(__rhs); }
......
...@@ -63,11 +63,12 @@ int main() ...@@ -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; auto copy = o;
VERIFY( copy ); VERIFY( copy );
VERIFY( *copy == 0x1234ABCDF1E2D3C4 ); VERIFY( *copy == val );
VERIFY( o && o == 0x1234ABCDF1E2D3C4 ); VERIFY( o && o == val );
} }
{ {
......
...@@ -63,11 +63,12 @@ int main() ...@@ -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); auto moved_to = std::move(o);
VERIFY( moved_to ); VERIFY( moved_to );
VERIFY( *moved_to == 0x1234ABCDF1E2D3C4 ); VERIFY( *moved_to == val );
VERIFY( o && *o == 0x1234ABCDF1E2D3C4 ); VERIFY( o && *o == val );
} }
{ {
......
...@@ -66,51 +66,51 @@ int main() ...@@ -66,51 +66,51 @@ int main()
// [20.5.4.1] Constructors // [20.5.4.1] Constructors
{ {
auto i = 0x1234ABCDF1E2D3C4; auto i = 0x1234ABCD;
std::experimental::optional<long> o { i }; std::experimental::optional<long> o { i };
VERIFY( o ); VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 ); VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCDF1E2D3C4 ); VERIFY( i == 0x1234ABCD );
} }
{ {
auto i = 0x1234ABCDF1E2D3C4; auto i = 0x1234ABCD;
std::experimental::optional<long> o = i; std::experimental::optional<long> o = i;
VERIFY( o ); VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 ); VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCDF1E2D3C4 ); VERIFY( i == 0x1234ABCD );
} }
{ {
auto i = 0x1234ABCDF1E2D3C4; auto i = 0x1234ABCD;
std::experimental::optional<long> o = { i }; std::experimental::optional<long> o = { i };
VERIFY( o ); VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 ); VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCDF1E2D3C4 ); VERIFY( i == 0x1234ABCD );
} }
{ {
auto i = 0x1234ABCDF1E2D3C4; auto i = 0x1234ABCD;
std::experimental::optional<long> o { std::move(i) }; std::experimental::optional<long> o { std::move(i) };
VERIFY( o ); VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 ); VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCDF1E2D3C4 ); VERIFY( i == 0x1234ABCD );
} }
{ {
auto i = 0x1234ABCDF1E2D3C4; auto i = 0x1234ABCD;
std::experimental::optional<long> o = std::move(i); std::experimental::optional<long> o = std::move(i);
VERIFY( o ); VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 ); VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCDF1E2D3C4 ); VERIFY( i == 0x1234ABCD );
} }
{ {
auto i = 0x1234ABCDF1E2D3C4; auto i = 0x1234ABCD;
std::experimental::optional<long> o = { std::move(i) }; std::experimental::optional<long> o = { std::move(i) };
VERIFY( o ); VERIFY( o );
VERIFY( *o == 0x1234ABCDF1E2D3C4 ); VERIFY( *o == 0x1234ABCD );
VERIFY( i == 0x1234ABCDF1E2D3C4 ); VERIFY( i == 0x1234ABCD );
} }
{ {
......
...@@ -26,44 +26,44 @@ int main() ...@@ -26,44 +26,44 @@ int main()
// [20.5.4.1] Constructors // [20.5.4.1] Constructors
{ {
constexpr auto i = 0x1234ABCDF1E2D3C4; constexpr long i = 0x1234ABCD;
constexpr std::experimental::optional<long> o { i }; constexpr std::experimental::optional<long> o { i };
static_assert( o, "" ); 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; constexpr std::experimental::optional<long> o = i;
static_assert( o, "" ); 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 }; constexpr std::experimental::optional<long> o = { i };
static_assert( o, "" ); 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) }; constexpr std::experimental::optional<long> o { std::move(i) };
static_assert( o, "" ); 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); constexpr std::experimental::optional<long> o = std::move(i);
static_assert( o, "" ); 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) }; constexpr std::experimental::optional<long> o = { std::move(i) };
static_assert( o, "" ); static_assert( o, "" );
static_assert( *o == 0x1234ABCDF1E2D3C4, "" ); static_assert( *o == 0x1234ABCD, "" );
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment