diff --git a/tests/std/tests/P0896R4_views_drop/test.cpp b/tests/std/tests/P0896R4_views_drop/test.cpp index f1c6be74a8e..571febe097c 100644 --- a/tests/std/tests/P0896R4_views_drop/test.cpp +++ b/tests/std/tests/P0896R4_views_drop/test.cpp @@ -289,6 +289,55 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { } } +#if _HAS_CXX23 + using ranges::const_iterator_t, ranges::const_sentinel_t, ranges::cbegin, ranges::cend; + + // Validate view_interface::cbegin + STATIC_ASSERT(CanMemberCBegin == input_range); + STATIC_ASSERT(same_as, const_iterator_t>); + STATIC_ASSERT(CanMemberCBegin == (random_access_range && sized_range) ); + if (forward_range) { // intentionally not if constexpr + const same_as> auto i = r.cbegin(); + if (!is_empty) { + assert(*i == *cbegin(expected)); + } + + if constexpr (copyable) { + auto r2 = r; + const same_as> auto i2 = r2.cbegin(); + if (!is_empty) { + assert(*i2 == *i); + } + } + + if constexpr (random_access_range && sized_range) { + STATIC_ASSERT(same_as, const_iterator_t>); + const same_as> auto i3 = as_const(r).cbegin(); + if (!is_empty) { + assert(*i3 == *i); + } + } + } + + // Validate view_interface::cend + STATIC_ASSERT(CanMemberCEnd == input_range); + STATIC_ASSERT(same_as, const_sentinel_t>); + STATIC_ASSERT(CanMemberCEnd == (random_access_range && sized_range) ); + if (!is_empty) { + same_as> auto i = r.cend(); + if constexpr (bidirectional_range && common_range) { + assert(*prev(i) == *prev(cend(expected))); + } + + if constexpr (random_access_range && sized_range) { + same_as> auto i2 = as_const(r).cend(); + if constexpr (bidirectional_range && common_range) { + assert(*prev(i2) == *prev(cend(expected))); + } + } + } +#endif // _HAS_CXX23 + // Validate view_interface::data STATIC_ASSERT(CanMemberData == contiguous_range); STATIC_ASSERT(CanData == contiguous_range); diff --git a/tests/std/tests/P0896R4_views_drop_while/test.cpp b/tests/std/tests/P0896R4_views_drop_while/test.cpp index 7aede8f7fc9..c1e4f7bd888 100644 --- a/tests/std/tests/P0896R4_views_drop_while/test.cpp +++ b/tests/std/tests/P0896R4_views_drop_while/test.cpp @@ -213,6 +213,51 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { STATIC_ASSERT(!CanEnd); } +#if _HAS_CXX23 + using ranges::const_iterator_t, ranges::const_sentinel_t, ranges::cbegin, ranges::cend; + + // Validate view_interface::cbegin + STATIC_ASSERT(CanMemberCBegin == ranges::input_range); + if (forward_range) { // intentionally not if constexpr + const same_as> auto i = r.cbegin(); + if (!is_empty) { + assert(*i == *cbegin(expected)); + assert(*r.cbegin() == *cbegin(expected)); + } + + if constexpr (copyable) { + auto r2 = r; + const same_as> auto i2 = r2.cbegin(); + if (!is_empty) { + assert(*i2 == *i); + assert(*r2.cbegin() == *i2); + } + } + + STATIC_ASSERT(!CanCBegin); + } + + // Validate view_interface::cend + STATIC_ASSERT(CanMemberCEnd == ranges::input_range); + if (!is_empty) { + if constexpr (common_range) { + same_as> auto i = r.cend(); + if constexpr (bidirectional_range) { + assert(*prev(i) == *prev(cend(expected))); + } + } else { + [[maybe_unused]] same_as> auto s = r.cend(); + } + + if constexpr (bidirectional_range && common_range && copyable) { + auto r2 = r; + assert(*prev(r2.cend()) == *prev(cend(expected))); + } + + STATIC_ASSERT(!CanCEnd); + } +#endif // _HAS_CXX23 + // Validate view_interface::data STATIC_ASSERT(CanMemberData == contiguous_range); STATIC_ASSERT(CanData == contiguous_range); diff --git a/tests/std/tests/P0896R4_views_take/test.cpp b/tests/std/tests/P0896R4_views_take/test.cpp index 3a868a43384..b497e6969c6 100644 --- a/tests/std/tests/P0896R4_views_take/test.cpp +++ b/tests/std/tests/P0896R4_views_take/test.cpp @@ -321,6 +321,86 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { } } +#if _HAS_CXX23 + using ranges::const_iterator_t, ranges::const_sentinel_t, ranges::cbegin, ranges::cend; + + // Validate view_interface::cbegin + STATIC_ASSERT(CanMemberCBegin); + if constexpr (random_access_range && sized_range) { + STATIC_ASSERT(same_as, const_iterator_t>); + } else { + STATIC_ASSERT(same_as, const_iterator>>>); + } + STATIC_ASSERT(CanMemberCBegin == input_range); + if (forward_range) { // intentionally not if constexpr + const same_as> auto i = r.cbegin(); + if (!is_empty) { + assert(*i == *cbegin(expected)); + } + + if constexpr (copyable) { + auto r2 = r; + const same_as> auto i2 = r2.cbegin(); + if (!is_empty) { + assert(*i2 == *i); + } + } + + if constexpr (range) { + if constexpr (random_access_range && sized_range) { + STATIC_ASSERT(same_as, const_iterator_t>); + } else { + STATIC_ASSERT( + same_as, const_iterator>>>); + } + + const same_as> auto i3 = as_const(r).cbegin(); + if (!is_empty) { + assert(*i3 == *i); + } + } + } + + // Validate view_interface::cend + STATIC_ASSERT(CanMemberCEnd); + if constexpr (sized_range) { + if constexpr (random_access_range) { + STATIC_ASSERT(same_as, const_iterator_t>); + } else { + STATIC_ASSERT(same_as, default_sentinel_t>); + } + } else { + // Not much we can do here + STATIC_ASSERT(!same_as, const_iterator_t>); + STATIC_ASSERT(!same_as, default_sentinel_t>); + STATIC_ASSERT(is_class_v>); + } + STATIC_ASSERT(CanCEnd == range); + if (!is_empty) { + same_as> auto s = r.cend(); + if constexpr (bidirectional_range && common_range) { + assert(*prev(s) == *prev(cend(expected))); + } + + if constexpr (range) { + same_as> auto sc = as_const(r).cend(); + if constexpr (bidirectional_range && common_range) { + assert(*prev(sc) == *prev(cend(expected))); + } + + if (forward_range) { // intentionally not if constexpr + // Compare with const / non-const iterators + const same_as> auto i = r.cbegin(); + const same_as> auto ic = as_const(r).cbegin(); + assert(s != i); + assert(s != ic); + assert(sc != i); + assert(sc != ic); + } + } + } +#endif // _HAS_CXX23 + // Validate view_interface::data STATIC_ASSERT(CanMemberData == contiguous_range); STATIC_ASSERT(CanData == contiguous_range); diff --git a/tests/std/tests/P0896R4_views_take_while/test.cpp b/tests/std/tests/P0896R4_views_take_while/test.cpp index 4b64b77a543..72348e094b8 100644 --- a/tests/std/tests/P0896R4_views_take_while/test.cpp +++ b/tests/std/tests/P0896R4_views_take_while/test.cpp @@ -239,7 +239,7 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { assert(sc == s.base()); assert(sc == sc.base()); } else if constexpr (forward_range && is_lvalue_reference_v) { - auto full_range = views::take_while(rng, [](auto const&) { return true; }); + auto full_range = views::take_while(rng, [](const auto&) { return true; }); const auto length = 8; // NB: depends on the test data assert(full_range.end() == next(full_range.begin(), length)); assert(full_range.end() == next(as_const(full_range).begin(), length)); @@ -258,6 +258,90 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) { } } +#if _HAS_CXX23 + using ranges::const_iterator_t, ranges::const_sentinel_t, ranges::cbegin, ranges::cend; + + // Validate view_interface::cbegin + STATIC_ASSERT(CanMemberCBegin); + STATIC_ASSERT(CanMemberCBegin == ranges::range); + STATIC_ASSERT(indirect_unary_predicate>); + if (forward_range) { // intentionally not if constexpr + const same_as> auto i = r.cbegin(); + if (!is_empty) { + assert(*i == *cbegin(expected)); + assert(*r.cbegin() == *cbegin(expected)); + } + + if constexpr (copyable) { + auto r2 = r; + const same_as> auto i2 = r2.cbegin(); + if (!is_empty) { + assert(*i2 == *i); + assert(*r2.cbegin() == *i2); + } + } + + const same_as> auto ic = as_const(r).cbegin(); + if (!is_empty) { + assert(*ic == *cbegin(expected)); + assert(*as_const(r).cbegin() == *cbegin(expected)); + } + + if constexpr (copyable) { + auto rc2 = as_const(r); + const same_as> auto ic2 = rc2.cbegin(); + if (!is_empty) { + assert(*ic2 == *ic); + assert(*rc2.cbegin() == *ic2); + } + } + } + + // Validate view_interface::cend + STATIC_ASSERT(CanMemberCEnd); + STATIC_ASSERT(CanMemberCEnd == ranges::range); + STATIC_ASSERT(indirect_unary_predicate>); + STATIC_ASSERT(CanCEnd == CanMemberCEnd); + STATIC_ASSERT(!common_range); + STATIC_ASSERT(!common_range); + if (!is_empty) { + same_as> auto s = r.cend(); + same_as> auto sc = as_const(r).cend(); + + if (forward_range) { // intentionally not if constexpr + // Compare with const / non-const iterators + assert(s != r.cbegin()); + assert(s != as_const(r).cbegin()); + assert(sc != r.cbegin()); + assert(sc != as_const(r).cbegin()); + + // Compare with end of range + if constexpr (common_range) { + assert(s == s.base()); + assert(s == sc.base()); + assert(sc == s.base()); + assert(sc == sc.base()); + } else if constexpr (forward_range && is_lvalue_reference_v) { + auto full_range = views::take_while(rng, [](const auto&) { return true; }); + const auto length = 8; // NB: depends on the test data + assert(full_range.cend() == next(full_range.cbegin(), length)); + assert(full_range.cend() == next(as_const(full_range).cbegin(), length)); + assert(as_const(full_range).cend() == next(full_range.cbegin(), length)); + assert(as_const(full_range).cend() == next(as_const(full_range).cbegin(), length)); + } + + // Compare with iterator whose predicate evaluates to false + if constexpr (forward_range) { + const auto length = 4; // NB: depends on the test data + assert(s == next(r.cbegin(), length)); + assert(s == next(as_const(r).cbegin(), length)); + assert(sc == next(r.cbegin(), length)); + assert(sc == next(as_const(r).cbegin(), length)); + } + } + } +#endif // _HAS_CXX23 + // Validate view_interface::data if constexpr (CanData) { const same_as>*> auto ptr1 = r.data();