]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Implement P3060R3: Add std::views::indices(n)
authorYuao Ma <c8ef@outlook.com>
Tue, 14 Oct 2025 16:28:48 +0000 (00:28 +0800)
committerc8ef <c8ef@outlook.com>
Mon, 20 Oct 2025 16:18:23 +0000 (00:18 +0800)
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
libstdc++-v3/include/bits/version.h
libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/std/ranges/indices/1.cc [new file with mode: 0644]

index f60a518b28d56f59385bf3aa5ee53f1cf57394df..04232187965f37a59555b43dd43dd72282cecd3a 100644 (file)
@@ -1754,6 +1754,14 @@ ftms = {
   };
 };
 
+ftms = {
+  name = ranges_indices;
+  values = {
+    v = 202506;
+    cxxmin = 26;
+  };
+};
+
 ftms = {
   name = constexpr_bitset;
   values = {
index cbd82ff81e89c87fecf0952bdfa00a4c9313ad6c..df7a291b05fb403119cc23e64297a6ee16d1128e 100644 (file)
 #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
index fd290ea362cc84a756c68af8bd7e2d38f2c48b47..25d2e28e72ffa5b0dbd0a0c250fde6290a1785d2 100644 (file)
@@ -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 (file)
index 0000000..805b29e
--- /dev/null
@@ -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));
+}