aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-02-24 16:38:07 -0500
committerPatrick Palka <ppalka@redhat.com>2020-02-25 13:04:32 -0500
commit510bd1c178f3719df7148dd584d30acc2595dc3c (patch)
tree0c8d33fb33c43e3ad04b302c0ab6c6dc898f49e1
parent7f0f108309a881fe9e84a9c0b9a6f13b24a7886e (diff)
downloadgcc-510bd1c178f3719df7148dd584d30acc2595dc3c.zip
gcc-510bd1c178f3719df7148dd584d30acc2595dc3c.tar.gz
gcc-510bd1c178f3719df7148dd584d30acc2595dc3c.tar.bz2
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.
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/include/std/ranges16
-rw-r--r--libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc24
3 files changed, 40 insertions, 5 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 046d50d..1a56a7d2 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
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.
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index ab8fbac..aed90e9 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 ad51fff..178544d 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 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();
}