aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2025-03-13 09:15:21 -0400
committerPatrick Palka <ppalka@redhat.com>2025-03-13 09:15:21 -0400
commit50359c0a44381edb6dbd9359ef2ebdadbcc3ed42 (patch)
tree72b6ddb8034e770f9ce8fcfb11d244ea510501b8
parente5d54c33a257b3f7137f8408592df009dffb5711 (diff)
downloadgcc-50359c0a44381edb6dbd9359ef2ebdadbcc3ed42.zip
gcc-50359c0a44381edb6dbd9359ef2ebdadbcc3ed42.tar.gz
gcc-50359c0a44381edb6dbd9359ef2ebdadbcc3ed42.tar.bz2
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 <tkaminsk@redhat.com> Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
-rw-r--r--libstdc++-v3/include/std/ranges12
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/as_const/1.cc4
2 files changed, 10 insertions, 6 deletions
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index c2a2d6f..ef277b8 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -48,6 +48,7 @@
#include <string_view>
#include <tuple>
#if __cplusplus > 202002L
+#include <utility>
#include <variant>
#endif
#include <bits/ranges_util.h>
@@ -9324,10 +9325,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>()); };
@@ -9349,10 +9351,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 c36786a..3f1f8eb 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