|
13 | 13 | #include <array> |
14 | 14 | #include <cassert> |
15 | 15 | #include "test_macros.h" |
16 | | -#include "../types.h" |
| 16 | +#include "../../range_adaptor_types.h" |
| 17 | + |
| 18 | +template <class Iter> |
| 19 | +concept canDecrement = requires(Iter it) { --it; } || requires(Iter it) { it--; }; |
| 20 | + |
| 21 | +struct NonBidi : IntBufferView { |
| 22 | + using IntBufferView::IntBufferView; |
| 23 | + using iterator = forward_iterator<int*>; |
| 24 | + constexpr iterator begin() const { return iterator(buffer_); } |
| 25 | + constexpr sentinel_wrapper<iterator> end() const { return sentinel_wrapper<iterator>(iterator(buffer_ + size_)); } |
| 26 | +}; |
| 27 | + |
| 28 | +constexpr bool test() { |
| 29 | + std::array<int, 4> a{1, 2, 3, 4}; |
| 30 | + std::array<int, 4> b{5, 6, 7, 8}; |
17 | 31 |
|
18 | | -constexpr void test() { |
19 | 32 | // Test with a single view |
20 | 33 | { |
21 | | - constexpr static std::array<int, 5> array{0, 1, 2, 3, 4}; |
22 | | - constexpr static std::ranges::concat_view view(std::views::all(array)); |
| 34 | + std::ranges::concat_view view(a); |
23 | 35 | auto it = std::ranges::next(view.begin(), view.end()); |
24 | 36 | assert(it == view.end()); |
25 | 37 |
|
26 | 38 | auto& result = --it; |
27 | 39 | ASSERT_SAME_TYPE(decltype(result)&, decltype(--it)); |
28 | 40 | assert(&result == &it); |
29 | | - assert(result == view.begin() + 4); |
| 41 | + assert(result == view.begin() + 3); |
30 | 42 | } |
31 | 43 |
|
32 | 44 | // Test with more than one view |
33 | 45 | { |
34 | | - constexpr static std::array<int, 3> array{0, 1, 2}; |
35 | | - constexpr static std::array<int, 3> array1{3, 4, 5}; |
36 | | - constexpr std::ranges::concat_view view(std::views::all(array), std::views::all(array1)); |
| 46 | + std::ranges::concat_view view(a, b); |
37 | 47 | auto it = std::ranges::next(view.begin(), view.end()); |
38 | 48 | assert(it == view.end()); |
39 | 49 |
|
40 | 50 | auto& result = --it; |
41 | 51 | assert(&result == &it); |
42 | 52 |
|
43 | 53 | --it; |
44 | | - assert(*it == 4); |
45 | | - assert(it == view.begin() + 4); |
| 54 | + assert(*it == 7); |
| 55 | + assert(it == view.begin() + 6); |
46 | 56 | } |
47 | 57 |
|
48 | 58 | // Test going forward and then backward on the same iterator |
49 | 59 | { |
50 | | - constexpr static std::array<int, 5> array{0, 1, 2, 3, 4}; |
51 | | - constexpr static std::ranges::concat_view view(std::views::all(array)); |
| 60 | + std::ranges::concat_view view(a, b); |
52 | 61 | auto it = view.begin(); |
53 | 62 | ++it; |
54 | 63 | --it; |
55 | | - assert(*it == array[0]); |
| 64 | + assert(*it == a[0]); |
56 | 65 | ++it; |
57 | 66 | ++it; |
58 | 67 | --it; |
59 | | - assert(*it == array[1]); |
| 68 | + assert(*it == a[1]); |
60 | 69 | ++it; |
61 | 70 | ++it; |
62 | 71 | --it; |
63 | | - assert(*it == array[2]); |
| 72 | + assert(*it == a[2]); |
64 | 73 | ++it; |
65 | 74 | ++it; |
66 | 75 | --it; |
67 | | - assert(*it == array[3]); |
| 76 | + assert(*it == a[3]); |
68 | 77 | } |
69 | 78 |
|
70 | 79 | // Test post-decrement |
71 | 80 | { |
72 | | - std::array<int, 5> array{0, 1, 2, 3, 4}; |
73 | | - std::ranges::concat_view view(std::views::all(array)); |
| 81 | + std::ranges::concat_view view(a, b); |
74 | 82 | auto it = std::ranges::next(view.begin(), view.end()); |
75 | 83 | assert(it == view.end()); // test the test |
76 | 84 | auto result = it--; |
77 | 85 | ASSERT_SAME_TYPE(decltype(result), decltype(it--)); |
78 | 86 | assert(result == view.end()); |
79 | 87 | assert(it == (result - 1)); |
80 | 88 | } |
| 89 | + |
| 90 | + // bidirectional |
| 91 | + { |
| 92 | + int buffer[2] = {1, 2}; |
| 93 | + |
| 94 | + std::ranges::concat_view v(BidiCommonView{buffer}, std::views::iota(0, 5)); |
| 95 | + auto it = v.begin(); |
| 96 | + using Iter = decltype(it); |
| 97 | + |
| 98 | + ++it; |
| 99 | + ++it; |
| 100 | + |
| 101 | + static_assert(std::is_same_v<decltype(--it), Iter&>); |
| 102 | + auto& it_ref = --it; |
| 103 | + assert(&it_ref == &it); |
| 104 | + |
| 105 | + assert(it == ++v.begin()); |
| 106 | + |
| 107 | + static_assert(std::is_same_v<decltype(it--), Iter>); |
| 108 | + auto tmp = it--; |
| 109 | + assert(it == v.begin()); |
| 110 | + assert(tmp == ++v.begin()); |
| 111 | + } |
| 112 | + |
| 113 | + // non bidirectional |
| 114 | + { |
| 115 | + int buffer[3] = {4, 5, 6}; |
| 116 | + std::ranges::zip_view v(a, NonBidi{buffer}); |
| 117 | + using Iter = std::ranges::iterator_t<decltype(v)>; |
| 118 | + static_assert(!canDecrement<Iter>); |
| 119 | + } |
| 120 | + |
| 121 | + return true; |
81 | 122 | } |
82 | 123 |
|
83 | 124 | int main(int, char**) { |
84 | 125 | test(); |
| 126 | + static_assert(test()); |
85 | 127 | return 0; |
86 | 128 | } |
0 commit comments