[libcxx-commits] [libcxx] [libc++] Fix the handling of `views::take` for `iota_view` (PR #75683)

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon Dec 18 12:39:28 PST 2023


https://github.com/ldionne updated https://github.com/llvm/llvm-project/pull/75683

>From c9c5860cfa090a7ab5fb758e6ba8ad0e37ac9d68 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 16 Dec 2023 11:15:48 +0800
Subject: [PATCH 1/2] Fix the handling of `views::take` for `iota_view`

---
 libcxx/include/__ranges/take_view.h                 | 13 +++++++------
 .../range.adaptors/range.take/adaptor.pass.cpp      |  5 ++---
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 4fd1d8b9ab8377..3912ec733b9283 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -282,15 +282,16 @@ struct __fn {
             class _Dist     = range_difference_t<_Range>>
     requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
              __is_iota_specialization<_RawRange>)
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto
-  operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(ranges::iota_view(
-      *ranges::begin(__rng), *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))))
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(
+      ranges::iota_view(*ranges::begin(__rng),
+                        *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))))
       -> decltype(ranges::iota_view(
           // Note: deliberately not forwarding `__rng` to guard against double moves.
           *ranges::begin(__rng),
-          *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))) {
-    return ranges::iota_view(*ranges::begin(__rng),
-                             *ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)));
+          *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))) {
+    return ranges::iota_view(
+        *ranges::begin(__rng),
+        *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))));
   }
   // clang-format off
 #if _LIBCPP_STD_VER >= 23
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
index 8ffac8d8fab153..7c108bd5d0a9aa 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
@@ -172,9 +172,8 @@ constexpr bool test() {
   // `views::take(iota_view, n)` returns an `iota_view`.
   {
     auto iota = std::views::iota(1, 8);
-    // The second template argument of the resulting `iota_view` is different because it has to be able to hold
-    // the `range_difference_t` of the input `iota_view`.
-    using Result = std::ranges::iota_view<int, std::ranges::range_difference_t<decltype(iota)>>;
+    // The second template argument of the resulting `iota_view` is same as the first.
+    using Result = std::ranges::iota_view<int, int>;
     std::same_as<Result> decltype(auto) result = iota | std::views::take(3);
     assert(result.size() == 3);
   }

>From 5b4c711097edcd8a6ef8f9af7ddbfa1e35197514 Mon Sep 17 00:00:00 2001
From: "A. Jiang" <de34 at live.cn>
Date: Sat, 16 Dec 2023 11:29:00 +0800
Subject: [PATCH 2/2] clang-format off

The original indent seems intended.
---
 libcxx/include/__ranges/take_view.h           | 35 +++++++++++--------
 .../range.take/adaptor.pass.cpp               |  2 +-
 2 files changed, 22 insertions(+), 15 deletions(-)

diff --git a/libcxx/include/__ranges/take_view.h b/libcxx/include/__ranges/take_view.h
index 3912ec733b9283..83ed5ca0ebd390 100644
--- a/libcxx/include/__ranges/take_view.h
+++ b/libcxx/include/__ranges/take_view.h
@@ -276,24 +276,31 @@ struct __fn {
   }
 
   // [range.take.overview]: the `iota_view` case.
+  // clang-format off
   template <class _Range,
             convertible_to<range_difference_t<_Range>> _Np,
             class _RawRange = remove_cvref_t<_Range>,
             class _Dist     = range_difference_t<_Range>>
-    requires(!__is_empty_view<_RawRange> && random_access_range<_RawRange> && sized_range<_RawRange> &&
-             __is_iota_specialization<_RawRange>)
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI constexpr auto operator()(_Range&& __rng, _Np&& __n) const noexcept(noexcept(
-      ranges::iota_view(*ranges::begin(__rng),
-                        *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))))
-      -> decltype(ranges::iota_view(
-          // Note: deliberately not forwarding `__rng` to guard against double moves.
-          *ranges::begin(__rng),
-          *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))))) {
-    return ranges::iota_view(
-        *ranges::begin(__rng),
-        *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n))));
-  }
-  // clang-format off
+    requires (!__is_empty_view<_RawRange> &&
+              random_access_range<_RawRange> &&
+              sized_range<_RawRange> &&
+              __is_iota_specialization<_RawRange>)
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI
+  constexpr auto operator()(_Range&& __rng, _Np&& __n) const
+    noexcept(noexcept(ranges::iota_view(
+                              *ranges::begin(__rng),
+                              *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+                              )))
+    -> decltype(      ranges::iota_view(
+                              // Note: deliberately not forwarding `__rng` to guard against double moves.
+                              *ranges::begin(__rng),
+                              *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+                              ))
+    { return          ranges::iota_view(
+                              *ranges::begin(__rng),
+                              *(ranges::begin(__rng) + std::min<_Dist>(ranges::distance(__rng), std::forward<_Np>(__n)))
+                              ); }
+
 #if _LIBCPP_STD_VER >= 23
   // [range.take.overview]: the `repeat_view` "_RawRange models sized_range" case.
   template <class _Range,
diff --git a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
index 7c108bd5d0a9aa..bb5b5f5ff4909a 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.take/adaptor.pass.cpp
@@ -173,7 +173,7 @@ constexpr bool test() {
   {
     auto iota = std::views::iota(1, 8);
     // The second template argument of the resulting `iota_view` is same as the first.
-    using Result = std::ranges::iota_view<int, int>;
+    using Result                               = std::ranges::iota_view<int, int>;
     std::same_as<Result> decltype(auto) result = iota | std::views::take(3);
     assert(result.size() == 3);
   }



More information about the libcxx-commits mailing list