aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/tuple
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2022-08-23 13:42:37 -0400
committerPatrick Palka <ppalka@redhat.com>2022-08-23 13:42:37 -0400
commit72886fcc6269531bbf3d9a09b3d64644963bff0d (patch)
treead19ae595e927e200e464a4499b997c8e0d33660 /libstdc++-v3/include/std/tuple
parent02f6b405f0e9dc7a8868fecef9a048b79c433125 (diff)
downloadgcc-72886fcc6269531bbf3d9a09b3d64644963bff0d.zip
gcc-72886fcc6269531bbf3d9a09b3d64644963bff0d.tar.gz
gcc-72886fcc6269531bbf3d9a09b3d64644963bff0d.tar.bz2
libstdc++: Implement std::pair/tuple/misc enhancements from P2321R2
This implements the non-<ranges> changes from P2321R2, which primarily consist of additional converting constructors, assignment operator and swap overloads for std::pair and std::tuple. libstdc++-v3/ChangeLog: * include/bits/stl_bvector.h (_Bit_reference::operator=): Define const overload for C++23 as per P2321R2. * include/bits/stl_pair.h (pair::swap): Likewise. (pair::pair): Define additional converting constructors for C++23 as per P2321R2. (pair::operator=): Define const overloads for C++23 as per P2321R2. (swap): Define overload taking const pair& for C++23 as per P2321R2. (basic_common_reference): Define partial specialization for pair for C++23 as per P2321R2. (common_type): Likewise. * include/bits/uses_allocator_args.h (uses_allocator_construction_args): Define additional pair overloads for C++23 as per P2321R2. * include/std/tuple (_Tuple_impl::_Tuple_impl): Define additional converting constructors for C++23 as per P2321R2. (_Tuple_impl::_M_assign): Define const overloads for C++23 as per P2321R2. (_Tuple_impl::_M_swap): Likewise. (tuple::__constructible): Define as a convenient renaming of _TCC<true>::__constructible. (tuple::__convertible): As above but for _TCC<true>::__convertible. (tuple::tuple): Define additional converting constructors for C++23 as per P2321R2. (tuple::operator=): Define const overloads for C++23 as per P2321R2. (tuple::swap): Likewise. (basic_common_reference): Define partial specialization for tuple for C++23 as per P2321R2. (common_type): Likewise. * testsuite/20_util/pair/p2321r2.cc: New test. * testsuite/20_util/tuple/p2321r2.cc: New test. * testsuite/23_containers/vector/bool/element_access/1.cc: New test.
Diffstat (limited to 'libstdc++-v3/include/std/tuple')
-rw-r--r--libstdc++-v3/include/std/tuple416
1 files changed, 416 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 7f9c072..05433d5 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -316,6 +316,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
{ }
+#if __cplusplus > 202002L
+ template<typename... _UElements>
+ constexpr
+ _Tuple_impl(_Tuple_impl<_Idx, _UElements...>& __in)
+ : _Inherited(_Tuple_impl<_Idx, _UElements...>::_M_tail(__in)),
+ _Base(_Tuple_impl<_Idx, _UElements...>::_M_head(__in))
+ { }
+
+ template<typename _UHead, typename... _UTails>
+ constexpr
+ _Tuple_impl(const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+ : _Inherited(std::move
+ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
+ _Base(std::forward<const _UHead>
+ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
+ { }
+#endif // C++23
+
template<typename _Alloc>
_GLIBCXX20_CONSTEXPR
_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
@@ -379,6 +397,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
{ }
+#if __cplusplus > 202002L
+ template<typename _Alloc, typename _UHead, typename... _UTails>
+ constexpr
+ _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+ _Tuple_impl<_Idx, _UHead, _UTails...>& __in)
+ : _Inherited(__tag, __a,
+ _Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)),
+ _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
+ _Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in))
+ { }
+
+ template<typename _Alloc, typename _UHead, typename... _UTails>
+ constexpr
+ _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+ const _Tuple_impl<_Idx, _UHead, _UTails...>&& __in)
+ : _Inherited(__tag, __a, std::move
+ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in))),
+ _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
+ std::forward<const _UHead>
+ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in)))
+ { }
+#endif // C++23
+
template<typename... _UElements>
_GLIBCXX20_CONSTEXPR
void
@@ -400,6 +441,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
}
+#if __cplusplus > 202002L
+ template<typename... _UElements>
+ constexpr void
+ _M_assign(const _Tuple_impl<_Idx, _UElements...>& __in) const
+ {
+ _M_head(*this) = _Tuple_impl<_Idx, _UElements...>::_M_head(__in);
+ _M_tail(*this)._M_assign(
+ _Tuple_impl<_Idx, _UElements...>::_M_tail(__in));
+ }
+
+ template<typename _UHead, typename... _UTails>
+ constexpr void
+ _M_assign(_Tuple_impl<_Idx, _UHead, _UTails...>&& __in) const
+ {
+ _M_head(*this) = std::forward<_UHead>
+ (_Tuple_impl<_Idx, _UHead, _UTails...>::_M_head(__in));
+ _M_tail(*this)._M_assign(
+ std::move(_Tuple_impl<_Idx, _UHead, _UTails...>::_M_tail(__in)));
+ }
+#endif // C++23
+
protected:
_GLIBCXX20_CONSTEXPR
void
@@ -409,6 +471,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
swap(_M_head(*this), _M_head(__in));
_Inherited::_M_swap(_M_tail(__in));
}
+
+#if __cplusplus > 202002L
+ constexpr void
+ _M_swap(const _Tuple_impl& __in) const
+ {
+ using std::swap;
+ swap(_M_head(*this), _M_head(__in));
+ _Inherited::_M_swap(_M_tail(__in));
+ }
+#endif // C++23
};
// Basis case of inheritance recursion.
@@ -469,6 +541,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _Base(std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
{ }
+#if __cplusplus > 202002L
+ template<typename _UHead>
+ constexpr
+ _Tuple_impl(_Tuple_impl<_Idx, _UHead>& __in)
+ : _Base(_Tuple_impl<_Idx, _UHead>::_M_head(__in))
+ { }
+
+ template<typename _UHead>
+ constexpr
+ _Tuple_impl(const _Tuple_impl<_Idx, _UHead>&& __in)
+ : _Base(std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
+ { }
+#endif // C++23
+
template<typename _Alloc>
_GLIBCXX20_CONSTEXPR
_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
@@ -521,6 +607,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
{ }
+#if __cplusplus > 202002L
+ template<typename _Alloc, typename _UHead>
+ constexpr
+ _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+ _Tuple_impl<_Idx, _UHead>& __in)
+ : _Base(__use_alloc<_Head, _Alloc, _UHead&>(__a),
+ _Tuple_impl<_Idx, _UHead>::_M_head(__in))
+ { }
+
+ template<typename _Alloc, typename _UHead>
+ constexpr
+ _Tuple_impl(allocator_arg_t __tag, const _Alloc& __a,
+ const _Tuple_impl<_Idx, _UHead>&& __in)
+ : _Base(__use_alloc<_Head, _Alloc, const _UHead>(__a),
+ std::forward<const _UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in)))
+ { }
+#endif // C++23
+
template<typename _UHead>
_GLIBCXX20_CONSTEXPR
void
@@ -538,6 +642,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
= std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
}
+#if __cplusplus > 202002L
+ template<typename _UHead>
+ constexpr void
+ _M_assign(const _Tuple_impl<_Idx, _UHead>& __in) const
+ {
+ _M_head(*this) = _Tuple_impl<_Idx, _UHead>::_M_head(__in);
+ }
+
+ template<typename _UHead>
+ constexpr void
+ _M_assign(_Tuple_impl<_Idx, _UHead>&& __in) const
+ {
+ _M_head(*this)
+ = std::forward<_UHead>(_Tuple_impl<_Idx, _UHead>::_M_head(__in));
+ }
+#endif // C++23
+
protected:
_GLIBCXX20_CONSTEXPR
void
@@ -546,6 +667,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using std::swap;
swap(_M_head(*this), _M_head(__in));
}
+
+#if __cplusplus > 202002L
+ constexpr void
+ _M_swap(const _Tuple_impl& __in) const
+ {
+ using std::swap;
+ swap(_M_head(*this), _M_head(__in));
+ }
+#endif // C++23
};
// Concept utility functions, reused in conditionally-explicit
@@ -712,6 +842,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr bool __use_other_ctor()
{ return _UseOtherCtor<_Tuple>::value; }
+#if __cplusplus > 202002L
+ template<typename... _Args>
+ static constexpr bool __constructible
+ = _TCC<true>::template __constructible<_Args...>::value;
+
+ template<typename... _Args>
+ static constexpr bool __convertible
+ = _TCC<true>::template __convertible<_Args...>::value;
+#endif // C++23
+
public:
template<typename _Dummy = void,
_ImplicitDefaultCtor<is_void<_Dummy>::value> = true>
@@ -799,6 +939,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(__nothrow_constructible<_UElements...>())
: _Inherited(static_cast<_Tuple_impl<0, _UElements...>&&>(__in)) { }
+#if __cplusplus > 202002L
+ template<typename... _UElements>
+ requires (sizeof...(_Elements) == sizeof...(_UElements))
+ && (!__use_other_ctor<tuple<_UElements...>&>())
+ && __constructible<_UElements&...>
+ explicit(!__convertible<_UElements&...>)
+ constexpr
+ tuple(tuple<_UElements...>& __in)
+ noexcept(__nothrow_constructible<_UElements&...>())
+ : _Inherited(static_cast<_Tuple_impl<0, _UElements...>&>(__in))
+ { }
+
+ template<typename... _UElements>
+ requires (sizeof...(_Elements) == sizeof...(_UElements))
+ && (!__use_other_ctor<const tuple<_UElements...>&&>())
+ && __constructible<const _UElements...>
+ explicit(!__convertible<const _UElements...>)
+ constexpr
+ tuple(const tuple<_UElements...>&& __in)
+ noexcept(__nothrow_constructible<const _UElements...>())
+ : _Inherited(static_cast<const _Tuple_impl<0, _UElements...>&&>(__in)) { }
+#endif // C++23
+
// Allocator-extended constructors.
template<typename _Alloc,
@@ -897,6 +1060,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static_cast<_Tuple_impl<0, _UElements...>&&>(__in))
{ }
+#if __cplusplus > 202002L
+ template<typename _Alloc, typename... _UElements>
+ requires (sizeof...(_Elements) == sizeof...(_UElements))
+ && (!__use_other_ctor<tuple<_UElements...>&>())
+ && __constructible<_UElements&...>
+ explicit(!__convertible<_UElements&...>)
+ constexpr
+ tuple(allocator_arg_t __tag, const _Alloc& __a,
+ tuple<_UElements...>& __in)
+ : _Inherited(__tag, __a,
+ static_cast<_Tuple_impl<0, _UElements...>&>(__in))
+ { }
+
+ template<typename _Alloc, typename... _UElements>
+ requires (sizeof...(_Elements) == sizeof...(_UElements))
+ && (!__use_other_ctor<const tuple<_UElements...>>())
+ && __constructible<const _UElements...>
+ explicit(!__convertible<const _UElements...>)
+ constexpr
+ tuple(allocator_arg_t __tag, const _Alloc& __a,
+ const tuple<_UElements...>&& __in)
+ : _Inherited(__tag, __a,
+ static_cast<const _Tuple_impl<0, _UElements...>&&>(__in))
+ { }
+#endif // C++23
+
// tuple assignment
_GLIBCXX20_CONSTEXPR
@@ -941,12 +1130,57 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+#if __cplusplus > 202002L
+ constexpr const tuple&
+ operator=(const tuple& __in) const
+ requires (is_copy_assignable_v<const _Elements> && ...)
+ {
+ this->_M_assign(__in);
+ return *this;
+ }
+
+ constexpr const tuple&
+ operator=(tuple&& __in) const
+ requires (is_assignable_v<const _Elements&, _Elements> && ...)
+ {
+ this->_M_assign(std::move(__in));
+ return *this;
+ }
+
+ template<typename... _UElements>
+ constexpr const tuple&
+ operator=(const tuple<_UElements...>& __in) const
+ requires (sizeof...(_Elements) == sizeof...(_UElements))
+ && (is_assignable_v<const _Elements&, const _UElements&> && ...)
+ {
+ this->_M_assign(__in);
+ return *this;
+ }
+
+ template<typename... _UElements>
+ constexpr const tuple&
+ operator=(tuple<_UElements...>&& __in) const
+ requires (sizeof...(_Elements) == sizeof...(_UElements))
+ && (is_assignable_v<const _Elements&, _UElements> && ...)
+ {
+ this->_M_assign(std::move(__in));
+ return *this;
+ }
+#endif // C++23
+
// tuple swap
_GLIBCXX20_CONSTEXPR
void
swap(tuple& __in)
noexcept(__and_<__is_nothrow_swappable<_Elements>...>::value)
{ _Inherited::_M_swap(__in); }
+
+#if __cplusplus > 202002L
+ constexpr void
+ swap(const tuple& __in) const
+ noexcept(__and_v<__is_nothrow_swappable<const _Elements>...>)
+ { _Inherited::_M_swap(__in); }
+#endif // C++23
};
#if __cpp_deduction_guides >= 201606
@@ -969,6 +1203,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public:
_GLIBCXX20_CONSTEXPR
void swap(tuple&) noexcept { /* no-op */ }
+#if __cplusplus > 202002L
+ constexpr void swap(const tuple&) const noexcept { /* no-op */ }
+#endif
// We need the default since we're going to define no-op
// allocator constructors.
tuple() = default;
@@ -1048,6 +1285,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static constexpr bool __is_alloc_arg()
{ return is_same<__remove_cvref_t<_U1>, allocator_arg_t>::value; }
+#if __cplusplus > 202002L
+ template<typename _U1, typename _U2>
+ static constexpr bool __constructible
+ = _TCC<true>::template __constructible<_U1, _U2>::value;
+
+ template<typename _U1, typename _U2>
+ static constexpr bool __convertible
+ = _TCC<true>::template __convertible<_U1, _U2>::value;
+#endif // C++23
+
public:
template<bool _Dummy = true,
_ImplicitDefaultCtor<_Dummy, _T1, _T2> = true>
@@ -1123,6 +1370,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(__nothrow_constructible<_U1, _U2>())
: _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in)) { }
+#if __cplusplus > 202002L
+ template<typename _U1, typename _U2>
+ requires __constructible<_U1&, _U2&>
+ explicit(!__convertible<_U1&, _U2&>)
+ constexpr
+ tuple(tuple<_U1, _U2>& __in)
+ noexcept(__nothrow_constructible<_U1&, _U2&>())
+ : _Inherited(static_cast<_Tuple_impl<0, _U1, _U2>&>(__in)) { }
+
+ template<typename _U1, typename _U2>
+ requires __constructible<const _U1, const _U2>
+ explicit(!__convertible<const _U1, const _U2>)
+ constexpr
+ tuple(const tuple<_U1, _U2>&& __in)
+ noexcept(__nothrow_constructible<const _U1, const _U2>())
+ : _Inherited(static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in)) { }
+#endif // C++23
+
template<typename _U1, typename _U2,
_ImplicitCtor<true, const _U1&, const _U2&> = true>
constexpr
@@ -1153,6 +1418,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _Inherited(std::forward<_U1>(__in.first),
std::forward<_U2>(__in.second)) { }
+#if __cplusplus > 202002L
+ template<typename _U1, typename _U2>
+ requires __constructible<_U1&, _U2&>
+ explicit(!__convertible<_U1&, _U2&>)
+ constexpr
+ tuple(pair<_U1, _U2>& __in)
+ noexcept(__nothrow_constructible<_U1&, _U2&>())
+ : _Inherited(__in.first, __in.second) { }
+
+ template<typename _U1, typename _U2>
+ requires __constructible<const _U1, const _U2>
+ explicit(!__convertible<const _U1, const _U2>)
+ constexpr
+ tuple(const pair<_U1, _U2>&& __in)
+ noexcept(__nothrow_constructible<const _U1, const _U2>())
+ : _Inherited(std::forward<const _U1>(__in.first),
+ std::forward<const _U2>(__in.second)) { }
+#endif // C++23
+
// Allocator-extended constructors.
template<typename _Alloc,
@@ -1236,6 +1520,28 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _Inherited(__tag, __a, static_cast<_Tuple_impl<0, _U1, _U2>&&>(__in))
{ }
+#if __cplusplus > 202002L
+ template<typename _Alloc, typename _U1, typename _U2>
+ requires __constructible<_U1&, _U2&>
+ explicit(!__convertible<_U1&, _U2&>)
+ constexpr
+ tuple(allocator_arg_t __tag, const _Alloc& __a,
+ tuple<_U1, _U2>& __in)
+ : _Inherited(__tag, __a,
+ static_cast<_Tuple_impl<0, _U1, _U2>&>(__in))
+ { }
+
+ template<typename _Alloc, typename _U1, typename _U2>
+ requires __constructible<const _U1, const _U2>
+ explicit(!__convertible<const _U1, const _U2>)
+ constexpr
+ tuple(allocator_arg_t __tag, const _Alloc& __a,
+ const tuple<_U1, _U2>&& __in)
+ : _Inherited(__tag, __a,
+ static_cast<const _Tuple_impl<0, _U1, _U2>&&>(__in))
+ { }
+#endif // C++23
+
template<typename _Alloc, typename _U1, typename _U2,
_ImplicitCtor<true, const _U1&, const _U2&> = true>
_GLIBCXX20_CONSTEXPR
@@ -1266,6 +1572,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _Inherited(__tag, __a, std::forward<_U1>(__in.first),
std::forward<_U2>(__in.second)) { }
+#if __cplusplus > 202002L
+ template<typename _Alloc, typename _U1, typename _U2>
+ requires __constructible<_U1&, _U2&>
+ explicit(!__convertible<_U1&, _U2&>)
+ constexpr
+ tuple(allocator_arg_t __tag, const _Alloc& __a,
+ pair<_U1, _U2>& __in)
+ : _Inherited(__tag, __a, __in.first, __in.second) { }
+
+ template<typename _Alloc, typename _U1, typename _U2>
+ requires __constructible<const _U1, const _U2>
+ explicit(!__convertible<const _U1, const _U2>)
+ constexpr
+ tuple(allocator_arg_t __tag, const _Alloc& __a, const pair<_U1, _U2>&& __in)
+ : _Inherited(__tag, __a, std::forward<const _U1>(__in.first),
+ std::forward<const _U2>(__in.second)) { }
+#endif // C++23
+
// Tuple assignment.
_GLIBCXX20_CONSTEXPR
@@ -1310,6 +1634,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+#if __cplusplus > 202002L
+ constexpr const tuple&
+ operator=(const tuple& __in) const
+ requires is_copy_assignable_v<const _T1> && is_copy_assignable_v<const _T2>
+ {
+ this->_M_assign(__in);
+ return *this;
+ }
+
+ constexpr const tuple&
+ operator=(tuple&& __in) const
+ requires is_assignable_v<const _T1&, _T1> && is_assignable_v<const _T2, _T2>
+ {
+ this->_M_assign(std::move(__in));
+ return *this;
+ }
+
+ template<typename _U1, typename _U2>
+ constexpr const tuple&
+ operator=(const tuple<_U1, _U2>& __in) const
+ requires is_assignable_v<const _T1&, const _U1&>
+ && is_assignable_v<const _T2&, const _U2&>
+ {
+ this->_M_assign(__in);
+ return *this;
+ }
+
+ template<typename _U1, typename _U2>
+ constexpr const tuple&
+ operator=(tuple<_U1, _U2>&& __in) const
+ requires is_assignable_v<const _T1&, _U1>
+ && is_assignable_v<const _T2&, _U2>
+ {
+ this->_M_assign(std::move(__in));
+ return *this;
+ }
+#endif // C++23
+
template<typename _U1, typename _U2>
_GLIBCXX20_CONSTEXPR
__enable_if_t<__assignable<const _U1&, const _U2&>(), tuple&>
@@ -1332,12 +1694,44 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return *this;
}
+#if __cplusplus > 202002L
+ template<typename _U1, typename _U2>
+ constexpr const tuple&
+ operator=(const pair<_U1, _U2>& __in) const
+ requires is_assignable_v<const _T1&, const _U1&>
+ && is_assignable_v<const _T2&, const _U2&>
+ {
+ this->_M_head(*this) = __in.first;
+ this->_M_tail(*this)._M_head(*this) = __in.second;
+ return *this;
+ }
+
+ template<typename _U1, typename _U2>
+ constexpr const tuple&
+ operator=(pair<_U1, _U2>&& __in) const
+ requires is_assignable_v<const _T1&, _U1>
+ && is_assignable_v<const _T2&, _U2>
+ {
+ this->_M_head(*this) = std::forward<_U1>(__in.first);
+ this->_M_tail(*this)._M_head(*this) = std::forward<_U2>(__in.second);
+ return *this;
+ }
+#endif // C++23
+
_GLIBCXX20_CONSTEXPR
void
swap(tuple& __in)
noexcept(__and_<__is_nothrow_swappable<_T1>,
__is_nothrow_swappable<_T2>>::value)
{ _Inherited::_M_swap(__in); }
+
+#if __cplusplus > 202002L
+ constexpr void
+ swap(const tuple& __in) const
+ noexcept(__and_v<__is_nothrow_swappable<const _T1>,
+ __is_nothrow_swappable<const _T2>>)
+ { _Inherited::_M_swap(__in); }
+#endif // C++23
};
@@ -1765,6 +2159,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
noexcept(noexcept(__x.swap(__y)))
{ __x.swap(__y); }
+#if __cplusplus > 202002L
+ template<typename... _Elements>
+ requires (is_swappable_v<const _Elements> && ...)
+ constexpr void
+ swap(const tuple<_Elements...>& __x, const tuple<_Elements...>& __y)
+ noexcept(noexcept(__x.swap(__y)))
+ { __x.swap(__y); }
+#endif // C++23
+
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
template<typename... _Elements>
_GLIBCXX20_CONSTEXPR
@@ -1889,6 +2292,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif // C++17
+#if __cplusplus > 202002L
+ template<typename... _TTypes, typename... _UTypes,
+ template<typename> class TQual, template<typename> class UQual>
+ requires requires { typename tuple<common_reference_t<TQual<_TTypes>, UQual<_UTypes>>...>; }
+ struct basic_common_reference<tuple<_TTypes...>, tuple<_UTypes...>, TQual, UQual>
+ { using type = tuple<common_reference_t<TQual<_TTypes>, UQual<_UTypes>>...>; };
+
+ template<typename... _TTypes, typename... _UTypes>
+ requires requires { typename tuple<common_type_t<_TTypes, _UTypes>...>; }
+ struct common_type<tuple<_TTypes...>, tuple<_UTypes...>>
+ { using type = tuple<common_type_t<_TTypes, _UTypes>...>; };
+#endif // C++23
+
/// @}
_GLIBCXX_END_NAMESPACE_VERSION