On Wed, 19 Feb 2025 at 14:57, Patrick Palka <ppa...@redhat.com> wrote:
>
> On Wed, 19 Feb 2025, Patrick Palka wrote:
>
> > On Wed, 19 Feb 2025, Jonathan Wakely wrote:
> >
> > > 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.
> >
> > Sounds good.  Clang 18 doesn't implement pack indexing, so it'd
> > otherwise break <ranges> in C++26 there.
>
> Like so?

OK for trunk, thanks.

>
> -- >8 --
>
> Subject: [PATCH] libstdc++: Sync concat_view with final P2542 revision
>  [PR115209]
>
> 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 is reflected here.  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.
> ---
>  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 002e560dc0d..e75befe7f4b 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 70de189b1e0..cd713ee54ea 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 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.385.ga554262210.dirty
>
>
> >
> > >
> > > 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
> > > >
> > >
> > >
> >
>

Reply via email to