From 2bef65e2860db92f296e94fd5a12ba3bc3f19dfc Mon Sep 17 00:00:00 2001
From: Yuao Ma <c8ef@outlook.com>
Date: Tue, 14 Oct 2025 22:42:42 +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         | 56 +++++++++++++++++++
 4 files changed, 87 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..5009e609eea 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>
+      constexpr auto
+      operator() [[nodiscard]] (_Tp&& __e) const
+      { 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..11b37cbd8fe
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/indices/1.cc
@@ -0,0 +1,56 @@
+// { dg-do run { target c++26 } }
+
+// Copyright (C) 2025 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <ranges>
+#include <vector>
+
+#include <testsuite_hooks.h>
+
+constexpr bool test() {
+  {
+    auto indices_view = std::ranges::views::indices(4);
+    static_assert(std::ranges::range<decltype(indices_view)>);
+
+    VERIFY(indices_view.size() == 4);
+    VERIFY(indices_view[0] == 0);
+    VERIFY(indices_view[1] == 1);
+    VERIFY(indices_view[2] == 2);
+    VERIFY(indices_view[3] == 3);
+  }
+
+  {
+    std::vector v(4, 0);
+
+    auto indices_view = std::ranges::views::indices(std::ranges::size(v));
+    static_assert(std::ranges::range<decltype(indices_view)>);
+
+    VERIFY(indices_view.size() == 4);
+    VERIFY(indices_view[0] == 0);
+    VERIFY(indices_view[1] == 1);
+    VERIFY(indices_view[2] == 2);
+    VERIFY(indices_view[3] == 3);
+  }
+
+  return true;
+}
+
+int main() {
+  VERIFY(test());
+  static_assert(test());
+}
-- 
2.43.0

