Remove some more code duplication in std::optional
Hoist the duplicated code from the _Optional_payload partial specializations into the _Optional_payload_base base class. * include/std/optional (_Optional_payload_base::_M_copy_assign): New member function to perform non-trivial assignment. (_Optional_payload_base::_M_move_assign): Likewise. (_Optional_payload<T, true, false, true>::operator=) (_Optional_payload<T, true, true, false>::operator=) (_Optional_payload<T, true, false, false>::operator=): Call _M_copy_assign and/or _M_move_assign to do non-trivial assignments. From-SVN: r267761
This commit is contained in:
parent
5ed895a74a
commit
50b0a3d672
|
@ -1,5 +1,13 @@
|
||||||
2019-01-09 Jonathan Wakely <jwakely@redhat.com>
|
2019-01-09 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/std/optional (_Optional_payload_base::_M_copy_assign): New
|
||||||
|
member function to perform non-trivial assignment.
|
||||||
|
(_Optional_payload_base::_M_move_assign): Likewise.
|
||||||
|
(_Optional_payload<T, true, false, true>::operator=)
|
||||||
|
(_Optional_payload<T, true, true, false>::operator=)
|
||||||
|
(_Optional_payload<T, true, false, false>::operator=): Call
|
||||||
|
_M_copy_assign and/or _M_move_assign to do non-trivial assignments.
|
||||||
|
|
||||||
PR libstdc++/88204
|
PR libstdc++/88204
|
||||||
* testsuite/26_numerics/complex/operators/more_constexpr.cc: Do not
|
* testsuite/26_numerics/complex/operators/more_constexpr.cc: Do not
|
||||||
test std::complex<long double> if long double format is IBM128.
|
test std::complex<long double> if long double format is IBM128.
|
||||||
|
|
|
@ -157,6 +157,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_Optional_payload_base&
|
_Optional_payload_base&
|
||||||
operator=(_Optional_payload_base&&) = default;
|
operator=(_Optional_payload_base&&) = default;
|
||||||
|
|
||||||
|
// used to perform non-trivial copy assignment.
|
||||||
|
constexpr void
|
||||||
|
_M_copy_assign(const _Optional_payload_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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to perform non-trivial move assignment.
|
||||||
|
constexpr void
|
||||||
|
_M_move_assign(_Optional_payload_base&& __other)
|
||||||
|
noexcept(__and_v<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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct _Empty_byte { };
|
struct _Empty_byte { };
|
||||||
|
|
||||||
template<typename _Up, bool = is_trivially_destructible_v<_Up>>
|
template<typename _Up, bool = is_trivially_destructible_v<_Up>>
|
||||||
|
@ -286,15 +318,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_Optional_payload&
|
_Optional_payload&
|
||||||
operator=(const _Optional_payload& __other)
|
operator=(const _Optional_payload& __other)
|
||||||
{
|
{
|
||||||
if (this->_M_engaged && __other._M_engaged)
|
this->_M_copy_assign(__other);
|
||||||
this->_M_get() = __other._M_get();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (__other._M_engaged)
|
|
||||||
this->_M_construct(__other._M_get());
|
|
||||||
else
|
|
||||||
this->_M_reset();
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -319,15 +343,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
noexcept(__and_v<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)
|
this->_M_move_assign(std::move(__other));
|
||||||
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;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -344,20 +360,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
_Optional_payload(const _Optional_payload&) = default;
|
_Optional_payload(const _Optional_payload&) = default;
|
||||||
_Optional_payload(_Optional_payload&&) = default;
|
_Optional_payload(_Optional_payload&&) = default;
|
||||||
|
|
||||||
// Non-trivial copy
|
// Non-trivial copy assignment.
|
||||||
constexpr
|
constexpr
|
||||||
_Optional_payload&
|
_Optional_payload&
|
||||||
operator=(const _Optional_payload& __other)
|
operator=(const _Optional_payload& __other)
|
||||||
{
|
{
|
||||||
if (this->_M_engaged && __other._M_engaged)
|
this->_M_copy_assign(__other);
|
||||||
this->_M_get() = __other._M_get();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (__other._M_engaged)
|
|
||||||
this->_M_construct(__other._M_get());
|
|
||||||
else
|
|
||||||
this->_M_reset();
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,15 +376,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
noexcept(__and_v<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)
|
this->_M_move_assign(std::move(__other));
|
||||||
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;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue