forked from OSchip/llvm-project
[libc++] NFC: More refactoring in the prev/next/advance tests per review comments
This commit is contained in:
parent
f39dcf85f9
commit
9f967eed89
|
@ -24,14 +24,14 @@ static_assert(is_function_like<decltype(std::ranges::advance)>());
|
|||
|
||||
using range_t = std::array<int, 10>;
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_move_forward(std::ptrdiff_t const n) {
|
||||
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
auto first = stride_counting_iterator(I(range.begin()));
|
||||
auto first = stride_counting_iterator(It(range.begin()));
|
||||
std::ranges::advance(first, n);
|
||||
|
||||
assert(first.base().base() == range.begin() + n);
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(first.stride_count() == 0 || first.stride_count() == 1);
|
||||
assert(first.stride_displacement() == 1);
|
||||
} else {
|
||||
|
@ -40,14 +40,14 @@ constexpr void check_move_forward(std::ptrdiff_t const n) {
|
|||
}
|
||||
}
|
||||
|
||||
template <std::bidirectional_iterator I>
|
||||
template <std::bidirectional_iterator It>
|
||||
constexpr void check_move_backward(std::ptrdiff_t const n) {
|
||||
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
auto first = stride_counting_iterator(I(range.begin() + n));
|
||||
auto first = stride_counting_iterator(It(range.begin() + n));
|
||||
std::ranges::advance(first, -n);
|
||||
assert(first.base().base() == range.begin());
|
||||
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(first.stride_count() == 0 || first.stride_count() == 1);
|
||||
assert(first.stride_displacement() == 1);
|
||||
} else {
|
||||
|
@ -83,7 +83,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
assert(test());
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -53,14 +53,15 @@ struct expected_t {
|
|||
std::ptrdiff_t result;
|
||||
};
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check_forward_sized_sentinel(std::ptrdiff_t const n, expected_t const expected, range_t& range) {
|
||||
auto current = stride_counting_iterator(I(range.begin()));
|
||||
auto const result = std::ranges::advance(current, n, distance_apriori_sentinel(range.size()));
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_forward_sized_sentinel(std::ptrdiff_t n, expected_t expected, range_t& range) {
|
||||
using Difference = std::iter_difference_t<It>;
|
||||
auto current = stride_counting_iterator(It(range.begin()));
|
||||
Difference const result = std::ranges::advance(current, n, distance_apriori_sentinel(range.size()));
|
||||
assert(current.base().base() == expected.coordinate);
|
||||
assert(result == expected.result);
|
||||
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(current.stride_count() == 0 || current.stride_count() == 1);
|
||||
assert(current.stride_displacement() == current.stride_count());
|
||||
} else {
|
||||
|
@ -69,10 +70,11 @@ constexpr void check_forward_sized_sentinel(std::ptrdiff_t const n, expected_t c
|
|||
}
|
||||
}
|
||||
|
||||
template <std::random_access_iterator I>
|
||||
constexpr void check_backward_sized_sentinel(std::ptrdiff_t const n, expected_t const expected, range_t& range) {
|
||||
auto current = stride_counting_iterator(I(range.end()));
|
||||
auto const result = std::ranges::advance(current, -n, stride_counting_iterator(I(range.begin())));
|
||||
template <std::random_access_iterator It>
|
||||
constexpr void check_backward_sized_sentinel(std::ptrdiff_t n, expected_t expected, range_t& range) {
|
||||
using Difference = std::iter_difference_t<It>;
|
||||
auto current = stride_counting_iterator(It(range.end()));
|
||||
Difference const result = std::ranges::advance(current, -n, stride_counting_iterator(It(range.begin())));
|
||||
assert(current.base().base() == expected.coordinate);
|
||||
assert(result == expected.result);
|
||||
|
||||
|
@ -80,19 +82,21 @@ constexpr void check_backward_sized_sentinel(std::ptrdiff_t const n, expected_t
|
|||
assert(current.stride_displacement() == current.stride_count());
|
||||
}
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check_forward(std::ptrdiff_t const n, expected_t const expected, range_t& range) {
|
||||
auto current = stride_counting_iterator(I(range.begin()));
|
||||
auto const result = std::ranges::advance(current, n, sentinel_wrapper(I(range.end())));
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_forward(std::ptrdiff_t n, expected_t expected, range_t& range) {
|
||||
using Difference = std::iter_difference_t<It>;
|
||||
auto current = stride_counting_iterator(It(range.begin()));
|
||||
Difference const result = std::ranges::advance(current, n, sentinel_wrapper(It(range.end())));
|
||||
assert(current.base().base() == expected.coordinate);
|
||||
assert(result == expected.result);
|
||||
assert(current.stride_count() == n - result);
|
||||
}
|
||||
|
||||
template <std::bidirectional_iterator I>
|
||||
constexpr void check_backward(std::ptrdiff_t const n, expected_t const expected, range_t& range) {
|
||||
auto current = stride_counting_iterator(I(range.end()));
|
||||
auto const result = std::ranges::advance(current, -n, stride_counting_iterator(I(range.begin())));
|
||||
template <std::bidirectional_iterator It>
|
||||
constexpr void check_backward(std::ptrdiff_t n, expected_t expected, range_t& range) {
|
||||
using Difference = std::iter_difference_t<It>;
|
||||
auto current = stride_counting_iterator(It(range.end()));
|
||||
Difference const result = std::ranges::advance(current, -n, stride_counting_iterator(It(range.begin())));
|
||||
assert(current.base().base() == expected.coordinate);
|
||||
assert(result == expected.result);
|
||||
assert(current.stride_count() == n + result);
|
||||
|
@ -139,7 +143,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
assert(test());
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -48,23 +48,23 @@ private:
|
|||
std::ptrdiff_t count_ = 0;
|
||||
};
|
||||
|
||||
template <std::input_or_output_iterator I, std::sentinel_for<I> S = I>
|
||||
template <std::input_or_output_iterator It, std::sentinel_for<It> Sent = It>
|
||||
constexpr void check_assignable_case(std::ptrdiff_t const n) {
|
||||
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
auto first = stride_counting_iterator(I(range.begin()));
|
||||
std::ranges::advance(first, stride_counting_iterator(S(I(range.begin() + n))));
|
||||
auto first = stride_counting_iterator(It(range.begin()));
|
||||
std::ranges::advance(first, stride_counting_iterator(Sent(It(range.begin() + n))));
|
||||
assert(first.base().base() == range.begin() + n);
|
||||
assert(first.stride_count() == 0); // because we got here by assigning from last, not by incrementing
|
||||
}
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_sized_sentinel_case(std::ptrdiff_t const n) {
|
||||
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
auto first = stride_counting_iterator(I(range.begin()));
|
||||
auto first = stride_counting_iterator(It(range.begin()));
|
||||
std::ranges::advance(first, distance_apriori_sentinel(n));
|
||||
|
||||
assert(first.base().base() == range.begin() + n);
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(first.stride_count() == 1);
|
||||
assert(first.stride_displacement() == 1);
|
||||
} else {
|
||||
|
@ -73,11 +73,11 @@ constexpr void check_sized_sentinel_case(std::ptrdiff_t const n) {
|
|||
}
|
||||
}
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_sentinel_case(std::ptrdiff_t const n) {
|
||||
auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
auto first = stride_counting_iterator(I(range.begin()));
|
||||
auto const last = I(range.begin() + n);
|
||||
auto first = stride_counting_iterator(It(range.begin()));
|
||||
auto const last = It(range.begin() + n);
|
||||
std::ranges::advance(first, sentinel_wrapper(last));
|
||||
assert(first.base() == last);
|
||||
assert(first.stride_count() == n);
|
||||
|
@ -107,7 +107,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
assert(test());
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <class ...Args>
|
||||
concept has_ranges_next = requires (Args ...args) {
|
||||
concept has_ranges_next = requires (Args&& ...args) {
|
||||
{ std::ranges::next(std::forward<Args>(args)...) };
|
||||
};
|
||||
|
||||
|
@ -31,4 +32,7 @@ static_assert(!has_ranges_next<It, It>);
|
|||
static_assert(!has_ranges_next<It, std::ptrdiff_t, It>);
|
||||
|
||||
// Test the test
|
||||
static_assert(has_ranges_next<int*, std::ptrdiff_t, int*>);
|
||||
using It2 = forward_iterator<int*>;
|
||||
static_assert(has_ranges_next<It2>);
|
||||
static_assert(has_ranges_next<It2, std::ptrdiff_t>);
|
||||
static_assert(has_ranges_next<It2, std::ptrdiff_t, It2>);
|
||||
|
|
|
@ -40,7 +40,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
test();
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,19 +19,19 @@
|
|||
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check_steps(I it, std::ptrdiff_t n, int const* expected) {
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_steps(It it, std::ptrdiff_t n, int const* expected) {
|
||||
{
|
||||
auto result = std::ranges::next(std::move(it), n);
|
||||
It result = std::ranges::next(std::move(it), n);
|
||||
assert(&*result == expected);
|
||||
}
|
||||
|
||||
// Count the number of operations
|
||||
{
|
||||
stride_counting_iterator strided_it(std::move(it));
|
||||
auto result = std::ranges::next(std::move(strided_it), n);
|
||||
stride_counting_iterator result = std::ranges::next(std::move(strided_it), n);
|
||||
assert(&*result == expected);
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(result.stride_count() == 1); // uses += exactly once
|
||||
assert(result.stride_displacement() == 1);
|
||||
} else {
|
||||
|
@ -68,7 +68,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
test();
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,26 +17,27 @@
|
|||
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check(I it, std::ptrdiff_t n, I last) {
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check(It it, std::ptrdiff_t n, It last) {
|
||||
{
|
||||
auto result = std::ranges::next(it, n, last);
|
||||
It result = std::ranges::next(it, n, last);
|
||||
assert(result == last);
|
||||
}
|
||||
|
||||
// Count the number of operations
|
||||
{
|
||||
stride_counting_iterator strided_it(it), strided_last(last);
|
||||
auto result = std::ranges::next(strided_it, n, strided_last);
|
||||
stride_counting_iterator<It> strided_it(it);
|
||||
stride_counting_iterator<It> strided_last(last);
|
||||
stride_counting_iterator<It> result = std::ranges::next(strided_it, n, strided_last);
|
||||
assert(result == strided_last);
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
if (n == 0 || n >= (last - it)) {
|
||||
assert(result.stride_count() == 0); // uses the assign-from-sentinel codepath
|
||||
} else {
|
||||
assert(result.stride_count() == 1); // uses += exactly once
|
||||
}
|
||||
} else {
|
||||
auto const abs_n = n < 0 ? -n : n;
|
||||
std::ptrdiff_t const abs_n = n < 0 ? -n : n;
|
||||
assert(result.stride_count() == abs_n);
|
||||
assert(result.stride_displacement() == n);
|
||||
}
|
||||
|
@ -65,8 +66,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
assert(test());
|
||||
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -46,10 +46,10 @@ private:
|
|||
std::ptrdiff_t count_ = 0;
|
||||
};
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check_assignable(I it, I last, int const* expected) {
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_assignable(It it, It last, int const* expected) {
|
||||
{
|
||||
auto result = std::ranges::next(std::move(it), std::move(last));
|
||||
It result = std::ranges::next(std::move(it), std::move(last));
|
||||
assert(&*result == expected);
|
||||
}
|
||||
|
||||
|
@ -63,8 +63,8 @@ constexpr void check_assignable(I it, I last, int const* expected) {
|
|||
}
|
||||
}
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check_sized_sentinel(I it, I last, int const* expected) {
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_sized_sentinel(It it, It last, int const* expected) {
|
||||
auto n = (last.base() - it.base());
|
||||
|
||||
{
|
||||
|
@ -80,7 +80,7 @@ constexpr void check_sized_sentinel(I it, I last, int const* expected) {
|
|||
auto result = std::ranges::next(std::move(strided_it), sent);
|
||||
assert(&*result == expected);
|
||||
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(result.stride_count() == 1); // should have used exactly one +=
|
||||
assert(result.stride_displacement() == 1);
|
||||
} else {
|
||||
|
@ -90,13 +90,13 @@ constexpr void check_sized_sentinel(I it, I last, int const* expected) {
|
|||
}
|
||||
}
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check_sentinel(I it, I last, int const* expected) {
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check_sentinel(It it, It last, int const* expected) {
|
||||
auto n = (last.base() - it.base());
|
||||
|
||||
{
|
||||
auto sent = sentinel_wrapper(last);
|
||||
auto result = std::ranges::next(std::move(it), sent);
|
||||
It result = std::ranges::next(std::move(it), sent);
|
||||
assert(&*result == expected);
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ constexpr void check_sentinel(I it, I last, int const* expected) {
|
|||
{
|
||||
auto strided_it = stride_counting_iterator(it);
|
||||
auto sent = sentinel_wrapper(stride_counting_iterator(last));
|
||||
auto result = std::ranges::next(std::move(strided_it), sent);
|
||||
stride_counting_iterator result = std::ranges::next(std::move(strided_it), sent);
|
||||
assert(&*result == expected);
|
||||
assert(result.stride_count() == n); // must have used ++ until it hit the sentinel
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
test();
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "test_iterators.h"
|
||||
|
||||
template <class ...Args>
|
||||
concept has_ranges_prev = requires (Args ...args) {
|
||||
concept has_ranges_prev = requires (Args&& ...args) {
|
||||
{ std::ranges::prev(std::forward<Args>(args)...) };
|
||||
};
|
||||
|
||||
|
@ -30,4 +30,7 @@ static_assert(!has_ranges_prev<It, std::ptrdiff_t>);
|
|||
static_assert(!has_ranges_prev<It, std::ptrdiff_t, It>);
|
||||
|
||||
// Test the test
|
||||
static_assert(has_ranges_prev<int*, std::ptrdiff_t, int*>);
|
||||
using It2 = bidirectional_iterator<int*>;
|
||||
static_assert(has_ranges_prev<It2>);
|
||||
static_assert(has_ranges_prev<It2, std::ptrdiff_t>);
|
||||
static_assert(has_ranges_prev<It2, std::ptrdiff_t, It2>);
|
||||
|
|
|
@ -20,9 +20,11 @@
|
|||
template <class It>
|
||||
constexpr void check() {
|
||||
int range[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
assert(std::ranges::prev(It(&range[1])) == It(&range[0]));
|
||||
assert(std::ranges::prev(It(&range[4])) == It(&range[3]));
|
||||
assert(std::ranges::prev(It(&range[5])) == It(&range[4]));
|
||||
assert(std::ranges::prev(It(&range[6])) == It(&range[5]));
|
||||
assert(std::ranges::prev(It(&range[10])) == It(&range[9]));
|
||||
}
|
||||
|
||||
constexpr bool test() {
|
||||
|
@ -34,7 +36,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
test();
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,17 +18,17 @@
|
|||
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <std::input_or_output_iterator I>
|
||||
constexpr void check(I it, std::ptrdiff_t n, int const* expected) {
|
||||
auto result = std::ranges::prev(stride_counting_iterator(std::move(it)), n);
|
||||
template <std::input_or_output_iterator It>
|
||||
constexpr void check(It it, std::ptrdiff_t n, int const* expected) {
|
||||
stride_counting_iterator result = std::ranges::prev(stride_counting_iterator(std::move(it)), n);
|
||||
assert(result.base().base() == expected);
|
||||
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
assert(result.stride_count() <= 1);
|
||||
// we can't say anything about the stride displacement, cause we could be using -= or +=.
|
||||
} else {
|
||||
auto const distance = n < 0 ? -n : n;
|
||||
assert(result.stride_count() == distance);
|
||||
std::ptrdiff_t const abs_n = n < 0 ? -n : n;
|
||||
assert(result.stride_count() == abs_n);
|
||||
assert(result.stride_displacement() == -n);
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
test();
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -17,21 +17,22 @@
|
|||
|
||||
#include "test_iterators.h"
|
||||
|
||||
template <std::bidirectional_iterator I>
|
||||
constexpr void check(I it, std::ptrdiff_t n, I last) {
|
||||
template <std::bidirectional_iterator It>
|
||||
constexpr void check(It it, std::ptrdiff_t n, It last) {
|
||||
auto abs = [](auto x) { return x < 0 ? -x : x; };
|
||||
|
||||
{
|
||||
auto result = std::ranges::prev(it, n, last);
|
||||
It result = std::ranges::prev(it, n, last);
|
||||
assert(result == last);
|
||||
}
|
||||
|
||||
// Count the number of operations
|
||||
{
|
||||
stride_counting_iterator strided_it(it), strided_last(last);
|
||||
auto result = std::ranges::prev(strided_it, n, strided_last);
|
||||
stride_counting_iterator<It> strided_it(it);
|
||||
stride_counting_iterator<It> strided_last(last);
|
||||
stride_counting_iterator<It> result = std::ranges::prev(strided_it, n, strided_last);
|
||||
assert(result == strided_last);
|
||||
if constexpr (std::random_access_iterator<I>) {
|
||||
if constexpr (std::random_access_iterator<It>) {
|
||||
if (n == 0 || abs(n) >= abs(last - it)) {
|
||||
assert(result.stride_count() == 0); // uses the assign-from-sentinel codepath
|
||||
} else {
|
||||
|
@ -62,8 +63,7 @@ constexpr bool test() {
|
|||
}
|
||||
|
||||
int main(int, char**) {
|
||||
static_assert(test());
|
||||
assert(test());
|
||||
|
||||
static_assert(test());
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -663,9 +663,9 @@ struct cpp20_input_iterator {
|
|||
|
||||
constexpr void operator++(int) { ++base_; }
|
||||
|
||||
[[nodiscard]] constexpr I const& base() const& { return base_; }
|
||||
constexpr I const& base() const& { return base_; }
|
||||
|
||||
[[nodiscard]] constexpr I base() && { return std::move(base_); }
|
||||
constexpr I base() && { return std::move(base_); }
|
||||
|
||||
private:
|
||||
I base_ = I();
|
||||
|
|
Loading…
Reference in New Issue