[libcxx-commits] [libcxx] [libc++][ranges] Implement LWG4054 `Repeating a repeat_view should repeat the view` (PR #88606)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Apr 15 07:06:57 PDT 2024
https://github.com/yronglin updated https://github.com/llvm/llvm-project/pull/88606
>From 2a1bae736154c4aa7d0006c33655dfc1a4dc779e Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Sat, 13 Apr 2024 17:04:11 +0800
Subject: [PATCH 1/3] [libc++][ranges] Implement LWG4054 'Repeating a
repeat_view should repeat the view'
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
libcxx/docs/Status/Cxx2cIssues.csv | 2 +-
libcxx/include/__ranges/repeat_view.h | 7 ++++---
.../range.repeat.view/views_repeat.pass.cpp | 4 ++++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 008f7418ab9c05..b9afe5387f5724 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -60,7 +60,7 @@
"`4043 <https://wg21.link/LWG4043>`__","""ASCII"" is not a registered character encoding","Tokyo March 2024","|Nothing To Do|","",""
"`4045 <https://wg21.link/LWG4045>`__","``tuple`` can create dangling references from ``tuple-like``","Tokyo March 2024","","",""
"`4053 <https://wg21.link/LWG4053>`__","Unary call to ``std::views::repeat`` does not decay the argument","Tokyo March 2024","","","|ranges|"
-"`4054 <https://wg21.link/LWG4054>`__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","","","|ranges|"
+"`4054 <https://wg21.link/LWG4054>`__","Repeating a ``repeat_view`` should repeat the view","Tokyo March 2024","|Complete|","19.0","|ranges|"
"","","","","",""
"`3343 <https://wg21.link/LWG3343>`__","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 5caea757a39314..eb7fb1292316ee 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 <class _Tp>
_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<decay_t<_Tp>>(std::forward<_Tp>(__value))))
+ -> decltype( ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)))
+ { return ranges::repeat_view<decay_t<_Tp>>(std::forward<_Tp>(__value)); }
template <class _Tp, class _Bound>
_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/views_repeat.pass.cpp b/libcxx/test/std/ranges/range.factories/range.repeat.view/views_repeat.pass.cpp
index 9cbe505621b989..05c310bfca2089 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,10 @@ static_assert(!std::is_invocable_v<decltype(std::views::repeat), NonCopyable>);
// Tp is move_constructible
static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);
+// Test LWG4054 "Repeating a repeat_view should repeat the view"
+static_assert(std::is_same_v<decltype(std::views::repeat(std::views::repeat(42))),
+ std::ranges::repeat_view<std::ranges::repeat_view<int>>>);
+
constexpr bool test() {
assert(*std::views::repeat(33).begin() == 33);
assert(*std::views::repeat(33, 10).begin() == 33);
>From 6f50618054bc7a03dc8ddde2e4b5ca6b2ed8b749 Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Mon, 15 Apr 2024 21:56:12 +0800
Subject: [PATCH 2/3] Move tests from LWG4053
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
.../range.repeat.view/views_repeat.pass.cpp | 8 ++++++++
1 file changed, 8 insertions(+)
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 05c310bfca2089..10086fb454ac7b 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
@@ -64,6 +64,14 @@ static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);
static_assert(std::is_same_v<decltype(std::views::repeat(std::views::repeat(42))),
std::ranges::repeat_view<std::ranges::repeat_view<int>>>);
+// 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<const char*>;
+static_assert(std::same_as<decltype(std::views::repeat("foo", std::unreachable_sentinel)), RPV>); // OK
+static_assert(std::same_as<decltype(std::views::repeat(+"foo", std::unreachable_sentinel)), RPV>); // OK
+static_assert(std::same_as<decltype(std::views::repeat("foo")), RPV>); // OK since LWG4054
+static_assert(std::same_as<decltype(std::views::repeat(+"foo")), RPV>); // OK
+
constexpr bool test() {
assert(*std::views::repeat(33).begin() == 33);
assert(*std::views::repeat(33, 10).begin() == 33);
>From 71db176f6c9239f9a12b052849ac05fe227f630c Mon Sep 17 00:00:00 2001
From: yronglin <yronglin777 at gmail.com>
Date: Mon, 15 Apr 2024 22:06:37 +0800
Subject: [PATCH 3/3] format
Signed-off-by: yronglin <yronglin777 at gmail.com>
---
.../range.factories/range.repeat.view/views_repeat.pass.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
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 10086fb454ac7b..5d913fa197f5a9 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
@@ -64,7 +64,7 @@ static_assert(std::is_invocable_v<decltype(std::views::repeat), MoveOnly>);
static_assert(std::is_same_v<decltype(std::views::repeat(std::views::repeat(42))),
std::ranges::repeat_view<std::ranges::repeat_view<int>>>);
-// These cases are from LWG4053, but they are actually covered by the resolution of LWG4054,
+// 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<const char*>;
static_assert(std::same_as<decltype(std::views::repeat("foo", std::unreachable_sentinel)), RPV>); // OK
More information about the libcxx-commits
mailing list