mirror of git://gcc.gnu.org/git/gcc.git
Refactor std::optional SFINAE constraints
* include/std/optional (_Optional_payload): Use variable templates for conditions in default template arguments and exception specifications. (optional): Likewise. Adjust indentation. (optional::__not_self, optional::__not_tag, optional::_Requires): New SFINAE helpers. (optional::optional): Use new helpers in constructor constraints. * include/std/type_traits (__or_v, __and_v): New variable templates. * testsuite/20_util/optional/cons/value_neg.cc: Change dg-error to dg-prune-output. Remove unused header. From-SVN: r263657
This commit is contained in:
parent
285ee4d029
commit
b655b8fc7e
|
|
@ -1,3 +1,16 @@
|
||||||
|
2018-08-20 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/std/optional (_Optional_payload): Use variable templates
|
||||||
|
for conditions in default template arguments and exception
|
||||||
|
specifications.
|
||||||
|
(optional): Likewise. Adjust indentation.
|
||||||
|
(optional::__not_self, optional::__not_tag, optional::_Requires): New
|
||||||
|
SFINAE helpers.
|
||||||
|
(optional::optional): Use new helpers in constructor constraints.
|
||||||
|
* include/std/type_traits (__or_v, __and_v): New variable templates.
|
||||||
|
* testsuite/20_util/optional/cons/value_neg.cc: Change dg-error to
|
||||||
|
dg-prune-output. Remove unused header.
|
||||||
|
|
||||||
2018-08-18 François Dumont <fdumont@gcc.gnu.org>
|
2018-08-18 François Dumont <fdumont@gcc.gnu.org>
|
||||||
|
|
||||||
* testsuite/25_algorithms/copy/86658.cc: Use dg-options to define
|
* testsuite/25_algorithms/copy/86658.cc: Use dg-options to define
|
||||||
|
|
|
||||||
|
|
@ -102,11 +102,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
// Payload for optionals with non-trivial destructor.
|
// Payload for optionals with non-trivial destructor.
|
||||||
template <typename _Tp,
|
template <typename _Tp,
|
||||||
bool /*_HasTrivialDestructor*/ =
|
bool /*_HasTrivialDestructor*/ =
|
||||||
is_trivially_destructible<_Tp>::value,
|
is_trivially_destructible_v<_Tp>,
|
||||||
bool /*_HasTrivialCopyAssignment*/ =
|
bool /*_HasTrivialCopyAssignment*/ =
|
||||||
is_trivially_copy_assignable<_Tp>::value,
|
is_trivially_copy_assignable_v<_Tp>,
|
||||||
bool /*_HasTrivialMoveAssignment*/ =
|
bool /*_HasTrivialMoveAssignment*/ =
|
||||||
is_trivially_move_assignable<_Tp>::value>
|
is_trivially_move_assignable_v<_Tp>>
|
||||||
struct _Optional_payload
|
struct _Optional_payload
|
||||||
{
|
{
|
||||||
constexpr _Optional_payload() noexcept : _M_empty() { }
|
constexpr _Optional_payload() noexcept : _M_empty() { }
|
||||||
|
|
@ -165,8 +165,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
_Optional_payload&
|
_Optional_payload&
|
||||||
operator=(_Optional_payload&& __other)
|
operator=(_Optional_payload&& __other)
|
||||||
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
|
noexcept(__and_v<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());
|
||||||
|
|
@ -199,7 +199,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(_Args&&... __args)
|
_M_construct(_Args&&... __args)
|
||||||
noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
|
noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
|
||||||
{
|
{
|
||||||
::new ((void *) std::__addressof(this->_M_payload))
|
::new ((void *) std::__addressof(this->_M_payload))
|
||||||
_Stored_type(std::forward<_Args>(__args)...);
|
_Stored_type(std::forward<_Args>(__args)...);
|
||||||
|
|
@ -377,7 +377,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(_Args&&... __args)
|
_M_construct(_Args&&... __args)
|
||||||
noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
|
noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
|
||||||
{
|
{
|
||||||
::new ((void *) std::__addressof(this->_M_payload))
|
::new ((void *) std::__addressof(this->_M_payload))
|
||||||
_Stored_type(std::forward<_Args>(__args)...);
|
_Stored_type(std::forward<_Args>(__args)...);
|
||||||
|
|
@ -468,8 +468,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
_Optional_payload&
|
_Optional_payload&
|
||||||
operator=(_Optional_payload&& __other)
|
operator=(_Optional_payload&& __other)
|
||||||
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
|
noexcept(__and_v<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());
|
||||||
|
|
@ -496,7 +496,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(_Args&&... __args)
|
_M_construct(_Args&&... __args)
|
||||||
noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
|
noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
|
||||||
{
|
{
|
||||||
::new ((void *) std::__addressof(this->_M_payload))
|
::new ((void *) std::__addressof(this->_M_payload))
|
||||||
_Stored_type(std::forward<_Args>(__args)...);
|
_Stored_type(std::forward<_Args>(__args)...);
|
||||||
|
|
@ -598,8 +598,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
_Optional_payload&
|
_Optional_payload&
|
||||||
operator=(_Optional_payload&& __other)
|
operator=(_Optional_payload&& __other)
|
||||||
noexcept(__and_<is_nothrow_move_constructible<_Tp>,
|
noexcept(__and_v<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());
|
||||||
|
|
@ -626,7 +626,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(_Args&&... __args)
|
_M_construct(_Args&&... __args)
|
||||||
noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
|
noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
|
||||||
{
|
{
|
||||||
::new ((void *) std::__addressof(this->_M_payload))
|
::new ((void *) std::__addressof(this->_M_payload))
|
||||||
_Stored_type(std::forward<_Args>(__args)...);
|
_Stored_type(std::forward<_Args>(__args)...);
|
||||||
|
|
@ -665,7 +665,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
void
|
void
|
||||||
_M_construct(_Args&&... __args)
|
_M_construct(_Args&&... __args)
|
||||||
noexcept(is_nothrow_constructible<_Stored_type, _Args...>())
|
noexcept(is_nothrow_constructible_v<_Stored_type, _Args...>)
|
||||||
{
|
{
|
||||||
::new
|
::new
|
||||||
(std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
|
(std::__addressof(static_cast<_Dp*>(this)->_M_payload._M_payload))
|
||||||
|
|
@ -735,7 +735,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
constexpr _Optional_base(_Optional_base&& __other)
|
constexpr _Optional_base(_Optional_base&& __other)
|
||||||
noexcept(is_nothrow_move_constructible<_Tp>())
|
noexcept(is_nothrow_move_constructible_v<_Tp>)
|
||||||
: _M_payload(__other._M_payload._M_engaged,
|
: _M_payload(__other._M_payload._M_engaged,
|
||||||
std::move(__other._M_payload))
|
std::move(__other._M_payload))
|
||||||
{ }
|
{ }
|
||||||
|
|
@ -864,7 +864,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
constexpr _Optional_base(const _Optional_base& __other) = default;
|
constexpr _Optional_base(const _Optional_base& __other) = default;
|
||||||
|
|
||||||
constexpr _Optional_base(_Optional_base&& __other)
|
constexpr _Optional_base(_Optional_base&& __other)
|
||||||
noexcept(is_nothrow_move_constructible<_Tp>())
|
noexcept(is_nothrow_move_constructible_v<_Tp>)
|
||||||
: _M_payload(__other._M_payload._M_engaged,
|
: _M_payload(__other._M_payload._M_engaged,
|
||||||
std::move(__other._M_payload))
|
std::move(__other._M_payload))
|
||||||
{ }
|
{ }
|
||||||
|
|
@ -985,16 +985,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
class optional
|
class optional
|
||||||
: private _Optional_base<_Tp>,
|
: private _Optional_base<_Tp>,
|
||||||
private _Enable_copy_move<
|
private _Enable_copy_move<
|
||||||
// Copy constructor.
|
// Copy constructor.
|
||||||
is_copy_constructible<_Tp>::value,
|
is_copy_constructible_v<_Tp>,
|
||||||
// Copy assignment.
|
// Copy assignment.
|
||||||
__and_<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>::value,
|
__and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
|
||||||
// Move constructor.
|
// Move constructor.
|
||||||
is_move_constructible<_Tp>::value,
|
is_move_constructible_v<_Tp>,
|
||||||
// Move assignment.
|
// Move assignment.
|
||||||
__and_<is_move_constructible<_Tp>, is_move_assignable<_Tp>>::value,
|
__and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
|
||||||
// Unique tag type.
|
// Unique tag type.
|
||||||
optional<_Tp>>
|
optional<_Tp>>
|
||||||
{
|
{
|
||||||
static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
|
static_assert(!is_same_v<remove_cv_t<_Tp>, nullopt_t>);
|
||||||
static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
|
static_assert(!is_same_v<remove_cv_t<_Tp>, in_place_t>);
|
||||||
|
|
@ -1003,6 +1003,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
private:
|
private:
|
||||||
using _Base = _Optional_base<_Tp>;
|
using _Base = _Optional_base<_Tp>;
|
||||||
|
|
||||||
|
// SFINAE helpers
|
||||||
|
template<typename _Up>
|
||||||
|
using __not_self = __not_<is_same<optional, __remove_cvref_t<_Up>>>;
|
||||||
|
template<typename _Up>
|
||||||
|
using __not_tag = __not_<is_same<in_place_t, __remove_cvref_t<_Up>>>;
|
||||||
|
template<typename... _Cond>
|
||||||
|
using _Requires = enable_if_t<__and_v<_Cond...>, bool>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using value_type = _Tp;
|
using value_type = _Tp;
|
||||||
|
|
||||||
|
|
@ -1011,171 +1019,158 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
constexpr optional(nullopt_t) noexcept { }
|
constexpr optional(nullopt_t) noexcept { }
|
||||||
|
|
||||||
// Converting constructors for engaged optionals.
|
// Converting constructors for engaged optionals.
|
||||||
template <typename _Up = _Tp,
|
template<typename _Up = _Tp,
|
||||||
enable_if_t<__and_<
|
_Requires<__not_self<_Up>, __not_tag<_Up>,
|
||||||
__not_<is_same<optional<_Tp>, decay_t<_Up>>>,
|
is_constructible<_Tp, _Up&&>,
|
||||||
__not_<is_same<in_place_t, decay_t<_Up>>>,
|
is_convertible<_Up&&, _Tp>> = true>
|
||||||
is_constructible<_Tp, _Up&&>,
|
constexpr
|
||||||
is_convertible<_Up&&, _Tp>
|
optional(_Up&& __t)
|
||||||
>::value, bool> = true>
|
: _Base(std::in_place, std::forward<_Up>(__t)) { }
|
||||||
constexpr optional(_Up&& __t)
|
|
||||||
|
template<typename _Up = _Tp,
|
||||||
|
_Requires<__not_self<_Up>, __not_tag<_Up>,
|
||||||
|
is_constructible<_Tp, _Up&&>,
|
||||||
|
__not_<is_convertible<_Up&&, _Tp>>> = false>
|
||||||
|
explicit constexpr
|
||||||
|
optional(_Up&& __t)
|
||||||
: _Base(std::in_place, std::forward<_Up>(__t)) { }
|
: _Base(std::in_place, std::forward<_Up>(__t)) { }
|
||||||
|
|
||||||
template <typename _Up = _Tp,
|
template<typename _Up,
|
||||||
enable_if_t<__and_<
|
_Requires<__not_<is_same<_Tp, _Up>>,
|
||||||
__not_<is_same<optional<_Tp>, decay_t<_Up>>>,
|
is_constructible<_Tp, const _Up&>,
|
||||||
__not_<is_same<in_place_t, decay_t<_Up>>>,
|
is_convertible<const _Up&, _Tp>,
|
||||||
is_constructible<_Tp, _Up&&>,
|
__not_<__converts_from_optional<_Tp, _Up>>> = true>
|
||||||
__not_<is_convertible<_Up&&, _Tp>>
|
constexpr
|
||||||
>::value, bool> = false>
|
optional(const optional<_Up>& __t)
|
||||||
explicit constexpr optional(_Up&& __t)
|
{
|
||||||
: _Base(std::in_place, std::forward<_Up>(__t)) { }
|
if (__t)
|
||||||
|
emplace(*__t);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename _Up,
|
||||||
|
_Requires<__not_<is_same<_Tp, _Up>>,
|
||||||
|
is_constructible<_Tp, const _Up&>,
|
||||||
|
__not_<is_convertible<const _Up&, _Tp>>,
|
||||||
|
__not_<__converts_from_optional<_Tp, _Up>>> = false>
|
||||||
|
explicit constexpr
|
||||||
|
optional(const optional<_Up>& __t)
|
||||||
|
{
|
||||||
|
if (__t)
|
||||||
|
emplace(*__t);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename _Up,
|
template <typename _Up,
|
||||||
enable_if_t<__and_<
|
_Requires<__not_<is_same<_Tp, _Up>>,
|
||||||
__not_<is_same<_Tp, _Up>>,
|
is_constructible<_Tp, _Up&&>,
|
||||||
is_constructible<_Tp, const _Up&>,
|
is_convertible<_Up&&, _Tp>,
|
||||||
is_convertible<const _Up&, _Tp>,
|
__not_<__converts_from_optional<_Tp, _Up>>> = true>
|
||||||
__not_<__converts_from_optional<_Tp, _Up>>
|
constexpr
|
||||||
>::value, bool> = true>
|
optional(optional<_Up>&& __t)
|
||||||
constexpr optional(const optional<_Up>& __t)
|
{
|
||||||
{
|
if (__t)
|
||||||
if (__t)
|
emplace(std::move(*__t));
|
||||||
emplace(*__t);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename _Up,
|
template <typename _Up,
|
||||||
enable_if_t<__and_<
|
_Requires<__not_<is_same<_Tp, _Up>>,
|
||||||
__not_<is_same<_Tp, _Up>>,
|
is_constructible<_Tp, _Up&&>,
|
||||||
is_constructible<_Tp, const _Up&>,
|
__not_<is_convertible<_Up&&, _Tp>>,
|
||||||
__not_<is_convertible<const _Up&, _Tp>>,
|
__not_<__converts_from_optional<_Tp, _Up>>> = false>
|
||||||
__not_<__converts_from_optional<_Tp, _Up>>
|
explicit constexpr
|
||||||
>::value, bool> = false>
|
optional(optional<_Up>&& __t)
|
||||||
explicit constexpr optional(const optional<_Up>& __t)
|
{
|
||||||
{
|
if (__t)
|
||||||
if (__t)
|
emplace(std::move(*__t));
|
||||||
emplace(*__t);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename _Up,
|
|
||||||
enable_if_t<__and_<
|
|
||||||
__not_<is_same<_Tp, _Up>>,
|
|
||||||
is_constructible<_Tp, _Up&&>,
|
|
||||||
is_convertible<_Up&&, _Tp>,
|
|
||||||
__not_<__converts_from_optional<_Tp, _Up>>
|
|
||||||
>::value, bool> = true>
|
|
||||||
constexpr optional(optional<_Up>&& __t)
|
|
||||||
{
|
|
||||||
if (__t)
|
|
||||||
emplace(std::move(*__t));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename _Up,
|
|
||||||
enable_if_t<__and_<
|
|
||||||
__not_<is_same<_Tp, _Up>>,
|
|
||||||
is_constructible<_Tp, _Up&&>,
|
|
||||||
__not_<is_convertible<_Up&&, _Tp>>,
|
|
||||||
__not_<__converts_from_optional<_Tp, _Up>>
|
|
||||||
>::value, bool> = false>
|
|
||||||
explicit constexpr optional(optional<_Up>&& __t)
|
|
||||||
{
|
|
||||||
if (__t)
|
|
||||||
emplace(std::move(*__t));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... _Args,
|
template<typename... _Args,
|
||||||
enable_if_t<is_constructible_v<_Tp, _Args&&...>, bool> = false>
|
_Requires<is_constructible<_Tp, _Args&&...>> = false>
|
||||||
explicit constexpr optional(in_place_t, _Args&&... __args)
|
explicit constexpr
|
||||||
: _Base(std::in_place, std::forward<_Args>(__args)...) { }
|
optional(in_place_t, _Args&&... __args)
|
||||||
|
: _Base(std::in_place, std::forward<_Args>(__args)...) { }
|
||||||
|
|
||||||
template<typename _Up, typename... _Args,
|
template<typename _Up, typename... _Args,
|
||||||
enable_if_t<is_constructible_v<_Tp,
|
_Requires<is_constructible<_Tp,
|
||||||
initializer_list<_Up>&,
|
initializer_list<_Up>&,
|
||||||
_Args&&...>, bool> = false>
|
_Args&&...>> = false>
|
||||||
explicit constexpr optional(in_place_t,
|
explicit constexpr
|
||||||
initializer_list<_Up> __il,
|
optional(in_place_t, initializer_list<_Up> __il, _Args&&... __args)
|
||||||
_Args&&... __args)
|
: _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
|
||||||
: _Base(std::in_place, __il, std::forward<_Args>(__args)...) { }
|
|
||||||
|
|
||||||
// Assignment operators.
|
// Assignment operators.
|
||||||
optional&
|
optional&
|
||||||
operator=(nullopt_t) noexcept
|
operator=(nullopt_t) noexcept
|
||||||
{
|
{
|
||||||
this->_M_reset();
|
this->_M_reset();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Up = _Tp>
|
template<typename _Up = _Tp>
|
||||||
enable_if_t<__and_<
|
enable_if_t<__and_v<__not_self<_Up>,
|
||||||
__not_<is_same<optional<_Tp>, decay_t<_Up>>>,
|
__not_<__and_<is_scalar<_Tp>,
|
||||||
is_constructible<_Tp, _Up>,
|
is_same<_Tp, decay_t<_Up>>>>,
|
||||||
__not_<__and_<is_scalar<_Tp>,
|
is_constructible<_Tp, _Up>,
|
||||||
is_same<_Tp, decay_t<_Up>>>>,
|
is_assignable<_Tp&, _Up>>,
|
||||||
is_assignable<_Tp&, _Up>>::value,
|
|
||||||
optional&>
|
optional&>
|
||||||
operator=(_Up&& __u)
|
operator=(_Up&& __u)
|
||||||
{
|
{
|
||||||
if (this->_M_is_engaged())
|
if (this->_M_is_engaged())
|
||||||
this->_M_get() = std::forward<_Up>(__u);
|
this->_M_get() = std::forward<_Up>(__u);
|
||||||
else
|
else
|
||||||
this->_M_construct(std::forward<_Up>(__u));
|
this->_M_construct(std::forward<_Up>(__u));
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Up>
|
template<typename _Up>
|
||||||
enable_if_t<__and_<
|
enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
|
||||||
__not_<is_same<_Tp, _Up>>,
|
is_constructible<_Tp, const _Up&>,
|
||||||
is_constructible<_Tp, const _Up&>,
|
is_assignable<_Tp&, _Up>,
|
||||||
is_assignable<_Tp&, _Up>,
|
__not_<__converts_from_optional<_Tp, _Up>>,
|
||||||
__not_<__converts_from_optional<_Tp, _Up>>,
|
__not_<__assigns_from_optional<_Tp, _Up>>>,
|
||||||
__not_<__assigns_from_optional<_Tp, _Up>>
|
|
||||||
>::value,
|
|
||||||
optional&>
|
optional&>
|
||||||
operator=(const optional<_Up>& __u)
|
operator=(const optional<_Up>& __u)
|
||||||
{
|
{
|
||||||
if (__u)
|
if (__u)
|
||||||
{
|
{
|
||||||
if (this->_M_is_engaged())
|
if (this->_M_is_engaged())
|
||||||
this->_M_get() = *__u;
|
this->_M_get() = *__u;
|
||||||
else
|
else
|
||||||
this->_M_construct(*__u);
|
this->_M_construct(*__u);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->_M_reset();
|
this->_M_reset();
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Up>
|
template<typename _Up>
|
||||||
enable_if_t<__and_<
|
enable_if_t<__and_v<__not_<is_same<_Tp, _Up>>,
|
||||||
__not_<is_same<_Tp, _Up>>,
|
is_constructible<_Tp, _Up>,
|
||||||
is_constructible<_Tp, _Up>,
|
is_assignable<_Tp&, _Up>,
|
||||||
is_assignable<_Tp&, _Up>,
|
__not_<__converts_from_optional<_Tp, _Up>>,
|
||||||
__not_<__converts_from_optional<_Tp, _Up>>,
|
__not_<__assigns_from_optional<_Tp, _Up>>>,
|
||||||
__not_<__assigns_from_optional<_Tp, _Up>>
|
|
||||||
>::value,
|
|
||||||
optional&>
|
optional&>
|
||||||
operator=(optional<_Up>&& __u)
|
operator=(optional<_Up>&& __u)
|
||||||
{
|
{
|
||||||
if (__u)
|
if (__u)
|
||||||
{
|
{
|
||||||
if (this->_M_is_engaged())
|
if (this->_M_is_engaged())
|
||||||
this->_M_get() = std::move(*__u);
|
this->_M_get() = std::move(*__u);
|
||||||
else
|
else
|
||||||
this->_M_construct(std::move(*__u));
|
this->_M_construct(std::move(*__u));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this->_M_reset();
|
this->_M_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... _Args>
|
template<typename... _Args>
|
||||||
enable_if_t<is_constructible<_Tp, _Args&&...>::value, _Tp&>
|
enable_if_t<is_constructible_v<_Tp, _Args&&...>, _Tp&>
|
||||||
emplace(_Args&&... __args)
|
emplace(_Args&&... __args)
|
||||||
{
|
{
|
||||||
this->_M_reset();
|
this->_M_reset();
|
||||||
|
|
@ -1184,8 +1179,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename _Up, typename... _Args>
|
template<typename _Up, typename... _Args>
|
||||||
enable_if_t<is_constructible<_Tp, initializer_list<_Up>&,
|
enable_if_t<is_constructible_v<_Tp, initializer_list<_Up>&,
|
||||||
_Args&&...>::value, _Tp&>
|
_Args&&...>, _Tp&>
|
||||||
emplace(initializer_list<_Up> __il, _Args&&... __args)
|
emplace(initializer_list<_Up> __il, _Args&&... __args)
|
||||||
{
|
{
|
||||||
this->_M_reset();
|
this->_M_reset();
|
||||||
|
|
@ -1198,19 +1193,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
// Swap.
|
// Swap.
|
||||||
void
|
void
|
||||||
swap(optional& __other)
|
swap(optional& __other)
|
||||||
noexcept(is_nothrow_move_constructible<_Tp>()
|
noexcept(is_nothrow_move_constructible_v<_Tp>
|
||||||
&& is_nothrow_swappable_v<_Tp>)
|
&& is_nothrow_swappable_v<_Tp>)
|
||||||
{
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
|
|
||||||
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();
|
||||||
|
|
@ -1307,12 +1302,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
? std::move(this->_M_get())
|
? std::move(this->_M_get())
|
||||||
: static_cast<_Tp>(std::forward<_Up>(__u));
|
: static_cast<_Tp>(std::forward<_Up>(__u));
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() noexcept { this->_M_reset(); }
|
void reset() noexcept { this->_M_reset(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
using __optional_relop_t =
|
using __optional_relop_t =
|
||||||
enable_if_t<is_convertible<_Tp, bool>::value, bool>;
|
enable_if_t<is_convertible<_Tp, bool>::value, bool>;
|
||||||
|
|
||||||
// Comparisons between optional values.
|
// Comparisons between optional values.
|
||||||
template<typename _Tp, typename _Up>
|
template<typename _Tp, typename _Up>
|
||||||
|
|
|
||||||
|
|
@ -144,6 +144,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
#if __cplusplus >= 201703L
|
#if __cplusplus >= 201703L
|
||||||
|
|
||||||
|
template<typename... _Bn>
|
||||||
|
inline constexpr bool __or_v = __or_<_Bn...>::value;
|
||||||
|
template<typename... _Bn>
|
||||||
|
inline constexpr bool __and_v = __and_<_Bn...>::value;
|
||||||
|
|
||||||
#define __cpp_lib_logical_traits 201510
|
#define __cpp_lib_logical_traits 201510
|
||||||
|
|
||||||
template<typename... _Bn>
|
template<typename... _Bn>
|
||||||
|
|
|
||||||
|
|
@ -19,8 +19,6 @@
|
||||||
// <http://www.gnu.org/licenses/>.
|
// <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <testsuite_hooks.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
|
@ -37,8 +35,6 @@ int main()
|
||||||
std::optional<std::unique_ptr<int>> oup2 = new int; // { dg-error "conversion" }
|
std::optional<std::unique_ptr<int>> oup2 = new int; // { dg-error "conversion" }
|
||||||
struct U { explicit U(std::in_place_t); };
|
struct U { explicit U(std::in_place_t); };
|
||||||
std::optional<U> ou(std::in_place); // { dg-error "no matching" }
|
std::optional<U> ou(std::in_place); // { dg-error "no matching" }
|
||||||
// { dg-error "no type" "" { target { *-*-* } } 1020 }
|
|
||||||
// { dg-error "no type" "" { target { *-*-* } } 1030 }
|
|
||||||
// { dg-error "no type" "" { target { *-*-* } } 1087 }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// { dg-prune-output "no type .*enable_if" }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue