On Wed, 19 Feb 2025, Jonathan Wakely wrote:
> On Tue, 18 Feb 2025 at 04:11, Patrick Palka <[email protected]> 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.
Sounds good. Clang 18 doesn't implement pack indexing, so it'd
otherwise break <ranges> in C++26 there.
>
> As I noted in bugzilla, the conct_view::iterator type should be named
> _Iterator
Will fix
>
>
> >
> > 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
> >
>
>