On Thu, 3 Jul 2025 at 15:19, Patrick Palka <ppa...@redhat.com> wrote:
>
> Tested on x86_64-pc-linux-gnu, does this look OK for trunk/15?

yes for both, thanks.

>
> -- >8 --
>
> In r15-4555-gf191c830154565 we proactively implemented the initial
> proposed resolution for LWG 4166 which was later revealed to be
> insufficient, since we must also require equality_comparable of the
> underlying iterators before concat_view could be common.
>
> This patch implements the updated P/R, requiring all underlying
> iterators to be forward (which implies equality_comparable) before
> making concat_view a common range, which fixes the testcase from
> this PR.
>
>         PR libstdc++/120934
>
> libstdc++-v3/ChangeLog:
>
>         * include/std/ranges (concat_view::end): Update condition
>         for returning an iterator instead of default_sentinel as
>         per the updated P/R for LWG 4166.
>         * testsuite/std/ranges/concat/1.cc (test05): New test.
> ---
>  libstdc++-v3/include/std/ranges               |  4 ++--
>  libstdc++-v3/testsuite/std/ranges/concat/1.cc | 13 +++++++++++++
>  2 files changed, 15 insertions(+), 2 deletions(-)
>
> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
> index f764aa7512e3..3a6710bd0ae1 100644
> --- a/libstdc++-v3/include/std/ranges
> +++ b/libstdc++-v3/include/std/ranges
> @@ -9735,7 +9735,7 @@ namespace ranges
>      end() requires (!(__detail::__simple_view<_Vs> && ...))
>      {
>        constexpr auto __n = sizeof...(_Vs);
> -      if constexpr ((semiregular<iterator_t<_Vs>> && ...)
> +      if constexpr (__detail::__all_forward<false, _Vs...>
>                     && common_range<_Vs...[__n - 1]>)
>         return _Iterator<false>(this, in_place_index<__n - 1>,
>                                 ranges::end(std::get<__n - 1>(_M_views)));
> @@ -9747,7 +9747,7 @@ namespace ranges
>      end() const requires (range<const _Vs> && ...) && 
> __detail::__concatable<const _Vs...>
>      {
>        constexpr auto __n = sizeof...(_Vs);
> -      if constexpr ((semiregular<iterator_t<const _Vs>> && ...)
> +      if constexpr (__detail::__all_forward<true, _Vs...>
>                     && common_range<const _Vs...[__n - 1]>)
>         return _Iterator<true>(this, in_place_index<__n - 1>,
>                                ranges::end(std::get<__n - 1>(_M_views)));
> diff --git a/libstdc++-v3/testsuite/std/ranges/concat/1.cc 
> b/libstdc++-v3/testsuite/std/ranges/concat/1.cc
> index 16721912a37d..f78ed08a610b 100644
> --- a/libstdc++-v3/testsuite/std/ranges/concat/1.cc
> +++ b/libstdc++-v3/testsuite/std/ranges/concat/1.cc
> @@ -99,6 +99,18 @@ test04()
>    using type = decltype(v);
>  }
>
> +void
> +test05()
> +{
> +  // PR libstdc++/120934 - views::concat is ill-formed depending on argument 
> order
> +  auto v1 = views::single(1);
> +  std::vector<int> vec = {2, 3};
> +  auto v2 = views::join(views::transform(vec, views::single));
> +
> +  static_assert( ranges::range<decltype(views::concat(v1, v2))> );
> +  static_assert( ranges::range<decltype(views::concat(v2, v1))> );
> +}
> +
>  int
>  main()
>  {
> @@ -107,4 +119,5 @@ main()
>    test02();
>    test03();
>    test04();
> +  test05();
>  }
> --
> 2.50.0.173.g8b6f19ccfc
>

Reply via email to