On Mon, 14 Oct 2024, Jonathan Wakely wrote: > Tested x86_64-linux. > > -- >8 -- > > LWG 3798 modified the iterator_category of the iterator types for > transform_view, join_with_view, zip_transform_view and > adjacent_transform_view, to allow the iterator's reference type to be an > rvalue reference. > > libstdc++-v3/ChangeLog: > > PR libstdc++/106676 > * include/bits/iterator_concepts.h (__cpp17_fwd_iterator): Use > is_reference instead of is_value_reference. > rvalue references. > * include/std/ranges (transform_view:__iter_cat::_S_iter_cat): > Likewise. > (zip_transform_view::__iter_cat::_S_iter_cat): Likewise. > (adjacent_transform_view::__iter_cat::_S_iter_cat): Likewise. > (join_with_view::__iter_cat::_S_iter_cat): Likewise. > * testsuite/std/ranges/adaptors/transform.cc: Check > iterator_category when the transformation function returns an > rvalue reference type. > --- > libstdc++-v3/include/bits/iterator_concepts.h | 4 +++- > libstdc++-v3/include/std/ranges | 16 ++++++++++++---- > .../testsuite/std/ranges/adaptors/transform.cc | 16 ++++++++++++++++ > 3 files changed, 31 insertions(+), 5 deletions(-) > > diff --git a/libstdc++-v3/include/bits/iterator_concepts.h > b/libstdc++-v3/include/bits/iterator_concepts.h > index 490a362cdf1..669d3ddfd1e 100644 > --- a/libstdc++-v3/include/bits/iterator_concepts.h > +++ b/libstdc++-v3/include/bits/iterator_concepts.h > @@ -333,10 +333,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > typename incrementable_traits<_Iter>::difference_type>; > }; > > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 3798. Rvalue reference and iterator_category > template<typename _Iter> > concept __cpp17_fwd_iterator = __cpp17_input_iterator<_Iter> > && constructible_from<_Iter> > - && is_lvalue_reference_v<iter_reference_t<_Iter>> > + && is_reference_v<iter_reference_t<_Iter>> > && same_as<remove_cvref_t<iter_reference_t<_Iter>>, > typename indirectly_readable_traits<_Iter>::value_type> > && requires(_Iter __it) > diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges > index f0d81cbea0c..941189d65c3 100644 > --- a/libstdc++-v3/include/std/ranges > +++ b/libstdc++-v3/include/std/ranges > @@ -1892,7 +1892,9 @@ namespace views::__adaptor > using _Fpc = __detail::__maybe_const_t<_Const, _Fp>; > using _Base = transform_view::_Base<_Const>; > using _Res = invoke_result_t<_Fpc&, range_reference_t<_Base>>; > - if constexpr (is_lvalue_reference_v<_Res>) > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 3798. Rvalue reference and iterator_category > + if constexpr (is_reference_v<_Res>) > { > using _Cat > = typename > iterator_traits<iterator_t<_Base>>::iterator_category; > @@ -5047,7 +5049,9 @@ namespace views::__adaptor > using __detail::__range_iter_cat; > using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&, > > range_reference_t<__maybe_const_t<_Const, _Vs>>...>; > - if constexpr (!is_lvalue_reference_v<_Res>) > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 3798. Rvalue reference and iterator_category > + if constexpr (!is_reference_v<_Res>) > return input_iterator_tag{}; > else if constexpr ((derived_from<__range_iter_cat<_Vs, _Const>, > random_access_iterator_tag> && ...)) > @@ -5820,7 +5824,9 @@ namespace views::__adaptor > using _Res = invoke_result_t<__unarize<__maybe_const_t<_Const, _Fp>&, > _Nm>, > range_reference_t<_Base>>; > using _Cat = typename > iterator_traits<iterator_t<_Base>>::iterator_category; > - if constexpr (!is_lvalue_reference_v<_Res>) > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 3798. Rvalue reference and iterator_category > + if constexpr (!is_reference_v<_Res>) > return input_iterator_tag{}; > else if constexpr (derived_from<_Cat, random_access_iterator_tag>) > return random_access_iterator_tag{}; > @@ -7228,7 +7234,9 @@ namespace views::__adaptor > using _OuterCat = typename > iterator_traits<_OuterIter>::iterator_category; > using _InnerCat = typename > iterator_traits<_InnerIter>::iterator_category; > using _PatternCat = typename > iterator_traits<_PatternIter>::iterator_category; > - if constexpr > (!is_lvalue_reference_v<common_reference_t<iter_reference_t<_InnerIter>, > + // _GLIBCXX_RESOLVE_LIB_DEFECTS > + // 3798. Rvalue reference and iterator_category > + if constexpr > (!is_reference_v<common_reference_t<iter_reference_t<_InnerIter>, > > iter_reference_t<_PatternIter>>>)
This line is misaligned with the previous one now. LGTM besides that > return input_iterator_tag{}; > else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag> > diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > index ca695349650..e1b74353e63 100644 > --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > @@ -214,6 +214,21 @@ test10() > static_assert(std::same_as<cat, std::random_access_iterator_tag>); > } > > +void > +test11() > +{ > + struct MoveIt { > + int&& operator()(int& i) const { return std::move(i); } > + }; > + > + int x[] {2, 4}; > + auto xform = x | views::transform(MoveIt{}); > + using iterator = decltype(xform.begin()); > + // LWG 3798. Rvalue reference and iterator_category > + using cat = std::iterator_traits<iterator>::iterator_category; > + static_assert(std::same_as<cat, std::random_access_iterator_tag>); > +} > + > int > main() > { > @@ -227,4 +242,5 @@ main() > test08(); > test09(); > test10(); > + test11(); > } > -- > 2.46.2 > >