https://gcc.gnu.org/g:925a744efec5a630eb9bf49e755c554a884fda99

commit r14-11446-g925a744efec5a630eb9bf49e755c554a884fda99
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Mar 13 09:15:21 2025 -0400

    libstdc++: Fix ref_view branch of views::as_const [PR119135]
    
    Unlike for span<X> and empty_view<X>, the range_reference_t of
    ref_view<X> doesn't correspond to X.  This patch fixes the ref_view
    branch of views::as_const to correctly query its underlying range
    type X.
    
            PR libstdc++/119135
    
    libstdc++-v3/ChangeLog:
    
            * include/std/ranges: Include <utility>.
            (views::__detail::__is_ref_view): Replace with ...
            (views::__detail::__is_constable_ref_view): ... this.
            (views::_AsConst::operator()): Replace bogus use of element_type
            in the ref_view branch.
            * testsuite/std/ranges/adaptors/as_const/1.cc (test03): Extend
            test.
    
    Reviewed-by: Tomasz KamiƄski <tkami...@redhat.com>
    Reviewed-by: Jonathan Wakely <jwak...@redhat.com>
    (cherry picked from commit 50359c0a44381edb6dbd9359ef2ebdadbcc3ed42)

Diff:
---
 libstdc++-v3/include/std/ranges                          | 12 ++++++------
 libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc |  4 ++++
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index a966699479bb..c2dcb0265660 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -46,6 +46,7 @@
 #include <string_view>
 #include <tuple>
 #if __cplusplus > 202002L
+#include <utility>
 #include <variant>
 #endif
 #include <bits/ranges_util.h>
@@ -9297,10 +9298,11 @@ namespace views::__adaptor
     namespace __detail
     {
       template<typename _Tp>
-       inline constexpr bool __is_ref_view = false;
+       inline constexpr bool __is_constable_ref_view = false;
 
       template<typename _Range>
-       inline constexpr bool __is_ref_view<ref_view<_Range>> = true;
+       inline constexpr bool __is_constable_ref_view<ref_view<_Range>>
+         = constant_range<const _Range>;
 
       template<typename _Range>
        concept __can_as_const_view = requires { 
as_const_view(std::declval<_Range>()); };
@@ -9322,10 +9324,8 @@ namespace views::__adaptor
          return views::empty<const element_type>;
        else if constexpr (std::__detail::__is_span<_Tp>)
          return span<const element_type, 
_Tp::extent>(std::forward<_Range>(__r));
-       else if constexpr (__detail::__is_ref_view<_Tp>
-                          && constant_range<const element_type>)
-         return ref_view(static_cast<const element_type&>
-                         (std::forward<_Range>(__r).base()));
+       else if constexpr (__detail::__is_constable_ref_view<_Tp>)
+         return ref_view(std::as_const(std::forward<_Range>(__r).base()));
        else if constexpr (is_lvalue_reference_v<_Range>
                           && constant_range<const _Tp>
                           && !view<_Tp>)
diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc 
b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc
index c36786a8c5fa..3f1f8eb17726 100644
--- a/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc
+++ b/libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc
@@ -63,6 +63,10 @@ test03()
   std::vector<int> v;
   std::same_as<ranges::ref_view<const std::vector<int>>>
     auto r = views::as_const(v);
+
+  // PR libstdc++/119135
+  std::same_as<ranges::ref_view<const std::vector<int>>>
+    auto r2 = views::as_const(views::all(v));
 }
 
 int

Reply via email to