https://gcc.gnu.org/g:612690936f5ddd122b60cf843cb4f40ae7ede436

commit r15-9917-g612690936f5ddd122b60cf843cb4f40ae7ede436
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Jul 3 10:55:17 2025 -0400

    libstdc++: Update LWG 4166 changes to concat_view::end() [PR120934]
    
    In r15-4555-gf191c830154565 we proactively implemented the initial
    proposed resolution for LWG 4166 which later turned out to be
    insufficient, since we must also require equality_comparable of the
    underlying iterators before concat_view could be a common range.
    
    This patch implements the updated P/R, requiring all underlying
    iterators to be forward (which implies equality_comparable) before
    making concat_view common, which fixes the testcase from this PR.
    
            PR libstdc++/120934
    
    libstdc++-v3/ChangeLog:
    
            * include/std/ranges (concat_view::end): Refine 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.
    
    Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
    (cherry picked from commit c5a17e92ebf0c6f3887fb5698a1114a3fdf50576)

Diff:
---
 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 210ac8274fc1..87560dddd65d 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();
 }

Reply via email to