diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2020-09-21 14:30:38 +0100 |
---|---|---|
committer | Jonathan Wakely <jwakely@redhat.com> | 2020-09-21 14:30:38 +0100 |
commit | 2ec58cfcea146a61755516ce4ed160827fe0b4ff (patch) | |
tree | b1fcf569ab7b8253574c11eac18d5b08951063a1 | |
parent | f10ed928e2f8ecc2c859abff8f2f9296b11b8d95 (diff) | |
download | gcc-2ec58cfcea146a61755516ce4ed160827fe0b4ff.zip gcc-2ec58cfcea146a61755516ce4ed160827fe0b4ff.tar.gz gcc-2ec58cfcea146a61755516ce4ed160827fe0b4ff.tar.bz2 |
libstdc++: Relax constraints on transform_view and elements_view iterators
libstdc++-v3/ChangeLog:
* include/std/ranges (transform_view, elements_view): Relax
constraints on operator- for iterators, as per LWG 3483.
* testsuite/std/ranges/adaptors/elements.cc: Check that we
can take the difference of two iterators from a non-random
access range.
* testsuite/std/ranges/adaptors/transform.cc: Likewise.
-rw-r--r-- | libstdc++-v3/include/std/ranges | 8 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc | 24 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc | 24 |
3 files changed, 54 insertions, 2 deletions
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 23a04d6..005e89f94 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -1833,9 +1833,11 @@ namespace views requires random_access_range<_Base> { return {*__i._M_parent, __i._M_current - __n}; } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3483. transform_view::iterator's difference is overconstrained friend constexpr difference_type operator-(const _Iterator& __x, const _Iterator& __y) - requires random_access_range<_Base> + requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> { return __x._M_current - __y._M_current; } friend constexpr decltype(auto) @@ -3538,9 +3540,11 @@ namespace views requires random_access_range<_Base> { return _Iterator{__x} -= __y; } + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3483. transform_view::iterator's difference is overconstrained friend constexpr difference_type operator-(const _Iterator& __x, const _Iterator& __y) - requires random_access_range<_Base> + requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>> { return __x._M_current - __y._M_current; } friend _Sentinel<_Const>; diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc index 3026adf..94dd7c9 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/elements.cc @@ -66,9 +66,33 @@ test02() VERIFY( ranges::equal(v2, (std::pair<char, int>[]){{1,2}}) ); } +struct X +{ + using Iter = __gnu_test::forward_iterator_wrapper<std::pair<int, X>>; + + friend auto operator-(Iter l, Iter r) { return l.ptr - r.ptr; } +}; + +void +test03() +{ + // LWG 3483 + std::pair<int, X> x[3]; + __gnu_test::test_forward_range<std::pair<int, X>> r(x); + auto v = views::elements<1>(r); + auto b = begin(v); + static_assert( !ranges::random_access_range<decltype(r)> ); + static_assert( std::sized_sentinel_for<decltype(b), decltype(b)> ); + VERIFY( (next(b, 1) - b) == 1 ); + const auto v_const = v; + auto b_const = begin(v_const); + VERIFY( (next(b_const, 2) - b_const) == 2 ); +} + int main() { test01(); test02(); + test03(); } diff --git a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc index c14e36e..41a7d3b 100644 --- a/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc +++ b/libstdc++-v3/testsuite/std/ranges/adaptors/transform.cc @@ -122,6 +122,29 @@ test05() b = ranges::end(v); } +struct Y +{ + using Iter = __gnu_test::forward_iterator_wrapper<Y>; + + friend auto operator-(Iter l, Iter r) { return l.ptr - r.ptr; } +}; + +void +test06() +{ + // LWG 3483 + Y y[3]; + __gnu_test::test_forward_range<Y> r(y); + auto v = views::transform(r, std::identity{}); + auto b = begin(v); + static_assert( !ranges::random_access_range<decltype(r)> ); + static_assert( std::sized_sentinel_for<decltype(b), decltype(b)> ); + VERIFY( (next(b, 1) - b) == 1 ); + const auto v_const = v; + auto b_const = begin(v_const); + VERIFY( (next(b_const, 2) - b_const) == 2 ); +} + int main() { @@ -130,4 +153,5 @@ main() test03(); test04(); test05(); + test06(); } |