From 9a60b2fa0c414c4230801e792be28a92439dae8f Mon Sep 17 00:00:00 2001 From: Nhat Nguyen Date: Sun, 8 Feb 2026 20:17:30 -0500 Subject: [PATCH] [libc++] LWG4012: common_view::begin/end are missing the simple-view check (#153674) close #105320 --- libcxx/docs/Status/Cxx2cIssues.csv | 2 +- .../range.common.view/begin.pass.cpp | 6 ++++ .../range.common.view/end.pass.cpp | 6 ++++ .../range.adaptors/range.common.view/types.h | 33 +++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index 101a708b7b2d..60b1bd6ff70d 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -46,7 +46,7 @@ "`LWG3975 `__","Specializations of ``basic_format_context`` should not be permitted","2024-03 (Tokyo)","|Nothing To Do|","","`#105317 `__","" "`LWG3984 `__","``ranges::to``'s recursion branch may be ill-formed","2024-03 (Tokyo)","|Complete|","19","`#105318 `__","" "`LWG4011 `__","""`Effects`: Equivalent to return"" in ``[span.elem]``","2024-03 (Tokyo)","|Nothing To Do|","","`#105319 `__","" -"`LWG4012 `__","``common_view::begin/end`` are missing the ``simple-view`` check","2024-03 (Tokyo)","","","`#105320 `__","" +"`LWG4012 `__","``common_view::begin/end`` are missing the ``simple-view`` check","2024-03 (Tokyo)","|Complete|","23","`#105320 `__","" "`LWG4013 `__","``lazy_split_view::outer-iterator::value_type`` should not provide default constructor","2024-03 (Tokyo)","","","`#105321 `__","" "`LWG4016 `__","container-insertable checks do not match what container-inserter does","2024-03 (Tokyo)","|Complete|","20","`#105322 `__","" "`LWG4023 `__","Preconditions of ``std::basic_streambuf::setg/setp``","2024-03 (Tokyo)","|Complete|","19","`#105323 `__","" 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 96116dc37553..b13b4b4e69e7 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 0565ed02f271..a80f85defaeb 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 18354483fd32..56f2f6ad5fcb 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>); +static_assert(HasOnlyConstBegin>); + #endif // TEST_STD_RANGES_RANGE_ADAPTORS_RANGE_COMMON_VIEW_TYPES_H