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
* include/std/ranges (iota_view): Require that _Winc models semiregular
as per LWG 3292.
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)
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
main()
{
test01();
test02();
test03();
+ test04();
}