From 8543dc52d84662e3fc0b8b6ac5e98ce13ebe9ad9 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 19 Feb 2025 22:59:49 -0500 Subject: [PATCH] libstdc++: Sync concat_view with final P2542 revision [PR115209] Our concat_view implementation is accidentally based off of an older revision of the paper, P2542R7 instead of R8. As far as I can tell the only semantic change in the final revision is the relaxed constraints on the iterator's iter/sent operator- overloads, which this patch updates. This patch also simplifies the concat_view::end wording via C++26 pack indexing as per the final revision. In turn we make the availability of this library feature conditional on __cpp_pack_indexing. (Note pack indexing is implemented in GCC 15 and Clang 19). PR libstdc++/115209 libstdc++-v3/ChangeLog: * include/bits/version.def (ranges_concat): Depend on __cpp_pack_indexing. * include/bits/version.h: Regenerate. * include/std/ranges (__detail::__last_is_common): Remove. (__detail::__all_but_first_sized): New. (concat_view::end): Use C++26 pack indexing instead of __last_is_common as per R8 of P2542. (concat_view::iterator::operator-): Update constraints on iter/sent overloads as per R8 of P2542. Reviewed-by: Jonathan Wakely --- libstdc++-v3/include/bits/version.def | 1 + libstdc++-v3/include/bits/version.h | 2 +- libstdc++-v3/include/std/ranges | 38 +++++++++++---------------- 3 files changed, 18 insertions(+), 23 deletions(-) diff --git a/libstdc++-v3/include/bits/version.def b/libstdc++-v3/include/bits/version.def index 002e560dc0d2..e75befe7f4b1 100644 --- a/libstdc++-v3/include/bits/version.def +++ b/libstdc++-v3/include/bits/version.def @@ -1842,6 +1842,7 @@ ftms = { values = { v = 202403; cxxmin = 26; + extra_cond = "__cpp_pack_indexing"; }; }; diff --git a/libstdc++-v3/include/bits/version.h b/libstdc++-v3/include/bits/version.h index 70de189b1e0b..cd713ee54ea3 100644 --- a/libstdc++-v3/include/bits/version.h +++ b/libstdc++-v3/include/bits/version.h @@ -2036,7 +2036,7 @@ #undef __glibcxx_want_is_virtual_base_of #if !defined(__cpp_lib_ranges_concat) -# if (__cplusplus > 202302L) +# if (__cplusplus > 202302L) && (__cpp_pack_indexing) # define __glibcxx_ranges_concat 202403L # if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_concat) # define __cpp_lib_ranges_concat 202403L diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 5c795a90fbc2..22e0c9cae447 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -9683,12 +9683,8 @@ namespace ranges && __all_but_last_common<_Const, _Rs...>::value; template - struct __last_is_common - { static inline constexpr bool value = __last_is_common<_Rs...>::value; }; - - template - struct __last_is_common<_Range> - { static inline constexpr bool value = common_range<_Range>; }; + struct __all_but_first_sized + { static inline constexpr bool value = (sized_range<_Rs> && ...); }; } // namespace __detail template @@ -9726,13 +9722,11 @@ namespace ranges constexpr auto end() requires (!(__detail::__simple_view<_Vs> && ...)) { + constexpr auto __n = sizeof...(_Vs); if constexpr ((semiregular> && ...) - && __detail::__last_is_common<_Vs...>::value) - { - constexpr auto __n = sizeof...(_Vs); - return iterator(this, in_place_index<__n - 1>, - ranges::end(std::get<__n - 1>(_M_views))); - } + && common_range<_Vs...[__n - 1]>) + return iterator(this, in_place_index<__n - 1>, + ranges::end(std::get<__n - 1>(_M_views))); else return default_sentinel; } @@ -9740,13 +9734,11 @@ namespace ranges constexpr auto end() const requires (range && ...) && __detail::__concatable { + constexpr auto __n = sizeof...(_Vs); if constexpr ((semiregular> && ...) - && __detail::__last_is_common::value) - { - constexpr auto __n = sizeof...(_Vs); - return iterator(this, in_place_index<__n - 1>, - ranges::end(std::get<__n - 1>(_M_views))); - } + && common_range) + return iterator(this, in_place_index<__n - 1>, + ranges::end(std::get<__n - 1>(_M_views))); else return default_sentinel; } @@ -10128,8 +10120,9 @@ namespace ranges friend constexpr difference_type operator-(const iterator& __x, default_sentinel_t) - requires __detail::__concat_is_random_access<_Const, _Vs...> - && __detail::__last_is_common<__maybe_const_t<_Const, _Vs>...>::value + requires (sized_sentinel_for>, + iterator_t<__maybe_const_t<_Const, _Vs>>> && ...) + && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value { return _S_invoke_with_runtime_index([&]() -> difference_type { auto __dx = ranges::distance(std::get<_Ix>(__x._M_it), @@ -10148,8 +10141,9 @@ namespace ranges friend constexpr difference_type operator-(default_sentinel_t, const iterator& __x) - requires __detail::__concat_is_random_access<_Const, _Vs...> - && __detail::__last_is_common<__maybe_const_t<_Const, _Vs>...>::value + requires (sized_sentinel_for>, + iterator_t<__maybe_const_t<_Const, _Vs>>> && ...) + && __detail::__all_but_first_sized<__maybe_const_t<_Const, _Vs>...>::value { return -(__x - default_sentinel); } friend constexpr decltype(auto) -- 2.47.2