aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r--libstdc++-v3/include/std/concepts11
-rw-r--r--libstdc++-v3/include/std/map1
-rw-r--r--libstdc++-v3/include/std/ranges48
-rw-r--r--libstdc++-v3/include/std/tuple325
-rw-r--r--libstdc++-v3/include/std/unordered_map1
-rw-r--r--libstdc++-v3/include/std/utility1
6 files changed, 311 insertions, 76 deletions
diff --git a/libstdc++-v3/include/std/concepts b/libstdc++-v3/include/std/concepts
index 66ed371..4f3e059 100644
--- a/libstdc++-v3/include/std/concepts
+++ b/libstdc++-v3/include/std/concepts
@@ -62,6 +62,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
concept same_as
= __detail::__same_as<_Tp, _Up> && __detail::__same_as<_Up, _Tp>;
+ namespace __detail
+ {
+ template<typename _Tp, typename _Up>
+ concept __different_from
+ = !same_as<remove_cvref_t<_Tp>, remove_cvref_t<_Up>>;
+ } // namespace __detail
+
/// [concept.derived], concept derived_from
template<typename _Derived, typename _Base>
concept derived_from = __is_base_of(_Base, _Derived)
@@ -185,8 +192,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp, typename _Up>
concept __adl_swap
- = (__detail::__class_or_enum<remove_reference_t<_Tp>>
- || __detail::__class_or_enum<remove_reference_t<_Up>>)
+ = (std::__detail::__class_or_enum<remove_reference_t<_Tp>>
+ || std::__detail::__class_or_enum<remove_reference_t<_Up>>)
&& requires(_Tp&& __t, _Up&& __u) {
swap(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u));
};
diff --git a/libstdc++-v3/include/std/map b/libstdc++-v3/include/std/map
index dcfd222..4a96e59 100644
--- a/libstdc++-v3/include/std/map
+++ b/libstdc++-v3/include/std/map
@@ -74,6 +74,7 @@
#define __glibcxx_want_map_try_emplace
#define __glibcxx_want_node_extract
#define __glibcxx_want_nonmember_container_access
+#define __glibcxx_want_tuple_like
#include <bits/version.h>
#if __cplusplus >= 201703L
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index f2413ba..7d73985 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -2389,11 +2389,7 @@ namespace views::__adaptor
inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
= true;
- template<typename _Range>
- inline constexpr bool __is_subrange = false;
-
- template<typename _Iter, typename _Sent, subrange_kind _Kind>
- inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
+ using ranges::__detail::__is_subrange;
template<typename _Range>
inline constexpr bool __is_iota_view = false;
@@ -4166,6 +4162,10 @@ namespace views::__adaptor
namespace __detail
{
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _Tp, size_t _Nm>
+ concept __has_tuple_element = __tuple_like<_Tp> && _Nm < tuple_size_v<_Tp>;
+#else
template<typename _Tp, size_t _Nm>
concept __has_tuple_element = requires(_Tp __t)
{
@@ -4175,6 +4175,7 @@ namespace views::__adaptor
{ std::get<_Nm>(__t) }
-> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
};
+#endif
template<typename _Tp, size_t _Nm>
concept __returnable_element
@@ -4559,23 +4560,12 @@ namespace views::__adaptor
|| (!(bidirectional_range<_Rs> && ...) && (common_range<_Rs> && ...))
|| ((random_access_range<_Rs> && ...) && (sized_range<_Rs> && ...));
- template<typename... _Ts>
- struct __tuple_or_pair
- { using type = std::tuple<_Ts...>; };
-
- template<typename _Tp, typename _Up>
- struct __tuple_or_pair<_Tp, _Up>
- { using type = pair<_Tp, _Up>; };
-
- template<typename... _Ts>
- using __tuple_or_pair_t = typename __tuple_or_pair<_Ts...>::type;
-
template<typename _Fp, typename _Tuple>
constexpr auto
__tuple_transform(_Fp&& __f, _Tuple&& __tuple)
{
return std::apply([&]<typename... _Ts>(_Ts&&... __elts) {
- return __tuple_or_pair_t<invoke_result_t<_Fp&, _Ts>...>
+ return tuple<invoke_result_t<_Fp&, _Ts>...>
(std::__invoke(__f, std::forward<_Ts>(__elts))...);
}, std::forward<_Tuple>(__tuple));
}
@@ -4696,7 +4686,7 @@ namespace views::__adaptor
#ifdef __clang__ // LLVM-61763 workaround
public:
#endif
- __detail::__tuple_or_pair_t<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
+ tuple<iterator_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_current;
constexpr explicit
_Iterator(decltype(_M_current) __current)
@@ -4728,7 +4718,7 @@ namespace views::__adaptor
// iterator_category defined in __zip_view_iter_cat
using iterator_concept = decltype(_S_iter_concept());
using value_type
- = __detail::__tuple_or_pair_t<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
+ = tuple<range_value_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
using difference_type
= common_type_t<range_difference_t<__detail::__maybe_const_t<_Const, _Vs>>...>;
@@ -4900,7 +4890,7 @@ namespace views::__adaptor
template<bool _Const>
class zip_view<_Vs...>::_Sentinel
{
- __detail::__tuple_or_pair_t<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
+ tuple<sentinel_t<__detail::__maybe_const_t<_Const, _Vs>>...> _M_end;
constexpr explicit
_Sentinel(decltype(_M_end) __end)
@@ -8325,8 +8315,7 @@ namespace views::__adaptor
&& __detail::__cartesian_product_is_common<_First, _Vs...>)
{
auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
- using _Ret = __detail::__tuple_or_pair_t<iterator_t<_First>,
- iterator_t<_Vs>...>;
+ using _Ret = tuple<iterator_t<_First>, iterator_t<_Vs>...>;
bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
auto& __first = std::get<0>(_M_bases);
return _Ret{(__empty_tail
@@ -8342,8 +8331,7 @@ namespace views::__adaptor
end() const requires __detail::__cartesian_product_is_common<const _First, const _Vs...>
{
auto __its = [this]<size_t... _Is>(index_sequence<_Is...>) {
- using _Ret = __detail::__tuple_or_pair_t<iterator_t<const _First>,
- iterator_t<const _Vs>...>;
+ using _Ret = tuple<iterator_t<const _First>, iterator_t<const _Vs>...>;
bool __empty_tail = (ranges::empty(std::get<1 + _Is>(_M_bases)) || ...);
auto& __first = std::get<0>(_M_bases);
return _Ret{(__empty_tail
@@ -8416,8 +8404,8 @@ namespace views::__adaptor
{
using _Parent = __maybe_const_t<_Const, cartesian_product_view>;
_Parent* _M_parent = nullptr;
- __detail::__tuple_or_pair_t<iterator_t<__maybe_const_t<_Const, _First>>,
- iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
+ tuple<iterator_t<__maybe_const_t<_Const, _First>>,
+ iterator_t<__maybe_const_t<_Const, _Vs>>...> _M_current;
constexpr
_Iterator(_Parent& __parent, decltype(_M_current) __current)
@@ -8444,11 +8432,11 @@ namespace views::__adaptor
using iterator_category = input_iterator_tag;
using iterator_concept = decltype(_S_iter_concept());
using value_type
- = __detail::__tuple_or_pair_t<range_value_t<__maybe_const_t<_Const, _First>>,
- range_value_t<__maybe_const_t<_Const, _Vs>>...>;
+ = tuple<range_value_t<__maybe_const_t<_Const, _First>>,
+ range_value_t<__maybe_const_t<_Const, _Vs>>...>;
using reference
- = __detail::__tuple_or_pair_t<range_reference_t<__maybe_const_t<_Const, _First>>,
- range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
+ = tuple<range_reference_t<__maybe_const_t<_Const, _First>>,
+ range_reference_t<__maybe_const_t<_Const, _Vs>>...>;
using difference_type = decltype(cartesian_product_view::_S_difference_type());
_Iterator() = default;
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index be92f1e..9c89c13 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -50,6 +50,7 @@
#define __glibcxx_want_apply
#define __glibcxx_want_make_from_tuple
#define __glibcxx_want_ranges_zip
+#define __glibcxx_want_tuple_like
#include <bits/version.h>
namespace std _GLIBCXX_VISIBILITY(default)
@@ -246,6 +247,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Head _M_head_impl;
};
+#if __cpp_lib_tuple_like // >= C++23
+ struct __tuple_like_tag_t { explicit __tuple_like_tag_t() = default; };
+
+ // These forward declarations are used by the operator<=> overload for
+ // tuple-like types.
+ template<typename _Cat, typename _Tp, typename _Up>
+ constexpr _Cat
+ __tuple_cmp(const _Tp&, const _Up&, index_sequence<>);
+
+ template<typename _Cat, typename _Tp, typename _Up,
+ size_t _Idx0, size_t... _Idxs>
+ constexpr _Cat
+ __tuple_cmp(const _Tp& __t, const _Up& __u,
+ index_sequence<_Idx0, _Idxs...>);
+#endif // C++23
+
/**
* Contains the actual implementation of the @c tuple template, stored
* as a recursive inheritance hierarchy from the first element (most
@@ -342,6 +359,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _UTuple, size_t... _Is>
+ constexpr
+ _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<_Is...>)
+ : _Tuple_impl(std::get<_Is>(std::forward<_UTuple>(__u))...)
+ { }
+#endif // C++23
+
template<typename _Alloc>
_GLIBCXX20_CONSTEXPR
_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
@@ -428,6 +453,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _Alloc, typename _UTuple, size_t... _Is>
+ constexpr
+ _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag, const _Alloc& __a,
+ _UTuple&& __u, index_sequence<_Is...>)
+ : _Tuple_impl(__tag, __a, std::get<_Is>(std::forward<_UTuple>(__u))...)
+ { }
+#endif // C++23
+
template<typename... _UElements>
_GLIBCXX20_CONSTEXPR
void
@@ -470,6 +504,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _UTuple>
+ constexpr void
+ _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u)
+ {
+ _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u));
+ _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));
+ }
+
+ template<typename _UTuple>
+ constexpr void
+ _M_assign(__tuple_like_tag_t __tag, _UTuple&& __u) const
+ {
+ _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u));
+ _M_tail(*this)._M_assign(__tag, std::forward<_UTuple>(__u));
+ }
+#endif // C++23
+
protected:
_GLIBCXX20_CONSTEXPR
void
@@ -563,6 +615,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _UTuple>
+ constexpr
+ _Tuple_impl(__tuple_like_tag_t, _UTuple&& __u, index_sequence<0>)
+ : _Tuple_impl(std::get<0>(std::forward<_UTuple>(__u)))
+ { }
+#endif // C++23
+
template<typename _Alloc>
_GLIBCXX20_CONSTEXPR
_Tuple_impl(allocator_arg_t __tag, const _Alloc& __a)
@@ -633,6 +693,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ }
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _Alloc, typename _UTuple>
+ constexpr
+ _Tuple_impl(__tuple_like_tag_t, allocator_arg_t __tag, const _Alloc& __a,
+ _UTuple&& __u, index_sequence<0>)
+ : _Tuple_impl(__tag, __a, std::get<0>(std::forward<_UTuple>(__u)))
+ { }
+#endif // C++23
+
template<typename _UHead>
_GLIBCXX20_CONSTEXPR
void
@@ -667,6 +736,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _UTuple>
+ constexpr void
+ _M_assign(__tuple_like_tag_t, _UTuple&& __u)
+ { _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }
+
+ template<typename _UTuple>
+ constexpr void
+ _M_assign(__tuple_like_tag_t, _UTuple&& __u) const
+ { _M_head(*this) = std::get<_Idx>(std::forward<_UTuple>(__u)); }
+#endif // C++23
+
protected:
_GLIBCXX20_CONSTEXPR
void
@@ -846,6 +927,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
}
+#if __cpp_lib_tuple_like // >= C++23
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4045. tuple can create dangling references from tuple-like
+ template<typename _UTuple>
+ static consteval bool
+ __dangles_from_tuple_like()
+ {
+ return []<size_t... _Is>(index_sequence<_Is...>) {
+ return __dangles<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
+ }(index_sequence_for<_Elements...>{});
+ }
+
+ template<typename _UTuple>
+ static consteval bool
+ __constructible_from_tuple_like()
+ {
+ return []<size_t... _Is>(index_sequence<_Is...>) {
+ return __constructible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
+ }(index_sequence_for<_Elements...>{});
+ }
+
+ template<typename _UTuple>
+ static consteval bool
+ __convertible_from_tuple_like()
+ {
+ return []<size_t... _Is>(index_sequence<_Is...>) {
+ return __convertible<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
+ }(index_sequence_for<_Elements...>{});
+ }
+#endif // C++23
+
public:
constexpr
explicit(!(__is_implicitly_default_constructible_v<_Elements> && ...))
@@ -1016,10 +1128,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple(const pair<_U1, _U2>&&) = delete;
#endif // C++23
-#if 0 && __cpp_lib_tuple_like // >= C++23
- template<__tuple_like _UTuple>
- constexpr explicit(...)
- tuple(_UTuple&& __u);
+#if __cpp_lib_tuple_like // >= C++23
+ template<__eligible_tuple_like<tuple> _UTuple>
+ requires (__constructible_from_tuple_like<_UTuple>())
+ && (!__use_other_ctor<_UTuple>())
+ && (!__dangles_from_tuple_like<_UTuple>())
+ constexpr explicit(!__convertible_from_tuple_like<_UTuple>())
+ tuple(_UTuple&& __u)
+ : _Inherited(__tuple_like_tag_t{},
+ std::forward<_UTuple>(__u),
+ index_sequence_for<_Elements...>{})
+ { }
+
+ template<__eligible_tuple_like<tuple> _UTuple>
+ requires (__constructible_from_tuple_like<_UTuple>())
+ && (!__use_other_ctor<_UTuple>())
+ && (__dangles_from_tuple_like<_UTuple>())
+ tuple(_UTuple&&) = delete;
#endif // C++23
// Allocator-extended constructors.
@@ -1202,10 +1327,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
tuple(allocator_arg_t, const _Alloc&, const pair<_U1, _U2>&&) = delete;
#endif // C++23
-#if 0 && __cpp_lib_tuple_like // >= C++23
- template<typename _Alloc, __tuple_like _UTuple>
- constexpr explicit(...)
- tuple(allocator_arg_t __tag, const _Alloc& __a, _UTuple&& __u);
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _Alloc, __eligible_tuple_like<tuple> _UTuple>
+ requires (__constructible_from_tuple_like<_UTuple>())
+ && (!__use_other_ctor<_UTuple>())
+ && (!__dangles_from_tuple_like<_UTuple>())
+ constexpr explicit(!__convertible_from_tuple_like<_UTuple>())
+ tuple(allocator_arg_t __tag, const _Alloc& __a, _UTuple&& __u)
+ : _Inherited(__tuple_like_tag_t{},
+ __tag, __a, std::forward<_UTuple>(__u),
+ index_sequence_for<_Elements...>{})
+ { }
+
+ template<typename _Alloc, __eligible_tuple_like<tuple> _UTuple>
+ requires (__constructible_from_tuple_like<_UTuple>())
+ && (!__use_other_ctor<_UTuple>())
+ && (__dangles_from_tuple_like<_UTuple>())
+ tuple(allocator_arg_t, const _Alloc&, _UTuple&&) = delete;
#endif // C++23
#else // !(concepts && conditional_explicit)
@@ -1539,6 +1677,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif // C++23
+#if __cpp_lib_tuple_like // >= C++23
+ template<typename _UTuple>
+ static consteval bool
+ __assignable_from_tuple_like()
+ {
+ return []<size_t... _Is>(index_sequence<_Is...>) {
+ return __assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
+ }(index_sequence_for<_Elements...>{});
+ }
+
+ template<typename _UTuple>
+ static consteval bool
+ __const_assignable_from_tuple_like()
+ {
+ return []<size_t... _Is>(index_sequence<_Is...>) {
+ return __const_assignable<decltype(std::get<_Is>(std::declval<_UTuple>()))...>();
+ }(index_sequence_for<_Elements...>{});
+ }
+#endif // C++23
+
public:
tuple& operator=(const tuple& __u) = delete;
@@ -1661,14 +1819,59 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif // C++23
-#if 0 && __cpp_lib_tuple_like // >= C++23
- template<__tuple_like _UTuple>
+#if __cpp_lib_tuple_like // >= C++23
+ template<__eligible_tuple_like<tuple> _UTuple>
+ requires (__assignable_from_tuple_like<_UTuple>())
constexpr tuple&
- operator=(_UTuple&& __u);
+ operator=(_UTuple&& __u)
+ {
+ this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));
+ return *this;
+ }
+
+ template<__eligible_tuple_like<tuple> _UTuple>
+ requires (__const_assignable_from_tuple_like<_UTuple>())
+ constexpr const tuple&
+ operator=(_UTuple&& __u) const
+ {
+ this->_M_assign(__tuple_like_tag_t{}, std::forward<_UTuple>(__u));
+ return *this;
+ }
template<__tuple_like _UTuple>
- constexpr tuple&
- operator=(_UTuple&& __u) const;
+ requires (!__is_tuple_v<_UTuple>)
+ friend constexpr bool
+ operator==(const tuple& __t, const _UTuple& __u)
+ {
+ static_assert(sizeof...(_Elements) == tuple_size_v<_UTuple>,
+ "tuple objects can only be compared if they have equal sizes.");
+ return [&]<size_t... _Is>(index_sequence<_Is...>) {
+ return (bool(std::get<_Is>(__t) == std::get<_Is>(__u))
+ && ...);
+ }(index_sequence_for<_Elements...>{});
+ }
+
+ template<__tuple_like _UTuple,
+ typename = make_index_sequence<tuple_size_v<_UTuple>>>
+ struct __tuple_like_common_comparison_category;
+
+ template<__tuple_like _UTuple, size_t... _Is>
+ requires requires
+ { typename void_t<__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>; }
+ struct __tuple_like_common_comparison_category<_UTuple, index_sequence<_Is...>>
+ {
+ using type = common_comparison_category_t
+ <__detail::__synth3way_t<_Elements, tuple_element_t<_Is, _UTuple>>...>;
+ };
+
+ template<__tuple_like _UTuple>
+ requires (!__is_tuple_v<_UTuple>)
+ friend constexpr typename __tuple_like_common_comparison_category<_UTuple>::type
+ operator<=>(const tuple& __t, const _UTuple& __u)
+ {
+ using _Cat = typename __tuple_like_common_comparison_category<_UTuple>::type;
+ return std::__tuple_cmp<_Cat>(__t, __u, index_sequence_for<_Elements...>());
+ }
#endif // C++23
#else // ! (concepts && consteval)
@@ -2433,27 +2636,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
forward_as_tuple(_Elements&&... __args) noexcept
{ return tuple<_Elements&&...>(std::forward<_Elements>(__args)...); }
- // Declarations of std::array and its std::get overloads, so that
- // std::tuple_cat can use them if <tuple> is included before <array>.
-
- template<typename _Tp, size_t _Nm> struct array;
-
- template<size_t _Int, typename _Tp, size_t _Nm>
- constexpr _Tp&
- get(array<_Tp, _Nm>&) noexcept;
-
- template<size_t _Int, typename _Tp, size_t _Nm>
- constexpr _Tp&&
- get(array<_Tp, _Nm>&&) noexcept;
-
- template<size_t _Int, typename _Tp, size_t _Nm>
- constexpr const _Tp&
- get(const array<_Tp, _Nm>&) noexcept;
-
- template<size_t _Int, typename _Tp, size_t _Nm>
- constexpr const _Tp&&
- get(const array<_Tp, _Nm>&&) noexcept;
-
/// @cond undocumented
template<size_t, typename, typename, size_t>
struct __make_tuple_impl;
@@ -2569,8 +2751,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @endcond
/// Create a `tuple` containing all elements from multiple tuple-like objects
+#if __cpp_lib_tuple_like // >= C++23
+ template<__tuple_like... _Tpls>
+#else
template<typename... _Tpls, typename = typename
enable_if<__and_<__is_tuple_like<_Tpls>...>::value>::type>
+#endif
constexpr auto
tuple_cat(_Tpls&&... __tpls)
-> typename __tuple_cat_result<_Tpls...>::__type
@@ -2722,7 +2908,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::get<_Idx>(std::forward<_Tuple>(__t))...);
}
+#if __cpp_lib_tuple_like // >= C++23
+ template <typename _Fn, __tuple_like _Tuple>
+#else
template <typename _Fn, typename _Tuple>
+#endif
constexpr decltype(auto)
apply(_Fn&& __f, _Tuple&& __t)
noexcept(__unpack_std_tuple<is_nothrow_invocable, _Fn, _Tuple>)
@@ -2741,7 +2931,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__make_from_tuple_impl(_Tuple&& __t, index_sequence<_Idx...>)
{ return _Tp(std::get<_Idx>(std::forward<_Tuple>(__t))...); }
+#if __cpp_lib_tuple_like // >= C++23
+ template <typename _Tp, __tuple_like _Tuple>
+#else
template <typename _Tp, typename _Tuple>
+#endif
constexpr _Tp
make_from_tuple(_Tuple&& __t)
noexcept(__unpack_std_tuple<is_nothrow_constructible, _Tp, _Tuple>)
@@ -2759,17 +2953,60 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
#endif
-#if __cpp_lib_ranges_zip // >= C++23
- template<typename... _TTypes, typename... _UTypes,
+#if __cpp_lib_tuple_like // >= C++23
+ template<__tuple_like _TTuple, __tuple_like _UTuple,
+ template<typename> class _TQual, template<typename> class _UQual,
+ typename = make_index_sequence<tuple_size_v<_TTuple>>>
+ struct __tuple_like_common_reference;
+
+ template<__tuple_like _TTuple, __tuple_like _UTuple,
+ template<typename> class _TQual, template<typename> class _UQual,
+ size_t... _Is>
+ requires requires
+ { typename tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,
+ _UQual<tuple_element_t<_Is, _UTuple>>>...>; }
+ struct __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual, index_sequence<_Is...>>
+ {
+ using type = tuple<common_reference_t<_TQual<tuple_element_t<_Is, _TTuple>>,
+ _UQual<tuple_element_t<_Is, _UTuple>>>...>;
+ };
+
+ template<__tuple_like _TTuple, __tuple_like _UTuple,
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>...>; };
+ requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)
+ && is_same_v<_TTuple, decay_t<_TTuple>>
+ && is_same_v<_UTuple, decay_t<_UTuple>>
+ && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)
+ && requires { typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type; }
+ struct basic_common_reference<_TTuple, _UTuple, _TQual, _UQual>
+ {
+ using type = typename __tuple_like_common_reference<_TTuple, _UTuple, _TQual, _UQual>::type;
+ };
+
+ template<__tuple_like _TTuple, __tuple_like _UTuple,
+ typename = make_index_sequence<tuple_size_v<_TTuple>>>
+ struct __tuple_like_common_type;
+
+ template<__tuple_like _TTuple, __tuple_like _UTuple, size_t... _Is>
+ requires requires
+ { typename tuple<common_type_t<tuple_element_t<_Is, _TTuple>,
+ tuple_element_t<_Is, _UTuple>>...>; }
+ struct __tuple_like_common_type<_TTuple, _UTuple, index_sequence<_Is...>>
+ {
+ using type = tuple<common_type_t<tuple_element_t<_Is, _TTuple>,
+ tuple_element_t<_Is, _UTuple>>...>;
+ };
+
+ template<__tuple_like _TTuple, __tuple_like _UTuple>
+ requires (__is_tuple_v<_TTuple> || __is_tuple_v<_UTuple>)
+ && is_same_v<_TTuple, decay_t<_TTuple>>
+ && is_same_v<_UTuple, decay_t<_UTuple>>
+ && (tuple_size_v<_TTuple> == tuple_size_v<_UTuple>)
+ && requires { typename __tuple_like_common_type<_TTuple, _UTuple>::type; }
+ struct common_type<_TTuple, _UTuple>
+ {
+ using type = typename __tuple_like_common_type<_TTuple, _UTuple>::type;
+ };
#endif // C++23
/// @}
diff --git a/libstdc++-v3/include/std/unordered_map b/libstdc++-v3/include/std/unordered_map
index efad0ce..ea6129d 100644
--- a/libstdc++-v3/include/std/unordered_map
+++ b/libstdc++-v3/include/std/unordered_map
@@ -51,6 +51,7 @@
#define __glibcxx_want_node_extract
#define __glibcxx_want_nonmember_container_access
#define __glibcxx_want_unordered_map_try_emplace
+#define __glibcxx_want_tuple_like
#include <bits/version.h>
#if __cplusplus >= 201703L
diff --git a/libstdc++-v3/include/std/utility b/libstdc++-v3/include/std/utility
index f113d572..212513f 100644
--- a/libstdc++-v3/include/std/utility
+++ b/libstdc++-v3/include/std/utility
@@ -92,6 +92,7 @@
#define __glibcxx_want_tuple_element_t
#define __glibcxx_want_tuples_by_type
#define __glibcxx_want_unreachable
+#define __glibcxx_want_tuple_like
#include <bits/version.h>
namespace std _GLIBCXX_VISIBILITY(default)