From e948179adc47c8dfd23e7b04dcbb6e94fef3a89e Mon Sep 17 00:00:00 2001 From: Michael Schellenberger Costa Date: Thu, 12 Nov 2020 11:43:31 +0100 Subject: [PATCH 1/3] Implement resolution of LWG-3449 for take_view Addresses #1446 --- stl/inc/ranges | 15 +++++++++++++-- tests/std/tests/P0896R4_views_take/test.cpp | 18 ++++++++++++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index a6eeefed238..db1e452dba6 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1618,7 +1618,9 @@ namespace ranges { using _Base_Ty = _Maybe_const<_Const, _Vw>; using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_Ty>>; - using _Counted_Iter = counted_iterator<_Maybe_wrapped<_Wrapped, iterator_t<_Base_Ty>>>; + template + using _Counted_Iter = + counted_iterator<_Maybe_wrapped<_Wrapped, iterator_t<_Maybe_const<_OtherConst, _Vw>>>>; _Base_sentinel _Last{}; @@ -1641,7 +1643,16 @@ namespace ranges { return _Last; } - _NODISCARD friend constexpr bool operator==(const _Counted_Iter& _Left, const _Sentinel& _Right) { + _NODISCARD friend constexpr bool operator==(const _Counted_Iter<_Const>& _Left, const _Sentinel& _Right) { + return _Left.count() == 0 || _Left.base() == _Right._Last; + } + + // clang-format off + template + requires sentinel_for<_Base_sentinel, _Counted_Iter<_OtherConst>> + _NODISCARD friend constexpr bool operator==( + const _Counted_Iter<_OtherConst>& _Left, const _Sentinel& _Right) { + // clang-format on return _Left.count() == 0 || _Left.base() == _Right._Last; } diff --git a/tests/std/tests/P0896R4_views_take/test.cpp b/tests/std/tests/P0896R4_views_take/test.cpp index ea8c453739c..c1104c12c29 100644 --- a/tests/std/tests/P0896R4_views_take/test.cpp +++ b/tests/std/tests/P0896R4_views_take/test.cpp @@ -282,15 +282,25 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { } STATIC_ASSERT(CanEnd == range); if (!is_empty) { - same_as> auto i = r.end(); + same_as> auto s = r.end(); if constexpr (bidirectional_range && common_range) { - assert(*prev(i) == *prev(end(expected))); + assert(*prev(s) == *prev(end(expected))); } if constexpr (range) { - same_as> auto i2 = as_const(r).end(); + same_as> auto sc = as_const(r).end(); if constexpr (bidirectional_range && common_range) { - assert(*prev(i2) == *prev(end(expected))); + assert(*prev(sc) == *prev(end(expected))); + } + + if (forward_range) { // intentionally not if constexpr + // Compare with const / non const iterators + const same_as> auto i = r.begin(); + const same_as> auto ic = as_const(r).begin(); + assert(s != i); + assert(s != ic); + assert(sc != i); + assert(sc != ic); } } } From 8ee062bed7693b00a4fcfaac1aa4f4d936ef87ec Mon Sep 17 00:00:00 2001 From: "Stephan T. Lavavej" Date: Thu, 19 Nov 2020 23:57:56 -0800 Subject: [PATCH 2/3] Hyphenate "non-const" --- tests/std/tests/P0896R4_views_take/test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/std/tests/P0896R4_views_take/test.cpp b/tests/std/tests/P0896R4_views_take/test.cpp index c1104c12c29..27ccb1b7cc3 100644 --- a/tests/std/tests/P0896R4_views_take/test.cpp +++ b/tests/std/tests/P0896R4_views_take/test.cpp @@ -294,7 +294,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { } if (forward_range) { // intentionally not if constexpr - // Compare with const / non const iterators + // Compare with const / non-const iterators const same_as> auto i = r.begin(); const same_as> auto ic = as_const(r).begin(); assert(s != i); From ec66fdf647116076fccdaddd3382cf37ab6e354c Mon Sep 17 00:00:00 2001 From: Casey Carter Date: Thu, 3 Dec 2020 09:19:38 -0800 Subject: [PATCH 3/3] Cleanup: * Correct the requirement on the new `operator==` overload * Rename `_Base_Ty` to `_Base_t` and `_Counted_Iter` to `_Counted_iter` to be consistent with our naming conventions (snakes and camels don't mix). --- stl/inc/ranges | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/stl/inc/ranges b/stl/inc/ranges index db1e452dba6..52b24330e19 100644 --- a/stl/inc/ranges +++ b/stl/inc/ranges @@ -1616,11 +1616,12 @@ namespace ranges { template friend class _Sentinel; - using _Base_Ty = _Maybe_const<_Const, _Vw>; - using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_Ty>>; + using _Base_t = _Maybe_const<_Const, _Vw>; + using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_t>>; template - using _Counted_Iter = - counted_iterator<_Maybe_wrapped<_Wrapped, iterator_t<_Maybe_const<_OtherConst, _Vw>>>>; + using _Base_iterator = _Maybe_wrapped<_Wrapped, iterator_t<_Maybe_const<_OtherConst, _Vw>>>; + template + using _Counted_iter = counted_iterator<_Base_iterator<_OtherConst>>; _Base_sentinel _Last{}; @@ -1643,15 +1644,15 @@ namespace ranges { return _Last; } - _NODISCARD friend constexpr bool operator==(const _Counted_Iter<_Const>& _Left, const _Sentinel& _Right) { + _NODISCARD friend constexpr bool operator==(const _Counted_iter<_Const>& _Left, const _Sentinel& _Right) { return _Left.count() == 0 || _Left.base() == _Right._Last; } // clang-format off - template - requires sentinel_for<_Base_sentinel, _Counted_Iter<_OtherConst>> + template + requires sentinel_for<_Base_sentinel, _Base_iterator<_OtherConst>> _NODISCARD friend constexpr bool operator==( - const _Counted_Iter<_OtherConst>& _Left, const _Sentinel& _Right) { + const _Counted_iter<_OtherConst>& _Left, const _Sentinel& _Right) { // clang-format on return _Left.count() == 0 || _Left.base() == _Right._Last; } @@ -1660,17 +1661,17 @@ namespace ranges { // clang-format off _NODISCARD constexpr auto _Unwrapped() const& - requires _Wrapped && _Unwrappable_v&> { + requires _Wrapped && _Unwrappable_v&> { // clang-format on return _Sentinel<_Const, false>{_Get_unwrapped(_Last)}; } // clang-format off - _NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v> { + _NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v> { // clang-format on return _Sentinel<_Const, false>{_Get_unwrapped(_STD move(_Last))}; } - static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v>; + static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v>; constexpr void _Seek_to(const _Sentinel<_Const, false>& _That) requires _Wrapped { _Seek_wrapped(_Last, _That._Last); @@ -1865,9 +1866,9 @@ namespace ranges { template friend class _Sentinel; - using _Base_Ty = _Maybe_const<_Const, _Vw>; - using _Base_iterator = _Maybe_wrapped<_Wrapped, iterator_t<_Base_Ty>>; - using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_Ty>>; + using _Base_t = _Maybe_const<_Const, _Vw>; + using _Base_iterator = _Maybe_wrapped<_Wrapped, iterator_t<_Base_t>>; + using _Base_sentinel = _Maybe_wrapped<_Wrapped, sentinel_t<_Base_t>>; template using _Maybe_const_iter = _Maybe_wrapped<_Wrapped, iterator_t<_Maybe_const<_OtherConst, _Vw>>>; @@ -1911,17 +1912,17 @@ namespace ranges { // clang-format off _NODISCARD constexpr auto _Unwrapped() const& - requires _Wrapped && _Unwrappable_v&> { + requires _Wrapped && _Unwrappable_v&> { // clang-format on return _Sentinel<_Const, false>{_Get_unwrapped(_Last), _Pred}; } // clang-format off - _NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v> { + _NODISCARD constexpr auto _Unwrapped() && requires _Wrapped && _Unwrappable_v> { // clang-format on return _Sentinel<_Const, false>{_Get_unwrapped(_STD move(_Last)), _Pred}; } - static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v>; + static constexpr bool _Unwrap_when_unverified = _Do_unwrap_when_unverified_v>; constexpr void _Seek_to(const _Sentinel<_Const, false>& _That) requires _Wrapped { _Seek_wrapped(_Last, _That._Last);