[gcc(refs/vendors/ibm/heads/perf)] libstdc++: LWG 3301 transform_view::iterator has incorrect iterator_category
Jiu Fu Guo
guojiufu@gcc.gnu.org
Thu Mar 19 05:52:13 GMT 2020
https://gcc.gnu.org/g:510bd1c178f3719df7148dd584d30acc2595dc3c
commit 510bd1c178f3719df7148dd584d30acc2595dc3c
Author: Patrick Palka <ppalka@redhat.com>
Date: Mon Feb 24 16:38:07 2020 -0500
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.
Diff:
---
libstdc++-v3/ChangeLog | 5 +++++
libstdc++-v3/include/std/ranges | 16 ++++++++++-----
.../testsuite/std/ranges/adaptors/transform.cc | 24 ++++++++++++++++++++++
3 files changed, 40 insertions(+), 5 deletions(-)
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 046d50de6d1..1a56a7d221c 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 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..178544d6378 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();
}
More information about the Libstdc++-cvs
mailing list