mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
libstdc++: Implement LWG 3798 for range adaptors [PR106676]
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. Reviewed-by: Patrick Palka <ppalka@redhat.com>
This commit is contained in:
parent
7d15248d41
commit
7f65f94917
@ -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)
|
||||
|
@ -1892,7 +1892,9 @@ namespace views::__adaptor
|
||||
using _Base = transform_view::_Base<_Const>;
|
||||
using _Res = invoke_result_t<__maybe_const_t<_Const, _Fp>&,
|
||||
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>>>)
|
||||
return input_iterator_tag{};
|
||||
else if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user