On Tue, 18 Feb 2025 at 04:11, Patrick Palka <ppa...@redhat.com> wrote: > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk? > > -- >8 -- > > The original implementation was 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. > > The revision also simplifies the concat_view::end wording via C++26 > pack indexing, which GCC 15 and Clang 19/20 implement so we can use > it unconditionally here and remove the __last_is_common helper trait.
What about Clang 18 with -std=c++26? I'd be OK with making the ranges_concat macro depend on the one for pack indexing though. As I noted in bugzilla, the conct_view::iterator type should be named _Iterator > > PR libstdc++/115209 > > libstdc++-v3/ChangeLog: > > * 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 P2542R8. > (concat_view::iterator::operator-): Update constraints on > iter/sent overloads as per P2542R7. > --- > libstdc++-v3/include/std/ranges | 38 ++++++++++++++------------------- > 1 file changed, 16 insertions(+), 22 deletions(-) > > diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges > index 5c795a90fbc..22e0c9cae44 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<typename _Range, typename... _Rs> > - struct __last_is_common > - { static inline constexpr bool value = > __last_is_common<_Rs...>::value; }; > - > - template<typename _Range> > - 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<input_range... _Vs> > @@ -9726,13 +9722,11 @@ namespace ranges > constexpr auto > end() requires (!(__detail::__simple_view<_Vs> && ...)) > { > + constexpr auto __n = sizeof...(_Vs); > if constexpr ((semiregular<iterator_t<_Vs>> && ...) > - && __detail::__last_is_common<_Vs...>::value) > - { > - constexpr auto __n = sizeof...(_Vs); > - return iterator<false>(this, in_place_index<__n - 1>, > - ranges::end(std::get<__n - 1>(_M_views))); > - } > + && common_range<_Vs...[__n - 1]>) > + return iterator<false>(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<const _Vs> && ...) && > __detail::__concatable<const _Vs...> > { > + constexpr auto __n = sizeof...(_Vs); > if constexpr ((semiregular<iterator_t<const _Vs>> && ...) > - && __detail::__last_is_common<const _Vs...>::value) > - { > - constexpr auto __n = sizeof...(_Vs); > - return iterator<true>(this, in_place_index<__n - 1>, > - ranges::end(std::get<__n - 1>(_M_views))); > - } > + && common_range<const _Vs...[__n - 1]>) > + return iterator<true>(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<sentinel_t<__maybe_const_t<_Const, _Vs>>, > + iterator_t<__maybe_const_t<_Const, _Vs>>> > && ...) > + && __detail::__all_but_first_sized<__maybe_const_t<_Const, > _Vs>...>::value > { > return _S_invoke_with_runtime_index([&]<size_t _Ix>() -> > 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<sentinel_t<__maybe_const_t<_Const, _Vs>>, > + 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.48.1.356.g0394451348.dirty >