diff --git a/libcxx/include/__ranges/common_view.h b/libcxx/include/__ranges/common_view.h index 133236dd1d78a..54bb8039b48af 100644 --- a/libcxx/include/__ranges/common_view.h +++ b/libcxx/include/__ranges/common_view.h @@ -58,7 +58,9 @@ class common_view : public view_interface> { _LIBCPP_HIDE_FROM_ABI constexpr _View base() && { return std::move(__base_); } - _LIBCPP_HIDE_FROM_ABI constexpr auto begin() { + _LIBCPP_HIDE_FROM_ABI constexpr auto begin() + requires(!__simple_view<_View>) + { if constexpr (random_access_range<_View> && sized_range<_View>) return ranges::begin(__base_); else @@ -74,7 +76,9 @@ class common_view : public view_interface> { return common_iterator, sentinel_t>(ranges::begin(__base_)); } - _LIBCPP_HIDE_FROM_ABI constexpr auto end() { + _LIBCPP_HIDE_FROM_ABI constexpr auto end() + requires(!__simple_view<_View>) + { if constexpr (random_access_range<_View> && sized_range<_View>) return ranges::begin(__base_) + ranges::size(__base_); else diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/begin.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.common.view/begin.pass.cpp index 96116dc37553a..b13b4b4e69e71 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.common.view/begin.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/begin.pass.cpp @@ -51,6 +51,12 @@ constexpr bool test() { assert(begin == std::ranges::begin(view)); } + { + NonSimpleNonCommonView view{buf, buf + 8}; + std::ranges::common_view common(view); + static_assert(!std::is_same_v); + } + return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/end.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.common.view/end.pass.cpp index 0565ed02f2716..a80f85defaeb5 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.common.view/end.pass.cpp +++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/end.pass.cpp @@ -39,6 +39,12 @@ constexpr bool test() { assert(base(end) == buf + 8); } + { + NonSimpleNonCommonView view{buf, buf + 8}; + std::ranges::common_view common(view); + static_assert(!std::is_same_v); + } + return true; } diff --git a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h index 18354483fd329..cae586f8c8990 100644 --- a/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h +++ b/libcxx/test/std/ranges/range.adaptors/range.common.view/types.h @@ -90,4 +90,37 @@ struct NonCommonView : std::ranges::view_base { static_assert( std::ranges::view); static_assert(!std::ranges::common_range); +template +concept HasConstBegin = requires(const T& ct) { ct.begin(); }; + +template +concept HasBegin = requires(T& t) { t.begin(); }; + +template +concept HasConstAndNonConstBegin = HasConstBegin && requires(T& t, const T& ct) { + requires !std::same_as; +}; + +template +concept HasOnlyNonConstBegin = HasBegin && !HasConstBegin; + +template +concept HasOnlyConstBegin = HasConstBegin && !HasConstAndNonConstBegin; + +struct NonSimpleNonCommonView : std::ranges::view_base { + int* begin_; + int* end_; + constexpr explicit NonSimpleNonCommonView(int* b, int* e) : begin_(b), end_(e) {} + constexpr auto begin() const { return static_cast(begin_); } + constexpr auto end() const { return sentinel_wrapper(end_); } + constexpr int* begin() { return begin_; } + constexpr auto end() { return sentinel_wrapper(end_); } +}; + +static_assert(!HasOnlyNonConstBegin>); +static_assert(!HasOnlyConstBegin>); +static_assert(HasConstAndNonConstBegin>); +static_assert(HasConstBegin const>); +static_assert(HasOnlyConstBegin const>); + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_COMMON_VIEW_TYPES_H