diff options
Diffstat (limited to 'libstdc++-v3/include/std')
-rw-r--r-- | libstdc++-v3/include/std/concepts | 11 | ||||
-rw-r--r-- | libstdc++-v3/include/std/map | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/std/ranges | 48 | ||||
-rw-r--r-- | libstdc++-v3/include/std/tuple | 325 | ||||
-rw-r--r-- | libstdc++-v3/include/std/unordered_map | 1 | ||||
-rw-r--r-- | libstdc++-v3/include/std/utility | 1 |
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) |