|
16 | 16 |
|
17 | 17 | #include <array>
|
18 | 18 | #include <cassert>
|
| 19 | +#include <climits> |
19 | 20 |
|
20 | 21 | #include "test_iterators.h"
|
21 | 22 |
|
@@ -100,6 +101,23 @@ constexpr void check_backward(std::ptrdiff_t n, expected_t expected, range_t& ra
|
100 | 101 | assert(current.stride_count() == -current.stride_displacement());
|
101 | 102 | }
|
102 | 103 |
|
| 104 | +struct iota_iterator { |
| 105 | + using difference_type = int; |
| 106 | + using value_type = int; |
| 107 | + |
| 108 | + constexpr int operator*() const { return x; } |
| 109 | + constexpr iota_iterator& operator++() { ++x; return *this; } |
| 110 | + constexpr iota_iterator operator++(int) { ++x; return iota_iterator{x - 1}; } |
| 111 | + constexpr bool operator==(const iota_iterator&) const = default; |
| 112 | + constexpr int operator-(const iota_iterator& that) const { return x - that.x; } |
| 113 | + constexpr iota_iterator& operator--() { --x; return *this; } |
| 114 | + constexpr iota_iterator operator--(int) { --x; return iota_iterator{x + 1}; } |
| 115 | + |
| 116 | + int x; |
| 117 | +}; |
| 118 | +static_assert(std::bidirectional_iterator<iota_iterator>); |
| 119 | +static_assert(std::sized_sentinel_for<iota_iterator, iota_iterator>); |
| 120 | + |
103 | 121 | constexpr bool test() {
|
104 | 122 | auto range = range_t{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
105 | 123 | check_forward_sized_sentinel<cpp17_input_iterator<range_t::const_iterator> >(1, {range.begin() + 1, 0}, range);
|
@@ -136,6 +154,19 @@ constexpr bool test() {
|
136 | 154 | check_forward<forward_iterator<range_t::const_iterator> >(1000, {range.end(), 990}, range);
|
137 | 155 | check_backward<bidirectional_iterator<range_t::const_iterator> >(1000, {range.begin(), -990}, range);
|
138 | 156 |
|
| 157 | + // regression-test that INT_MIN doesn't cause any undefined behavior |
| 158 | + { |
| 159 | + auto i = iota_iterator{+1}; |
| 160 | + assert(std::ranges::advance(i, INT_MIN, iota_iterator{-2}) == INT_MIN+3); |
| 161 | + assert(i == iota_iterator{-2}); |
| 162 | + i = iota_iterator{+1}; |
| 163 | + assert(std::ranges::advance(i, -2, iota_iterator{INT_MIN+1}) == 0); |
| 164 | + assert(i == iota_iterator{-1}); |
| 165 | + i = iota_iterator{+1}; |
| 166 | + assert(std::ranges::advance(i, INT_MIN, iota_iterator{INT_MIN+1}) == 0); |
| 167 | + assert(i == iota_iterator{INT_MIN+1}); |
| 168 | + } |
| 169 | + |
139 | 170 | return true;
|
140 | 171 | }
|
141 | 172 |
|
|
0 commit comments