From 4f1a78bf028bf20345bd3d7c238dd522b1505241 Mon Sep 17 00:00:00 2001 From: yronglin Date: Sat, 13 Apr 2024 17:52:17 +0800 Subject: [PATCH 1/5] [libc++][ranges] Implement LWG4053 'Unary call to std::views::repeat does not decay the argument' Signed-off-by: yronglin --- libcxx/docs/Status/Cxx2cIssues.csv | 2 +- libcxx/include/__ranges/repeat_view.h | 4 ++-- .../range.repeat.view/views_repeat.pass.cpp | 8 ++++++++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index 008f7418ab9c0..0c4034a1b412c 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -59,7 +59,7 @@ "`4038 `__","``std::text_encoding::aliases_view`` should have constexpr iterators","Tokyo March 2024","","","" "`4043 `__","""ASCII"" is not a registered character encoding","Tokyo March 2024","|Nothing To Do|","","" "`4045 `__","``tuple`` can create dangling references from ``tuple-like``","Tokyo March 2024","","","" -"`4053 `__","Unary call to ``std::views::repeat`` does not decay the argument","Tokyo March 2024","","","|ranges|" +"`4053 `__","Unary call to ``std::views::repeat`` does not decay the argument","Tokyo March 2024","|Complete|","19.0","|ranges|" "`4054 `__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","","","|ranges|" "","","","","","" "`3343 `__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Yet Adopted","|Complete|","16.0","" diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index 5caea757a3931..2544cf496c838 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -127,8 +127,8 @@ class _LIBCPP_ABI_LLVM18_NO_UNIQUE_ADDRESS repeat_view : public view_interface -repeat_view(_Tp, _Bound) -> repeat_view<_Tp, _Bound>; +template +repeat_view(_Tp, _Bound = _Bound()) -> repeat_view<_Tp, _Bound>; // [range.repeat.iterator] template diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp index 9cbe505621b98..9077f9a0c607c 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp @@ -60,6 +60,14 @@ static_assert(!std::is_invocable_v); // Tp is move_constructible static_assert(std::is_invocable_v); +// LWG4053: Unary call to std::views::repeat does not decay the argument +using RPV = std::ranges::repeat_view; + +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK since LWG4053 +static_assert(std::same_as); // OK + constexpr bool test() { assert(*std::views::repeat(33).begin() == 33); assert(*std::views::repeat(33, 10).begin() == 33); From 28464ecfc39b344bcd4c4c569bee9c320fa899b3 Mon Sep 17 00:00:00 2001 From: yronglin Date: Sun, 14 Apr 2024 10:40:42 +0800 Subject: [PATCH 2/5] Format Signed-off-by: yronglin --- .../range.factories/range.repeat.view/views_repeat.pass.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp index 9077f9a0c607c..703ea9d7053f8 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp @@ -63,10 +63,10 @@ static_assert(std::is_invocable_v); // LWG4053: Unary call to std::views::repeat does not decay the argument using RPV = std::ranges::repeat_view; -static_assert(std::same_as); // OK +static_assert(std::same_as); // OK static_assert(std::same_as); // OK -static_assert(std::same_as); // OK since LWG4053 -static_assert(std::same_as); // OK +static_assert(std::same_as); // OK since LWG4053 +static_assert(std::same_as); // OK constexpr bool test() { assert(*std::views::repeat(33).begin() == 33); From 5e428e9e971e24ed6dfc2342bf00840b020f6677 Mon Sep 17 00:00:00 2001 From: yronglin Date: Mon, 15 Apr 2024 22:05:24 +0800 Subject: [PATCH 3/5] Add CTAD test Signed-off-by: yronglin --- .../range.repeat.view/ctad.compile.pass.cpp | 3 +++ .../range.repeat.view/views_repeat.pass.cpp | 8 -------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp index 454bac6e03e51..73802dbd7984a 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp @@ -24,4 +24,7 @@ static_assert(std::same_as>); static_assert(std::same_as>); static_assert(std::same_as>); + +// LWG4053 and LWG4054 "Repeating a repeat_view should repeat the view" +static_assert(std::same_as>>); // clang-format on diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp index 703ea9d7053f8..9cbe505621b98 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp @@ -60,14 +60,6 @@ static_assert(!std::is_invocable_v); // Tp is move_constructible static_assert(std::is_invocable_v); -// LWG4053: Unary call to std::views::repeat does not decay the argument -using RPV = std::ranges::repeat_view; - -static_assert(std::same_as); // OK -static_assert(std::same_as); // OK -static_assert(std::same_as); // OK since LWG4053 -static_assert(std::same_as); // OK - constexpr bool test() { assert(*std::views::repeat(33).begin() == 33); assert(*std::views::repeat(33, 10).begin() == 33); From 04452dd9f15e9d9df44d677edafff46e0e88918b Mon Sep 17 00:00:00 2001 From: yronglin Date: Mon, 15 Apr 2024 23:50:48 +0800 Subject: [PATCH 4/5] [libc++][ranges] Implement LWG4054 'Repeating a repeat_view should repeat the view' Signed-off-by: yronglin --- libcxx/docs/Status/Cxx2cIssues.csv | 2 +- libcxx/include/__ranges/repeat_view.h | 7 ++++--- .../range.repeat.view/ctad.compile.pass.cpp | 2 +- .../range.repeat.view/views_repeat.pass.cpp | 12 ++++++++++++ 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv index 0c4034a1b412c..cb9c6b165bd00 100644 --- a/libcxx/docs/Status/Cxx2cIssues.csv +++ b/libcxx/docs/Status/Cxx2cIssues.csv @@ -60,7 +60,7 @@ "`4043 `__","""ASCII"" is not a registered character encoding","Tokyo March 2024","|Nothing To Do|","","" "`4045 `__","``tuple`` can create dangling references from ``tuple-like``","Tokyo March 2024","","","" "`4053 `__","Unary call to ``std::views::repeat`` does not decay the argument","Tokyo March 2024","|Complete|","19.0","|ranges|" -"`4054 `__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","","","|ranges|" +"`4054 `__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","|Complete|","19.0","|ranges|" "","","","","","" "`3343 `__","Ordering of calls to ``unlock()`` and ``notify_all()`` in Effects element of ``notify_all_at_thread_exit()`` should be reversed","Not Yet Adopted","|Complete|","16.0","" "XXXX","","The sys_info range should be affected by save","Not Yet Adopted","|Complete|","19.0" diff --git a/libcxx/include/__ranges/repeat_view.h b/libcxx/include/__ranges/repeat_view.h index 2544cf496c838..6f1241adb341e 100644 --- a/libcxx/include/__ranges/repeat_view.h +++ b/libcxx/include/__ranges/repeat_view.h @@ -22,6 +22,7 @@ #include <__ranges/iota_view.h> #include <__ranges/movable_box.h> #include <__ranges/view_interface.h> +#include <__type_traits/decay.h> #include <__type_traits/is_object.h> #include <__type_traits/make_unsigned.h> #include <__type_traits/remove_cv.h> @@ -230,9 +231,9 @@ namespace __repeat { struct __fn { template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value) - noexcept(noexcept(ranges::repeat_view(std::forward<_Tp>(__value)))) - -> decltype( ranges::repeat_view(std::forward<_Tp>(__value))) - { return ranges::repeat_view(std::forward<_Tp>(__value)); } + noexcept(noexcept(ranges::repeat_view>(std::forward<_Tp>(__value)))) + -> decltype( ranges::repeat_view>(std::forward<_Tp>(__value))) + { return ranges::repeat_view>(std::forward<_Tp>(__value)); } template _LIBCPP_NODISCARD_EXT _LIBCPP_HIDE_FROM_ABI static constexpr auto operator()(_Tp&& __value, _Bound&& __bound_sentinel) diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp index 73802dbd7984a..44560dd7a1140 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp @@ -26,5 +26,5 @@ static_assert(std::same_as>); // LWG4053 and LWG4054 "Repeating a repeat_view should repeat the view" -static_assert(std::same_as>>); +static_assert(std::same_as>>); // clang-format on diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp index 9cbe505621b98..5d913fa197f5a 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp @@ -60,6 +60,18 @@ static_assert(!std::is_invocable_v); // Tp is move_constructible static_assert(std::is_invocable_v); +// Test LWG4054 "Repeating a repeat_view should repeat the view" +static_assert(std::is_same_v>>); + +// These cases are from LWG4053, but they are actually covered by the resolution of LWG4054, +// and the resolution of LWG4053 only affects CTAD. +using RPV = std::ranges::repeat_view; +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK since LWG4054 +static_assert(std::same_as); // OK + constexpr bool test() { assert(*std::views::repeat(33).begin() == 33); assert(*std::views::repeat(33, 10).begin() == 33); From ea5e01bb0e497dfbc9fa05442995777f472db9e1 Mon Sep 17 00:00:00 2001 From: yronglin Date: Tue, 16 Apr 2024 20:00:04 +0800 Subject: [PATCH 5/5] Address review comments Signed-off-by: yronglin --- .../range.repeat.view/ctad.compile.pass.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp index 44560dd7a1140..97b74289619dd 100644 --- a/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp +++ b/libcxx/test/std/ranges/range.factories/range.repeat.view/ctad.compile.pass.cpp @@ -25,6 +25,9 @@ static_assert(std::same_as>); static_assert(std::same_as>); -// LWG4053 and LWG4054 "Repeating a repeat_view should repeat the view" -static_assert(std::same_as>>); +using RPV = std::ranges::repeat_view; +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK +static_assert(std::same_as); // OK since LWG4053 +static_assert(std::same_as); // OK // clang-format on