On Thu, 13 Mar 2025 at 03:54, Patrick Palka <ppa...@redhat.com> wrote: > > On Wed, 12 Mar 2025, Patrick Palka wrote: > > > On Wed, 12 Mar 2025, Patrick Palka wrote: > > > > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk/14 and > > > perhaps 13?
OK for trunk and 14 and 13. > > > > > > N.B. the use of a constrained auto instead of a separate static_assert > > > in the testcase is unfortunate but I opted for local consistency for > > > now. > > > > > > -- >8 -- > > > > > > 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 the 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()): Correct the ref_view branch. > > > * testsuite/std/ranges/adaptors/as_const/1.cc (test03): Extend > > > test. > > > --- > > > libstdc++-v3/include/std/ranges | 12 ++++++------ > > > .../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 c2a2d6f4e05..31d62454895 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(__r.base())); > > > > Whoops, just noticed that I got rid of the perfect forwarding of __r > > here for no good reason. It shouldn't matter since its base() member > > function is const, but consider the std::forward restored for > > consistency. > > Like so: > > -- >8 -- > > Subject: [PATCH v2] libstdc++: Fix ref_view branch of views::as_const > [PR119135] > > Tested on x86_64-pc-linux-gnu, does this look OK for trunk/14 and > perhaps 13? > > N.B. the use of a constrained auto instead of a separate static_assert > in the testcase is unfortunate but I opted for local consistency for > now. > > -- >8 -- > > 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()): Correct the ref_view branch. > * testsuite/std/ranges/adaptors/as_const/1.cc (test03): Extend > test. > --- > libstdc++-v3/include/std/ranges | 12 ++++++------ > .../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 c2a2d6f4e05..ef277b81bd3 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 c36786a8c5f..3f1f8eb1772 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 > -- > 2.49.0.rc1.37.ge969bc8759 >