diff --git a/libcxx/include/__ranges/concepts.h b/libcxx/include/__ranges/concepts.h --- a/libcxx/include/__ranges/concepts.h +++ b/libcxx/include/__ranges/concepts.h @@ -80,11 +80,11 @@ movable<_Tp> && enable_view<_Tp>; - template + template concept __simple_view = view<_Range> && range && same_as, iterator_t> && - same_as, iterator_t>; + same_as, sentinel_t>; // [range.refinements], other range refinements template diff --git a/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp b/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp --- a/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp +++ b/libcxx/test/libcxx/ranges/range.utility.helpers/simple_view.compile.pass.cpp @@ -39,7 +39,14 @@ sentinel_wrapper end() const; }; +struct WrongConstSentinel : std::ranges::view_base { + int *begin() const; + sentinel_wrapper end(); + sentinel_wrapper end() const; +}; + static_assert( std::ranges::__simple_view); static_assert(!std::ranges::__simple_view); static_assert(!std::ranges::__simple_view); -static_assert(!std::ranges::__simple_view); +static_assert( std::ranges::__simple_view); +static_assert(!std::ranges::__simple_view); diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp --- a/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.take/begin.pass.cpp @@ -21,6 +21,18 @@ #include "test_range.h" #include "types.h" +namespace { + +struct NonCommonSimpleView : std::ranges::view_base { + int* begin() const; + sentinel_wrapper end() const; + + // non const so that size_range is false + size_t size(); +}; + +} // namespace + constexpr bool test() { int buffer[8] = {1, 2, 3, 4, 5, 6, 7, 8}; @@ -63,6 +75,14 @@ ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator); } + // __simple_view && sized_range && !size_range + { + std::ranges::take_view tv(NonCommonSimpleView{}, 4); + ASSERT_SAME_TYPE(decltype(tv.begin()), std::counted_iterator); + // the optimal result should be int* but according to the c++20 standard, + // it returns std::counted_iterator + } + return true; }