Skip to content

Commit f14dc74

Browse files
add more valueless iterator test
1 parent a810c1b commit f14dc74

File tree

2 files changed

+123
-3
lines changed

2 files changed

+123
-3
lines changed

libcxx/include/__ranges/concat_view.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -577,7 +577,7 @@ class concat_view<_Views...>::__iterator : public __concat_view_iterator_categor
577577
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(
578578
!__x.__it_.valueless_by_exception(),
579579
"Trying to subtract a valuess iterators of concat_view from the default sentinel.");
580-
__x.__invoke_at_index([&]<std::size_t __index_x>() -> difference_type {
580+
return __x.__invoke_at_index([&]<std::size_t __index_x>() -> difference_type {
581581
auto __dx = ranges::distance(ranges::begin(std::get<__index_x>(__x.__parent_->__views_)), __x.__it_);
582582
difference_type __s = [&]<std::size_t __start, std::size_t __end>(this auto&& self) -> difference_type {
583583
if constexpr (__start < __end) {

libcxx/test/libcxx/ranges/range.adaptors/range.concat/iterator.valueless_by_exception.pass.cpp

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,12 @@ struct Iter {
101101
template <std::size_t X, std::size_t Y>
102102
friend difference_type operator-(Iter<X> a, Iter<Y> b);
103103

104-
friend bool operator==(Iter a, Iter b) = default;
104+
friend bool operator==(Iter a, Iter b) { return a.ptr_ == b.ptr_; };
105105
friend bool operator<(Iter a, Iter b) { return a.ptr_ < b.ptr_; }
106106
friend bool operator>(Iter a, Iter b) { return a.ptr_ > b.ptr_; }
107107
friend bool operator<=(Iter a, Iter b) { return a.ptr_ <= b.ptr_; }
108108
friend bool operator>=(Iter a, Iter b) { return a.ptr_ >= b.ptr_; }
109+
friend auto operator<=>(Iter a, Iter b) { return a.ptr_ <=> b.ptr_; }
109110
};
110111

111112
template <std::size_t X>
@@ -132,6 +133,7 @@ template <std::size_t N>
132133
struct Range : std::ranges::view_base {
133134
using iterator = Iter<N>;
134135
using const_iterator = Iter<N>;
136+
using sentinel = sentinel_wrapper<iterator>;
135137

136138
int* data_;
137139
std::size_t size_;
@@ -189,6 +191,22 @@ int main() {
189191
}
190192
}
191193

194+
{
195+
// valueless by exception test operator== with a sentinel
196+
flag = false;
197+
Range<0> r1;
198+
Range<1> r2;
199+
auto cv = std::views::concat(r1, r2);
200+
auto iter1 = cv.begin();
201+
auto iter2 = std::ranges::next(cv.begin(), 4);
202+
flag = true;
203+
try {
204+
iter1 = std::move(iter2);
205+
} catch (...) {
206+
TEST_LIBCPP_ASSERT_FAILURE([=] { (void)(iter1 == std::default_sentinel); }(), "valueless by exception");
207+
}
208+
}
209+
192210
{
193211
// valueless by exception test operator--
194212
flag = false;
@@ -202,7 +220,7 @@ int main() {
202220
try {
203221
iter1 = std::move(iter2);
204222
} catch (...) {
205-
TEST_LIBCPP_ASSERT_FAILURE([&] { iter1--; }(), "valueless by exception");
223+
TEST_LIBCPP_ASSERT_FAILURE([&] { --iter1; }(), "valueless by exception");
206224
}
207225
}
208226

@@ -240,6 +258,108 @@ int main() {
240258
}
241259
}
242260

261+
{
262+
// valueless by exception test operator>
263+
flag = false;
264+
Range<0> r1;
265+
Range<1> r2;
266+
267+
auto cv = std::views::concat(r1, r2);
268+
auto iter1 = cv.begin();
269+
auto iter2 = std::ranges::next(cv.begin(), 4);
270+
flag = true;
271+
try {
272+
iter1 = std::move(iter2);
273+
} catch (...) {
274+
TEST_LIBCPP_ASSERT_FAILURE([&] { (void)(iter1 > iter2); }(), "valueless by exception");
275+
}
276+
}
277+
278+
{
279+
// valueless by exception test operator>=
280+
flag = false;
281+
Range<0> r1;
282+
Range<1> r2;
283+
284+
auto cv = std::views::concat(r1, r2);
285+
auto iter1 = cv.begin();
286+
auto iter2 = std::ranges::next(cv.begin(), 4);
287+
flag = true;
288+
try {
289+
iter1 = std::move(iter2);
290+
} catch (...) {
291+
TEST_LIBCPP_ASSERT_FAILURE([&] { (void)(iter1 >= iter2); }(), "valueless by exception");
292+
}
293+
}
294+
295+
{
296+
// valueless by exception test operator<
297+
flag = false;
298+
Range<0> r1;
299+
Range<1> r2;
300+
301+
auto cv = std::views::concat(r1, r2);
302+
auto iter1 = cv.begin();
303+
auto iter2 = std::ranges::next(cv.begin(), 4);
304+
flag = true;
305+
try {
306+
iter1 = std::move(iter2);
307+
} catch (...) {
308+
TEST_LIBCPP_ASSERT_FAILURE([&] { (void)(iter1 < iter2); }(), "valueless by exception");
309+
}
310+
}
311+
312+
{
313+
// valueless by exception test operator<=
314+
flag = false;
315+
Range<0> r1;
316+
Range<1> r2;
317+
318+
auto cv = std::views::concat(r1, r2);
319+
auto iter1 = cv.begin();
320+
auto iter2 = std::ranges::next(cv.begin(), 4);
321+
flag = true;
322+
try {
323+
iter1 = std::move(iter2);
324+
} catch (...) {
325+
TEST_LIBCPP_ASSERT_FAILURE([&] { (void)(iter1 <= iter2); }(), "valueless by exception");
326+
}
327+
}
328+
329+
{
330+
// valueless by exception test operator- between two iterators
331+
flag = false;
332+
Range<0> r1;
333+
Range<1> r2;
334+
335+
auto cv = std::views::concat(r1, r2);
336+
auto iter1 = cv.begin();
337+
auto iter2 = std::ranges::next(cv.begin(), 4);
338+
flag = true;
339+
try {
340+
iter1 = std::move(iter2);
341+
} catch (...) {
342+
TEST_LIBCPP_ASSERT_FAILURE([&] { (void)(iter1 - iter2); }(), "valueless by exception");
343+
}
344+
}
345+
346+
{
347+
// valueless by exception test operator- with a constant
348+
flag = false;
349+
Range<0> r1;
350+
Range<1> r2;
351+
352+
auto cv = std::views::concat(r1, r2);
353+
auto iter1 = cv.begin();
354+
auto iter2 = std::ranges::next(cv.begin(), 4);
355+
flag = true;
356+
try {
357+
iter1 = std::move(iter2);
358+
} catch (...) {
359+
TEST_LIBCPP_ASSERT_FAILURE([&] { (void)(iter1 - 1); }(), "valueless by exception");
360+
}
361+
}
362+
243363
{
244364
// valueless by exception test constructor
245365
flag = false;

0 commit comments

Comments
 (0)