Commit 510bd1c1 by Patrick Palka

libstdc++: LWG 3301 transform_view::iterator has incorrect iterator_category

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.
parent 7f0f1083
2020-02-25 Patrick Palka <ppalka@redhat.com> 2020-02-25 Patrick Palka <ppalka@redhat.com>
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.
LWG 3292 iota_view is under-constrained LWG 3292 iota_view is under-constrained
* include/std/ranges (iota_view): Require that _Winc models semiregular * include/std/ranges (iota_view): Require that _Winc models semiregular
as per LWG 3292. as per LWG 3292.
......
...@@ -1570,6 +1570,9 @@ namespace views ...@@ -1570,6 +1570,9 @@ namespace views
static constexpr auto static constexpr auto
_S_iter_cat() _S_iter_cat()
{ {
using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
if constexpr (is_lvalue_reference_v<_Res>)
{
using _Cat using _Cat
= typename iterator_traits<_Base_iter>::iterator_category; = typename iterator_traits<_Base_iter>::iterator_category;
if constexpr (derived_from<_Cat, contiguous_iterator_tag>) if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
...@@ -1577,6 +1580,9 @@ namespace views ...@@ -1577,6 +1580,9 @@ namespace views
else else
return _Cat{}; return _Cat{};
} }
else
return input_iterator_tag{};
}
static constexpr decltype(auto) static constexpr decltype(auto)
__iter_move(const _Iterator& __i = {}) __iter_move(const _Iterator& __i = {})
......
...@@ -77,10 +77,34 @@ test03() ...@@ -77,10 +77,34 @@ test03()
VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) ); VERIFY( ranges::equal(v, (int[]){1,2,3,4,5}) );
} }
void
test04()
{
// LWG 3301
{
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 int
main() main()
{ {
test01(); test01();
test02(); test02();
test03(); test03();
test04();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment