Skip to content

Commit ccb0ed5

Browse files
committed
[libc++][NFC] Check for take_view returning different types depending on simple_view-ness
Add a check to make sure that an instance of a take_view::_iterator<false> is returned when the base type is not a simple view nor a sized view.
1 parent 283feb4 commit ccb0ed5

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

libcxx/test/std/ranges/range.adaptors/range.take/end.pass.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,27 @@ constexpr bool test() {
6969
assert(tv.end() == std::ranges::next(tv.begin(), 8));
7070
}
7171

72+
// Check that (non-)simple, non-sized views have different types for their end() member function.
73+
{
74+
// These assertions must be true in order to trigger the different paths through the end member function
75+
// that will return values with different types:
76+
static_assert(!simple_view<NonSimpleViewNonSized>);
77+
static_assert(!std::ranges::sized_range<NonSimpleViewNonSized>);
78+
static_assert(simple_view<SimpleViewNonSized>);
79+
static_assert(std::ranges::range<const SimpleViewNonSized>);
80+
static_assert(!std::ranges::sized_range<const SimpleViewNonSized>);
81+
82+
std::ranges::take_view<NonSimpleViewNonSized> tvns(NonSimpleViewNonSized{buffer, buffer + 8}, 0);
83+
std::ranges::take_view<SimpleViewNonSized> tvs(SimpleViewNonSized{buffer, buffer + 8}, 0);
84+
85+
// __iterator<false> has base with type std::ranges::sentinel_t<NonSimpleViewNonSized>; adding a const qualifier
86+
// would change the equality.
87+
static_assert(!std::is_same_v<decltype(tvns.end().base()), std::ranges::sentinel_t<const NonSimpleViewNonSized>>);
88+
// __iterator<true> has base with type std::ranges::sentinel_t<const NonSimpleViewNonSized>; adding a const qualifier
89+
// would not change the equality.
90+
static_assert(std::is_same_v<decltype(tvs.end().base()), std::ranges::sentinel_t<const SimpleViewNonSized>>);
91+
}
92+
7293
return true;
7394
}
7495

libcxx/test/std/ranges/range.adaptors/range.take/types.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,37 @@ struct View : std::ranges::view_base {
6565
int* end_;
6666
};
6767

68+
template <bool Simple>
69+
struct InputView : std::ranges::view_base {
70+
constexpr explicit InputView(int* b, int* e) : begin_(b), end_(e) {}
71+
72+
constexpr common_input_iterator<int*> begin() const { return common_input_iterator<int*>(begin_); }
73+
constexpr common_input_iterator<int*> end() const { return common_input_iterator<int*>(end_); }
74+
75+
constexpr common_input_iterator<const int*> begin()
76+
requires(!Simple)
77+
{
78+
return common_input_iterator<const int*>(begin_);
79+
}
80+
constexpr common_input_iterator<const int*> end()
81+
requires(!Simple)
82+
{
83+
return common_input_iterator<const int*>(end_);
84+
}
85+
86+
private:
87+
int* begin_;
88+
int* end_;
89+
};
90+
91+
using NonSimpleViewNonSized = InputView<false>;
92+
static_assert(std::ranges::view<NonSimpleViewNonSized>);
93+
static_assert(!simple_view<NonSimpleViewNonSized>);
94+
static_assert(!std::ranges::sized_range<NonSimpleViewNonSized>);
95+
96+
using SimpleViewNonSized = InputView<true>;
97+
static_assert(!std::ranges::sized_range<SimpleViewNonSized>);
98+
static_assert(std::ranges::view<SimpleViewNonSized>);
99+
static_assert(simple_view<SimpleViewNonSized>);
100+
68101
#endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_TAKE_TYPES_H

0 commit comments

Comments
 (0)