On Wed, Oct 15, 2025 at 12:21 AM Jonathan Wakely <[email protected]> wrote:
>
> On Tue, 14 Oct 2025 at 17:08, Yuao Ma <[email protected]> wrote:
> >
> > Hi Hewill and Jonathan,
> >
> > On Tue, Oct 14, 2025 at 11:39 PM Hewill Kang <[email protected]> wrote:
> > >
> > > 1. The prefix ranges:: in ranges::__detail::__is_integer_like can be 
> > > removed.
> >
> > It can't. views has its own __detail namespace.
> >
> > > 2. Parameters should not be passed by reference; otherwise, const int i = 
> > > 0; std::views::indices(i); will fail because const int& does not satisfy 
> > > __is_integer_like.
> >
> > Yes I figure that out with the new testcase. Done.
> >
> > > 3. operator() can be static.
> >
> > I think I'll stick to the style of the existing functions.
>
> static operator() is a C++23 feature, so wasn't an option for the
> original C++20 views.
>
> I'm not sure it makes much difference on the ABI used for most of our
> supported targets, and it should be optimized away anyway. In fact, we
> could add [[__gnu__::__always_inline__]] to the operator() here, since
> it's incredibly simple.
>
>
> > The testcase got updated, testing against different type and size. But
> > ranges::__detail::max_{size, diff}_type not working here:
>
> Ah yes, that's a problem. If you create
> views::indices(ranges::distance(views::iota(0ULL, 1ULL))) then you
> need to create an iota_view of the difference type of iota(0ULL,
> 1ULL), but that can't be represented. You would need an integer-like
> type wider than our widest integer-like type.
>
> That might be a defect in the wording for views::indices, but that's
> not your concern. There's no need to test it with that type then.
>

Thanks for the explanation! I also remember that P1522 seems to solve
the previous size_t problem about iota.

The updated patch is rfr now. Testcase updated with noexcept check.

Yuao
From c6318d68f3b3064bc279eaeb9bc282c8484049ad Mon Sep 17 00:00:00 2001
From: Yuao Ma <[email protected]>
Date: Wed, 15 Oct 2025 00:28:48 +0800
Subject: [PATCH] libstdc++: Implement P3060R3: Add std::views::indices(n)

This patch adds the views::indices function using iota.

libstdc++-v3/ChangeLog:

        * include/bits/version.def: Add ranges_indices FTM.
        * include/bits/version.h: Regenerate.
        * include/std/ranges: Implement views::indices.
        * testsuite/std/ranges/indices/1.cc: New test.
---
 libstdc++-v3/include/bits/version.def         |  8 +++++
 libstdc++-v3/include/bits/version.h           | 10 ++++++
 libstdc++-v3/include/std/ranges               | 13 ++++++++
 .../testsuite/std/ranges/indices/1.cc         | 31 +++++++++++++++++++
 4 files changed, 62 insertions(+)
 create mode 100644 libstdc++-v3/testsuite/std/ranges/indices/1.cc

diff --git a/libstdc++-v3/include/bits/version.def 
b/libstdc++-v3/include/bits/version.def
index 1118da4b541..80cfea39fb3 100644
--- a/libstdc++-v3/include/bits/version.def
+++ b/libstdc++-v3/include/bits/version.def
@@ -1754,6 +1754,14 @@ ftms = {
   };
 };
 
+ftms = {
+  name = ranges_indices;
+  values = {
+    v = 202506;
+    cxxmin = 26;
+  };
+};
+
 ftms = {
   name = constexpr_bitset;
   values = {
diff --git a/libstdc++-v3/include/bits/version.h 
b/libstdc++-v3/include/bits/version.h
index c452bbeec8e..07a8ecabb6e 100644
--- a/libstdc++-v3/include/bits/version.h
+++ b/libstdc++-v3/include/bits/version.h
@@ -1956,6 +1956,16 @@
 #endif /* !defined(__cpp_lib_ranges_starts_ends_with) */
 #undef __glibcxx_want_ranges_starts_ends_with
 
+#if !defined(__cpp_lib_ranges_indices)
+# if (__cplusplus >  202302L)
+#  define __glibcxx_ranges_indices 202506L
+#  if defined(__glibcxx_want_all) || defined(__glibcxx_want_ranges_indices)
+#   define __cpp_lib_ranges_indices 202506L
+#  endif
+# endif
+#endif /* !defined(__cpp_lib_ranges_indices) */
+#undef __glibcxx_want_ranges_indices
+
 #if !defined(__cpp_lib_constexpr_bitset)
 # if (__cplusplus >= 202100L) && _GLIBCXX_HOSTED && 
(__cpp_constexpr_dynamic_alloc)
 #  define __glibcxx_constexpr_bitset 202202L
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index fd290ea362c..25d2e28e72f 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -65,6 +65,7 @@
 #define __glibcxx_want_ranges_chunk
 #define __glibcxx_want_ranges_chunk_by
 #define __glibcxx_want_ranges_enumerate
+#define __glibcxx_want_ranges_indices
 #define __glibcxx_want_ranges_join_with
 #define __glibcxx_want_ranges_repeat
 #define __glibcxx_want_ranges_slide
@@ -785,6 +786,18 @@ namespace views
   };
 
   inline constexpr _Iota iota{};
+
+#ifdef __cpp_lib_ranges_indices // C++ >= 26
+  struct _Indices
+  {
+    template<ranges::__detail::__is_integer_like _Tp>
+      [[nodiscard]] constexpr auto
+      operator() (_Tp __e) const noexcept
+      { return iota(_Tp{}, __e); }
+  };
+
+  inline constexpr _Indices indices{};
+#endif // __cpp_lib_ranges_indices
 } // namespace views
 
 #if _GLIBCXX_HOSTED
diff --git a/libstdc++-v3/testsuite/std/ranges/indices/1.cc 
b/libstdc++-v3/testsuite/std/ranges/indices/1.cc
new file mode 100644
index 00000000000..805b29e358f
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/indices/1.cc
@@ -0,0 +1,31 @@
+// { dg-do run { target c++26 } }
+
+#include <testsuite_hooks.h>
+
+#include <ranges>
+#include <type_traits>
+#include <vector>
+
+template <typename T>
+constexpr bool test(T n) {
+  auto indices_view = std::ranges::views::indices(n);
+  static_assert(
+      std::is_same_v<T, std::ranges::range_value_t<decltype(indices_view)>>);
+  static_assert(noexcept(std::ranges::views::indices(n)));
+
+  VERIFY(indices_view.size() == n);
+  for (T i = 0; i < n; ++i) VERIFY(indices_view[i] == i);
+
+  return true;
+}
+
+int main() {
+  VERIFY(test<int>(41));
+  static_assert(test<int>(41));
+  VERIFY(test<short>(42));
+  static_assert(test<short>(42));
+  VERIFY(test<long>(43));
+  static_assert(test<long>(43));
+  VERIFY(test<size_t>(44));
+  static_assert(test<size_t>(44));
+}
-- 
2.43.0

Reply via email to