aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVille Voutilainen <ville.voutilainen@gmail.com>2019-03-28 18:18:49 +0200
committerVille Voutilainen <ville@gcc.gnu.org>2019-03-28 18:18:49 +0200
commit337d1fec361442eb173d834e4bb8ac6811397a1a (patch)
treecfc230a2f967e0929ecffa310367479e54e4f810
parentc7a53bdbb164f5a216f13801c1abbaa8c08c81f1 (diff)
downloadgcc-337d1fec361442eb173d834e4bb8ac6811397a1a.zip
gcc-337d1fec361442eb173d834e4bb8ac6811397a1a.tar.gz
gcc-337d1fec361442eb173d834e4bb8ac6811397a1a.tar.bz2
Don't revisit a variant we are already visiting.
* include/std/variant (__variant_construct_single): New. (__variant_construct): Use it. (_M_destructive_move): Likewise. (_M_destructive_copy): Likewise. (_Copy_assign_base::operator=): Adjust. (_Move_assign_base::operator=): Likewise. (swap): Likewise. From-SVN: r269996
-rw-r--r--libstdc++-v3/ChangeLog11
-rw-r--r--libstdc++-v3/include/std/variant131
2 files changed, 86 insertions, 56 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index b15d12d..c7b47d8 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2019-03-28 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Don't revisit a variant we are already visiting.
+ * include/std/variant (__variant_construct_single): New.
+ (__variant_construct): Use it.
+ (_M_destructive_move): Likewise.
+ (_M_destructive_copy): Likewise.
+ (_Copy_assign_base::operator=): Adjust.
+ (_Move_assign_base::operator=): Likewise.
+ (swap): Likewise.
+
2019-03-26 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/85965
diff --git a/libstdc++-v3/include/std/variant b/libstdc++-v3/include/std/variant
index 3932a8a..7fd6947 100644
--- a/libstdc++-v3/include/std/variant
+++ b/libstdc++-v3/include/std/variant
@@ -428,20 +428,25 @@ namespace __variant
using _Variant_storage_alias =
_Variant_storage<_Traits<_Types...>::_S_trivial_dtor, _Types...>;
+ template<typename _Tp, typename _Up>
+ void __variant_construct_single(_Tp&& __lhs, _Up&& __rhs_mem)
+ {
+ void* __storage = std::addressof(__lhs._M_u);
+ using _Type = remove_reference_t<decltype(__rhs_mem)>;
+ if constexpr (!is_same_v<_Type, __variant_cookie>)
+ ::new (__storage)
+ _Type(std::forward<decltype(__rhs_mem)>(__rhs_mem));
+ }
+
template<typename... _Types, typename _Tp, typename _Up>
void __variant_construct(_Tp&& __lhs, _Up&& __rhs)
{
__lhs._M_index = __rhs._M_index;
- void* __storage = std::addressof(__lhs._M_u);
- __do_visit([__storage](auto&& __rhs_mem) mutable
+ __do_visit([&__lhs](auto&& __rhs_mem) mutable
-> __detail::__variant::__variant_cookie
{
- using _Type = remove_reference_t<decltype(__rhs_mem)>;
- if constexpr (is_same_v<__remove_cvref_t<decltype(__rhs_mem)>,
- remove_cv_t<_Type>>
- && !is_same_v<_Type, __variant_cookie>)
- ::new (__storage)
- _Type(std::forward<decltype(__rhs_mem)>(__rhs_mem));
+ __variant_construct_single(std::forward<_Tp>(__lhs),
+ std::forward<decltype(__rhs_mem)>(__rhs_mem));
return {};
}, __variant_cast<_Types...>(std::forward<decltype(__rhs)>(__rhs)));
}
@@ -490,34 +495,38 @@ namespace __variant
std::forward<_Move_ctor_base>(__rhs));
}
- void _M_destructive_move(_Move_ctor_base&& __rhs)
- {
- this->_M_reset();
- __try
- {
- __variant_construct<_Types...>(*this,
- std::forward<_Move_ctor_base>(__rhs));
- }
- __catch (...)
- {
- this->_M_index = variant_npos;
- __throw_exception_again;
- }
- }
+ template<typename _Up>
+ void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs)
+ {
+ this->_M_reset();
+ this->_M_index = __rhs_index;
+ __try
+ {
+ __variant_construct_single(*this,
+ std::forward<_Up>(__rhs));
+ }
+ __catch (...)
+ {
+ this->_M_index = variant_npos;
+ __throw_exception_again;
+ }
+ }
- void _M_destructive_copy(const _Move_ctor_base& __rhs)
- {
- this->_M_reset();
- __try
- {
- __variant_construct<_Types...>(*this, __rhs);
- }
- __catch (...)
- {
- this->_M_index = variant_npos;
- __throw_exception_again;
- }
- }
+ template<typename _Up>
+ void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs)
+ {
+ this->_M_reset();
+ this->_M_index = __rhs_index;
+ __try
+ {
+ __variant_construct_single(*this, __rhs);
+ }
+ __catch (...)
+ {
+ this->_M_index = variant_npos;
+ __throw_exception_again;
+ }
+ }
_Move_ctor_base(const _Move_ctor_base&) = default;
_Move_ctor_base& operator=(const _Move_ctor_base&) = default;
@@ -530,17 +539,21 @@ namespace __variant
using _Base = _Copy_ctor_alias<_Types...>;
using _Base::_Base;
- void _M_destructive_move(_Move_ctor_base&& __rhs)
- {
- this->_M_reset();
- __variant_construct<_Types...>(*this,
- std::forward<_Move_ctor_base>(__rhs));
- }
- void _M_destructive_copy(const _Move_ctor_base& __rhs)
- {
- this->_M_reset();
- __variant_construct<_Types...>(*this, __rhs);
- }
+ template<typename _Up>
+ void _M_destructive_move(unsigned short __rhs_index, _Up&& __rhs)
+ {
+ this->_M_reset();
+ this->_M_index = __rhs_index;
+ __variant_construct_single(*this,
+ std::forward<_Up>(__rhs));
+ }
+ template<typename _Up>
+ void _M_destructive_copy(unsigned short __rhs_index, const _Up& __rhs)
+ {
+ this->_M_reset();
+ this->_M_index = __rhs_index;
+ __variant_construct_single(*this, __rhs);
+ }
};
template<typename... _Types>
@@ -580,12 +593,13 @@ namespace __variant
if constexpr (is_nothrow_copy_constructible_v<__rhs_type>
|| !is_nothrow_move_constructible_v<__rhs_type>)
{
- this->_M_destructive_copy(__rhs);
+ this->_M_destructive_copy(__rhs._M_index, __rhs_mem);
}
else
{
- _Copy_assign_base __tmp(__rhs);
- this->_M_destructive_move(std::move(__tmp));
+ auto __tmp(__rhs_mem);
+ this->_M_destructive_move(__rhs._M_index,
+ std::move(__tmp));
}
}
else
@@ -641,8 +655,8 @@ namespace __variant
}
else
{
- _Move_assign_base __tmp(std::move(__rhs));
- this->_M_destructive_move(std::move(__tmp));
+ auto __tmp(std::move(__rhs_mem));
+ this->_M_destructive_move(__rhs._M_index, std::move(__tmp));
}
return {};
}, __variant_cast<_Types...>(*this), __variant_cast<_Types...>(__rhs));
@@ -1409,21 +1423,26 @@ namespace __variant
remove_reference_t<decltype(__this_mem)>,
__detail::__variant::__variant_cookie>)
{
- this->_M_destructive_move(std::move(__rhs));
+ this->_M_destructive_move(__rhs.index(),
+ std::move(__rhs_mem));
__rhs._M_reset();
}
else if constexpr (is_same_v<
remove_reference_t<decltype(__rhs_mem)>,
__detail::__variant::__variant_cookie>)
{
- __rhs._M_destructive_move(std::move(*this));
+ __rhs._M_destructive_move(this->index(),
+ std::move(__this_mem));
this->_M_reset();
}
else
{
- auto __tmp = std::move(__rhs);
- __rhs._M_destructive_move(std::move(*this));
- this->_M_destructive_move(std::move(__tmp));
+ auto __tmp(std::move(__rhs_mem));
+ auto __idx = __rhs.index();
+ __rhs._M_destructive_move(this->index(),
+ std::move(__this_mem));
+ this->_M_destructive_move(__idx,
+ std::move(__tmp));
}
}
return {};