Message ID | 20200224232643.851356-2-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | libstdc++: LWG 3301 transform_view::iterator has incorrect iterator_category | expand |
On Mon, 24 Feb 2020, Patrick Palka wrote: > libstdc++-v3/ChangeLog: > > LWG 3301 transform_view::_Iterator has incorrect iterator_category > * include/std/ranges (transform_view::_Iterator::_S_iter_cat): Adjust > determination of iterator_category as per LWG 3301. > * testsuite/std/ranges/adaptors/transform.cc: Augment test. > --- > libstdc++-v3/include/std/ranges | 16 +++++++++---- > .../std/ranges/adaptors/transform.cc | 24 +++++++++++++++++++ > 2 files changed, 35 insertions(+), 5 deletions(-) > > diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges > index ab8fbaca38f..aed90e9710e 100644 > --- a/libstdc++-v3/include/std/ranges > +++ b/libstdc++-v3/include/std/ranges > @@ -1570,12 +1570,18 @@ namespace views > static constexpr auto > _S_iter_cat() > { > - using _Cat > - = typename iterator_traits<_Base_iter>::iterator_category; > - if constexpr (derived_from<_Cat, contiguous_iterator_tag>) > - return random_access_iterator_tag{}; > + using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>; Consider this line fixed to use 'typename'. > + if constexpr (is_lvalue_reference_v<_Res>) > + { > + using _Cat > + = typename iterator_traits<_Base_iter>::iterator_category; > + if constexpr (derived_from<_Cat, contiguous_iterator_tag>) > + return random_access_iterator_tag{}; > + else > + return _Cat{}; > + } > else > - return _Cat{}; > + return input_iterator_tag{}; > } > > static constexpr decltype(auto) > diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > index ad51fffb43d..0845febe2cf 100644 > --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > @@ -77,10 +77,34 @@ test03() > VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) ); > } > > +void > +test04() > +{ > + // LWG 3302 Consider this comment fixed to say 3301.
On 24/02/20 18:39 -0500, Patrick Palka wrote: >On Mon, 24 Feb 2020, Patrick Palka wrote: > >> libstdc++-v3/ChangeLog: >> >> LWG 3301 transform_view::_Iterator has incorrect iterator_category >> * include/std/ranges (transform_view::_Iterator::_S_iter_cat): Adjust >> determination of iterator_category as per LWG 3301. >> * testsuite/std/ranges/adaptors/transform.cc: Augment test. >> --- >> libstdc++-v3/include/std/ranges | 16 +++++++++---- >> .../std/ranges/adaptors/transform.cc | 24 +++++++++++++++++++ >> 2 files changed, 35 insertions(+), 5 deletions(-) >> >> diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges >> index ab8fbaca38f..aed90e9710e 100644 >> --- a/libstdc++-v3/include/std/ranges >> +++ b/libstdc++-v3/include/std/ranges >> @@ -1570,12 +1570,18 @@ namespace views >> static constexpr auto >> _S_iter_cat() >> { >> - using _Cat >> - = typename iterator_traits<_Base_iter>::iterator_category; >> - if constexpr (derived_from<_Cat, contiguous_iterator_tag>) >> - return random_access_iterator_tag{}; >> + using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>; > >Consider this line fixed to use 'typename'. > >> + if constexpr (is_lvalue_reference_v<_Res>) >> + { >> + using _Cat >> + = typename iterator_traits<_Base_iter>::iterator_category; >> + if constexpr (derived_from<_Cat, contiguous_iterator_tag>) >> + return random_access_iterator_tag{}; >> + else >> + return _Cat{}; >> + } >> else >> - return _Cat{}; >> + return input_iterator_tag{}; >> } >> >> static constexpr decltype(auto) >> diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc >> index ad51fffb43d..0845febe2cf 100644 >> --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc >> +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc >> @@ -77,10 +77,34 @@ test03() >> VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) ); >> } >> >> +void >> +test04() >> +{ >> + // LWG 3302 > >Consider this comment fixed to say 3301. OK, thanks.
On Tue, 25 Feb 2020, Jonathan Wakely wrote: > On 24/02/20 18:39 -0500, Patrick Palka wrote: > > On Mon, 24 Feb 2020, Patrick Palka wrote: > > > > > libstdc++-v3/ChangeLog: > > > > > > LWG 3301 transform_view::_Iterator has incorrect iterator_category > > > * include/std/ranges (transform_view::_Iterator::_S_iter_cat): Adjust > > > determination of iterator_category as per LWG 3301. > > > * testsuite/std/ranges/adaptors/transform.cc: Augment test. > > > --- > > > libstdc++-v3/include/std/ranges | 16 +++++++++---- > > > .../std/ranges/adaptors/transform.cc | 24 +++++++++++++++++++ > > > 2 files changed, 35 insertions(+), 5 deletions(-) > > > > > > diff --git a/libstdc++-v3/include/std/ranges > > > b/libstdc++-v3/include/std/ranges > > > index ab8fbaca38f..aed90e9710e 100644 > > > --- a/libstdc++-v3/include/std/ranges > > > +++ b/libstdc++-v3/include/std/ranges > > > @@ -1570,12 +1570,18 @@ namespace views > > > static constexpr auto > > > _S_iter_cat() > > > { > > > - using _Cat > > > - = typename iterator_traits<_Base_iter>::iterator_category; > > > - if constexpr (derived_from<_Cat, contiguous_iterator_tag>) > > > - return random_access_iterator_tag{}; > > > + using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>; > > > > Consider this line fixed to use 'typename'. > > > > > + if constexpr (is_lvalue_reference_v<_Res>) > > > + { > > > + using _Cat > > > + = typename iterator_traits<_Base_iter>::iterator_category; > > > + if constexpr (derived_from<_Cat, contiguous_iterator_tag>) > > > + return random_access_iterator_tag{}; > > > + else > > > + return _Cat{}; > > > + } > > > else > > > - return _Cat{}; > > > + return input_iterator_tag{}; > > > } > > > > > > static constexpr decltype(auto) > > > diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > > > b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > > > index ad51fffb43d..0845febe2cf 100644 > > > --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > > > +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc > > > @@ -77,10 +77,34 @@ test03() > > > VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) ); > > > } > > > > > > +void > > > +test04() > > > +{ > > > + // LWG 3302 > > > > Consider this comment fixed to say 3301. > > OK, thanks. Thanks for the review, I just committed all five patches.
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index ab8fbaca38f..aed90e9710e 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1570,12 +1570,18 @@ namespace views static constexpr auto _S_iter_cat() { - using _Cat - = typename iterator_traits<_Base_iter>::iterator_category; - if constexpr (derived_from<_Cat, contiguous_iterator_tag>) - return random_access_iterator_tag{}; + using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>; + if constexpr (is_lvalue_reference_v<_Res>) + { + using _Cat + = typename iterator_traits<_Base_iter>::iterator_category; + if constexpr (derived_from<_Cat, contiguous_iterator_tag>) + return random_access_iterator_tag{}; + else + return _Cat{}; + } else - return _Cat{}; + return input_iterator_tag{}; } static constexpr decltype(auto) diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc index ad51fffb43d..0845febe2cf 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc @@ -77,10 +77,34 @@ test03() VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) ); } +void +test04() +{ + // LWG 3302 + { + auto f = [] (int x) { return x; }; + int x[] = {1,2,3,4,5}; + auto v = x | views::transform(f); + auto i = v.begin(); + using Cat = decltype(i)::iterator_category; + static_assert(std::same_as<Cat, std::input_iterator_tag>); + } + + { + auto f = [] (int &x) -> int& { return x; }; + int x[] = {1,2,3,4,5}; + auto v = x | views::transform(f); + auto i = v.begin(); + using Cat = decltype(i)::iterator_category; + static_assert(std::derived_from<Cat, std::forward_iterator_tag>); + } +} + int main() { test01(); test02(); test03(); + test04(); }