зеркало из https://github.com/microsoft/STL.git
Improve `views::drop(_while)` and `views::take(_while)` tests (#3390)
Co-authored-by: Stephan T. Lavavej <stl@nuwen.net>
This commit is contained in:
Родитель
ade0d6630e
Коммит
580ae14276
|
@ -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<R> == input_range<V>);
|
||||
STATIC_ASSERT(same_as<const_iterator_t<R>, const_iterator_t<V>>);
|
||||
STATIC_ASSERT(CanMemberCBegin<const R&> == (random_access_range<const V> && sized_range<const V>) );
|
||||
if (forward_range<V>) { // intentionally not if constexpr
|
||||
const same_as<const_iterator_t<R>> auto i = r.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i == *cbegin(expected));
|
||||
}
|
||||
|
||||
if constexpr (copyable<V>) {
|
||||
auto r2 = r;
|
||||
const same_as<const_iterator_t<R>> auto i2 = r2.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i2 == *i);
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (random_access_range<const V> && sized_range<const V>) {
|
||||
STATIC_ASSERT(same_as<const_iterator_t<const R>, const_iterator_t<const V>>);
|
||||
const same_as<const_iterator_t<const R>> auto i3 = as_const(r).cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i3 == *i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate view_interface::cend
|
||||
STATIC_ASSERT(CanMemberCEnd<R> == input_range<V>);
|
||||
STATIC_ASSERT(same_as<const_sentinel_t<R>, const_sentinel_t<V>>);
|
||||
STATIC_ASSERT(CanMemberCEnd<const R&> == (random_access_range<const V> && sized_range<const V>) );
|
||||
if (!is_empty) {
|
||||
same_as<const_sentinel_t<R>> auto i = r.cend();
|
||||
if constexpr (bidirectional_range<R> && common_range<R>) {
|
||||
assert(*prev(i) == *prev(cend(expected)));
|
||||
}
|
||||
|
||||
if constexpr (random_access_range<const V> && sized_range<const V>) {
|
||||
same_as<const_sentinel_t<const R>> auto i2 = as_const(r).cend();
|
||||
if constexpr (bidirectional_range<const R> && common_range<const R>) {
|
||||
assert(*prev(i2) == *prev(cend(expected)));
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
// Validate view_interface::data
|
||||
STATIC_ASSERT(CanMemberData<R> == contiguous_range<V>);
|
||||
STATIC_ASSERT(CanData<R&> == contiguous_range<V>);
|
||||
|
|
|
@ -213,6 +213,51 @@ constexpr bool test_one(Rng&& rng, Expected&& expected) {
|
|||
STATIC_ASSERT(!CanEnd<const R>);
|
||||
}
|
||||
|
||||
#if _HAS_CXX23
|
||||
using ranges::const_iterator_t, ranges::const_sentinel_t, ranges::cbegin, ranges::cend;
|
||||
|
||||
// Validate view_interface::cbegin
|
||||
STATIC_ASSERT(CanMemberCBegin<R> == ranges::input_range<V>);
|
||||
if (forward_range<V>) { // intentionally not if constexpr
|
||||
const same_as<const_iterator_t<R>> auto i = r.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i == *cbegin(expected));
|
||||
assert(*r.cbegin() == *cbegin(expected));
|
||||
}
|
||||
|
||||
if constexpr (copyable<V>) {
|
||||
auto r2 = r;
|
||||
const same_as<const_iterator_t<R>> auto i2 = r2.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i2 == *i);
|
||||
assert(*r2.cbegin() == *i2);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_ASSERT(!CanCBegin<const R>);
|
||||
}
|
||||
|
||||
// Validate view_interface::cend
|
||||
STATIC_ASSERT(CanMemberCEnd<R> == ranges::input_range<V>);
|
||||
if (!is_empty) {
|
||||
if constexpr (common_range<V>) {
|
||||
same_as<const_iterator_t<R>> auto i = r.cend();
|
||||
if constexpr (bidirectional_range<V>) {
|
||||
assert(*prev(i) == *prev(cend(expected)));
|
||||
}
|
||||
} else {
|
||||
[[maybe_unused]] same_as<const_sentinel_t<R>> auto s = r.cend();
|
||||
}
|
||||
|
||||
if constexpr (bidirectional_range<V> && common_range<V> && copyable<V>) {
|
||||
auto r2 = r;
|
||||
assert(*prev(r2.cend()) == *prev(cend(expected)));
|
||||
}
|
||||
|
||||
STATIC_ASSERT(!CanCEnd<const R>);
|
||||
}
|
||||
#endif // _HAS_CXX23
|
||||
|
||||
// Validate view_interface::data
|
||||
STATIC_ASSERT(CanMemberData<R> == contiguous_range<V>);
|
||||
STATIC_ASSERT(CanData<R&> == contiguous_range<V>);
|
||||
|
|
|
@ -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<R>);
|
||||
if constexpr (random_access_range<V> && sized_range<V>) {
|
||||
STATIC_ASSERT(same_as<const_iterator_t<R>, const_iterator_t<V>>);
|
||||
} else {
|
||||
STATIC_ASSERT(same_as<const_iterator_t<R>, const_iterator<counted_iterator<iterator_t<V>>>>);
|
||||
}
|
||||
STATIC_ASSERT(CanMemberCBegin<const R&> == input_range<const V>);
|
||||
if (forward_range<V>) { // intentionally not if constexpr
|
||||
const same_as<const_iterator_t<R>> auto i = r.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i == *cbegin(expected));
|
||||
}
|
||||
|
||||
if constexpr (copyable<V>) {
|
||||
auto r2 = r;
|
||||
const same_as<const_iterator_t<R>> auto i2 = r2.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i2 == *i);
|
||||
}
|
||||
}
|
||||
|
||||
if constexpr (range<const V>) {
|
||||
if constexpr (random_access_range<const V> && sized_range<const V>) {
|
||||
STATIC_ASSERT(same_as<const_iterator_t<const R>, const_iterator_t<const V>>);
|
||||
} else {
|
||||
STATIC_ASSERT(
|
||||
same_as<const_iterator_t<const R>, const_iterator<counted_iterator<iterator_t<const V>>>>);
|
||||
}
|
||||
|
||||
const same_as<const_iterator_t<const R>> auto i3 = as_const(r).cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i3 == *i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate view_interface::cend
|
||||
STATIC_ASSERT(CanMemberCEnd<R>);
|
||||
if constexpr (sized_range<V>) {
|
||||
if constexpr (random_access_range<V>) {
|
||||
STATIC_ASSERT(same_as<const_sentinel_t<R>, const_iterator_t<V>>);
|
||||
} else {
|
||||
STATIC_ASSERT(same_as<const_sentinel_t<R>, default_sentinel_t>);
|
||||
}
|
||||
} else {
|
||||
// Not much we can do here
|
||||
STATIC_ASSERT(!same_as<const_sentinel_t<R>, const_iterator_t<V>>);
|
||||
STATIC_ASSERT(!same_as<const_sentinel_t<R>, default_sentinel_t>);
|
||||
STATIC_ASSERT(is_class_v<const_sentinel_t<R>>);
|
||||
}
|
||||
STATIC_ASSERT(CanCEnd<const R&> == range<const V>);
|
||||
if (!is_empty) {
|
||||
same_as<const_sentinel_t<R>> auto s = r.cend();
|
||||
if constexpr (bidirectional_range<R> && common_range<R>) {
|
||||
assert(*prev(s) == *prev(cend(expected)));
|
||||
}
|
||||
|
||||
if constexpr (range<const V>) {
|
||||
same_as<const_sentinel_t<const R>> auto sc = as_const(r).cend();
|
||||
if constexpr (bidirectional_range<const R> && common_range<const R>) {
|
||||
assert(*prev(sc) == *prev(cend(expected)));
|
||||
}
|
||||
|
||||
if (forward_range<V>) { // intentionally not if constexpr
|
||||
// Compare with const / non-const iterators
|
||||
const same_as<const_iterator_t<R>> auto i = r.cbegin();
|
||||
const same_as<const_iterator_t<const R>> 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<R> == contiguous_range<V>);
|
||||
STATIC_ASSERT(CanData<R&> == contiguous_range<V>);
|
||||
|
|
|
@ -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<V> && is_lvalue_reference_v<Rng>) {
|
||||
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<R>);
|
||||
STATIC_ASSERT(CanMemberCBegin<const R> == ranges::range<const R>);
|
||||
STATIC_ASSERT(indirect_unary_predicate<const Pred, const_iterator_t<const V>>);
|
||||
if (forward_range<V>) { // intentionally not if constexpr
|
||||
const same_as<const_iterator_t<R>> auto i = r.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i == *cbegin(expected));
|
||||
assert(*r.cbegin() == *cbegin(expected));
|
||||
}
|
||||
|
||||
if constexpr (copyable<V>) {
|
||||
auto r2 = r;
|
||||
const same_as<const_iterator_t<R>> auto i2 = r2.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*i2 == *i);
|
||||
assert(*r2.cbegin() == *i2);
|
||||
}
|
||||
}
|
||||
|
||||
const same_as<const_iterator_t<const R>> auto ic = as_const(r).cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*ic == *cbegin(expected));
|
||||
assert(*as_const(r).cbegin() == *cbegin(expected));
|
||||
}
|
||||
|
||||
if constexpr (copyable<V>) {
|
||||
auto rc2 = as_const(r);
|
||||
const same_as<const_iterator_t<const R>> auto ic2 = rc2.cbegin();
|
||||
if (!is_empty) {
|
||||
assert(*ic2 == *ic);
|
||||
assert(*rc2.cbegin() == *ic2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate view_interface::cend
|
||||
STATIC_ASSERT(CanMemberCEnd<R>);
|
||||
STATIC_ASSERT(CanMemberCEnd<const R> == ranges::range<const R>);
|
||||
STATIC_ASSERT(indirect_unary_predicate<const Pred, const_iterator_t<const V>>);
|
||||
STATIC_ASSERT(CanCEnd<const R&> == CanMemberCEnd<const R>);
|
||||
STATIC_ASSERT(!common_range<R>);
|
||||
STATIC_ASSERT(!common_range<const R>);
|
||||
if (!is_empty) {
|
||||
same_as<const_sentinel_t<R>> auto s = r.cend();
|
||||
same_as<const_sentinel_t<const R>> auto sc = as_const(r).cend();
|
||||
|
||||
if (forward_range<V>) { // 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<V>) {
|
||||
assert(s == s.base());
|
||||
assert(s == sc.base());
|
||||
assert(sc == s.base());
|
||||
assert(sc == sc.base());
|
||||
} else if constexpr (forward_range<V> && is_lvalue_reference_v<Rng>) {
|
||||
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<V>) {
|
||||
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<R&>) {
|
||||
const same_as<remove_reference_t<ranges::range_reference_t<V>>*> auto ptr1 = r.data();
|
||||
|
|
Загрузка…
Ссылка в новой задаче