[libcxx-commits] [libcxx] [libc++][ranges] P3060R3: Add `std::views::indices(n)` (PR #146823)

Hristo Hristov via libcxx-commits libcxx-commits at lists.llvm.org
Tue Jul 22 10:19:21 PDT 2025


https://github.com/H-G-Hristov updated https://github.com/llvm/llvm-project/pull/146823

>From 51d2b416c9da4f5edf1e9270d70287e572a92335 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 07:54:53 +0300
Subject: [PATCH 01/14] [libc++][ranges] P3060R3: Add `std::views::indices(n)`

Implements: P3060R3

# References
- https://github.com/cplusplus/draft/issues/7966
- https://github.com/cplusplus/draft/pull/8006
- https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p3060r2.html
---
 libcxx/include/CMakeLists.txt          |  1 +
 libcxx/include/__ranges/indices_view.h | 49 ++++++++++++++++++++++++++
 libcxx/include/module.modulemap.in     |  1 +
 libcxx/include/ranges                  |  4 +++
 4 files changed, 55 insertions(+)
 create mode 100644 libcxx/include/__ranges/indices_view.h

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cd6583cb62c24..fdd5c2f5e2a3b 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -713,6 +713,7 @@ set(files
   __ranges/enable_view.h
   __ranges/filter_view.h
   __ranges/from_range.h
+  __ranges/indices_view.h
   __ranges/iota_view.h
   __ranges/istream_view.h
   __ranges/join_view.h
diff --git a/libcxx/include/__ranges/indices_view.h b/libcxx/include/__ranges/indices_view.h
new file mode 100644
index 0000000000000..ea3a98e94696b
--- /dev/null
+++ b/libcxx/include/__ranges/indices_view.h
@@ -0,0 +1,49 @@
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___RANGES_INDECES_VIEW_H
+#define _LIBCPP___RANGES_INDECES_VIEW_H
+
+#include <__assert>
+#include <__config>
+#include <__iterator/concepts.h>
+#include <__ranges/iota_view.h>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+#  pragma GCC system_header
+#endif
+
+_LIBCPP_PUSH_MACROS
+#include <__undef_macros>
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+#if _LIBCPP_STD_VER >= 26
+
+namespace ranges {
+
+namespace views {
+
+inline constexpr auto indices = [](__integer_like auto __size) {
+  return ranges::views::iota(decletype(__size), __size);
+};
+
+inline namespace __cpo {
+
+} // namespace __cpo
+} // namespace views
+} // namespace ranges
+
+#endif // _LIBCPP_STD_VER >= 26
+
+_LIBCPP_END_NAMESPACE_STD
+
+_LIBCPP_POP_MACROS
+
+#endif // _LIBCPP___RANGES_INDECES_VIEW_H
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index ac497208bdce4..a69a7245eb699 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1887,6 +1887,7 @@ module std [system] {
       export std.functional.bind_back
     }
     module from_range                     { header "__ranges/from_range.h" }
+    module indices_view                   { header "__ranges/indices_view.h" }
     module iota_view                      { header "__ranges/iota_view.h" }
     module istream_view                   { header "__ranges/istream_view.h" }
     module join_view                      { header "__ranges/join_view.h" }
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 96d7a6b897188..f4b7a8a70f43e 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -453,6 +453,10 @@ namespace std {
 #    include <__ranges/zip_view.h>
 #  endif
 
+#  if _LIBCPP_STD_VER >= 26
+#    include <__ranges/indeces_view.h>
+#  endif
+
 #  include <version>
 
 // standard-mandated includes

>From 97e9af8efc58004fc3897974258125526050d0a2 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 09:31:14 +0300
Subject: [PATCH 02/14] Implement and cleanup

---
 libcxx/include/CMakeLists.txt                 |   1 -
 libcxx/include/__ranges/indices_view.h        |  49 -----
 libcxx/include/__ranges/iota_view.h           |  11 +
 libcxx/include/module.modulemap.in            |   1 -
 libcxx/include/ranges                         |   4 -
 .../range.iota.view/indices.pass.cpp          | 199 ++++++++++++++++++
 6 files changed, 210 insertions(+), 55 deletions(-)
 delete mode 100644 libcxx/include/__ranges/indices_view.h
 create mode 100644 libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp

diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index fdd5c2f5e2a3b..cd6583cb62c24 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -713,7 +713,6 @@ set(files
   __ranges/enable_view.h
   __ranges/filter_view.h
   __ranges/from_range.h
-  __ranges/indices_view.h
   __ranges/iota_view.h
   __ranges/istream_view.h
   __ranges/join_view.h
diff --git a/libcxx/include/__ranges/indices_view.h b/libcxx/include/__ranges/indices_view.h
deleted file mode 100644
index ea3a98e94696b..0000000000000
--- a/libcxx/include/__ranges/indices_view.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// -*- C++ -*-
-//===----------------------------------------------------------------------===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef _LIBCPP___RANGES_INDECES_VIEW_H
-#define _LIBCPP___RANGES_INDECES_VIEW_H
-
-#include <__assert>
-#include <__config>
-#include <__iterator/concepts.h>
-#include <__ranges/iota_view.h>
-
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-#  pragma GCC system_header
-#endif
-
-_LIBCPP_PUSH_MACROS
-#include <__undef_macros>
-
-_LIBCPP_BEGIN_NAMESPACE_STD
-
-#if _LIBCPP_STD_VER >= 26
-
-namespace ranges {
-
-namespace views {
-
-inline constexpr auto indices = [](__integer_like auto __size) {
-  return ranges::views::iota(decletype(__size), __size);
-};
-
-inline namespace __cpo {
-
-} // namespace __cpo
-} // namespace views
-} // namespace ranges
-
-#endif // _LIBCPP_STD_VER >= 26
-
-_LIBCPP_END_NAMESPACE_STD
-
-_LIBCPP_POP_MACROS
-
-#endif // _LIBCPP___RANGES_INDECES_VIEW_H
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 4b84585258b91..732a501c07857 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -371,6 +371,7 @@ template <class _Start, class _BoundSentinel>
 inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
 
 namespace views {
+
 namespace __iota {
 struct __fn {
   template <class _Start>
@@ -392,6 +393,16 @@ struct __fn {
 inline namespace __cpo {
 inline constexpr auto iota = __iota::__fn{};
 } // namespace __cpo
+
+
+#  if _LIBCPP_STD_VER >= 26
+
+inline constexpr auto indices = [](__integer_like auto __size) {
+  return ranges::views::iota(decltype(__size){}, __size);
+};
+
+#  endif
+
 } // namespace views
 } // namespace ranges
 
diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in
index a69a7245eb699..ac497208bdce4 100644
--- a/libcxx/include/module.modulemap.in
+++ b/libcxx/include/module.modulemap.in
@@ -1887,7 +1887,6 @@ module std [system] {
       export std.functional.bind_back
     }
     module from_range                     { header "__ranges/from_range.h" }
-    module indices_view                   { header "__ranges/indices_view.h" }
     module iota_view                      { header "__ranges/iota_view.h" }
     module istream_view                   { header "__ranges/istream_view.h" }
     module join_view                      { header "__ranges/join_view.h" }
diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index f4b7a8a70f43e..96d7a6b897188 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -453,10 +453,6 @@ namespace std {
 #    include <__ranges/zip_view.h>
 #  endif
 
-#  if _LIBCPP_STD_VER >= 26
-#    include <__ranges/indeces_view.h>
-#  endif
-
 #  include <version>
 
 // standard-mandated includes
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
new file mode 100644
index 0000000000000..01806c27a896f
--- /dev/null
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
@@ -0,0 +1,199 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// REQUIRES: std-at-least-c++26
+
+#include <cassert>
+#include <cstddef>
+#include <ranges>
+#include <vector>
+
+#include "test_macros.h"
+#define TEST_HAS_NO_INT128 // Size cannot be larger than 64 bits
+#include "type_algorithms.h"
+
+#include "types.h"
+
+// #include <compare>
+
+// class IntegerLike {
+//   int value;
+
+// public:
+//   // Constructor
+//   IntegerLike(int v = 0) : value(v) {}
+
+//   // Conversion to int
+//   operator int() const { return value; }
+
+//   // Conversion to std::size_t
+//   // This is necessary for std::ranges::views::indices to work with IntegerLike
+//   operator std::size_t() const { return static_cast<std::size_t>(value); }
+
+//   // Equality and comparison
+//   auto operator<=>(const IntegerLike&) const = default;
+
+//   // Arithmetic
+//   IntegerLike operator+(const IntegerLike& other) const { return IntegerLike(value + other.value); }
+
+//   IntegerLike operator-(const IntegerLike& other) const { return IntegerLike(value - other.value); }
+
+//   IntegerLike operator*(const IntegerLike& other) const { return IntegerLike(value * other.value); }
+
+//   IntegerLike operator/(const IntegerLike& other) const { return IntegerLike(value / other.value); }
+
+//   // Compound assignment
+//   IntegerLike& operator+=(const IntegerLike& other) {
+//     value += other.value;
+//     return *this;
+//   }
+
+//   IntegerLike& operator-=(const IntegerLike& other) {
+//     value -= other.value;
+//     return *this;
+//   }
+
+//   IntegerLike& operator*=(const IntegerLike& other) {
+//     value *= other.value;
+//     return *this;
+//   }
+
+//   IntegerLike& operator/=(const IntegerLike& other) {
+//     value /= other.value;
+//     return *this;
+//   }
+
+//   // Increment / Decrement
+//   IntegerLike& operator++() {
+//     ++value;
+//     return *this;
+//   }
+
+//   IntegerLike operator++(int) {
+//     IntegerLike tmp = *this;
+//     ++(*this);
+//     return tmp;
+//   }
+
+//   IntegerLike& operator--() {
+//     --value;
+//     return *this;
+//   }
+
+//   IntegerLike operator--(int) {
+//     IntegerLike tmp = *this;
+//     --(*this);
+//     return tmp;
+//   }
+// };
+
+// Test SFINAE.
+
+template <typename SizeType>
+concept HasIndices = requires(SizeType s) { std::ranges::views::indices(s); };
+
+struct NotIntegerLike {};
+
+struct IntegerTypesTest {
+  template <class T>
+  constexpr void operator()() {
+    static_assert(HasIndices<T>);
+  }
+};
+
+void test_SFIANE() {
+  static_assert(HasIndices<std::size_t>);
+  types::for_each(types::integer_types(), IntegerTypesTest{});
+
+  static_assert(!HasIndices<bool>);
+  static_assert(!HasIndices<float>);
+  static_assert(!HasIndices<void>);
+  static_assert(!HasIndices<SomeInt>); // Does satisfy is_integer_like, but not the conversion to std::size_t
+  static_assert(!HasIndices<NotIntegerLike>);
+}
+
+constexpr bool test() {
+  {
+    // Check that the indices view works as expected
+    auto indices_view = std::ranges::views::indices(5);
+    assert(indices_view.size() == 5);
+
+    // This should be valid, as indices_view is a range of integers
+    assert(indices_view[0] == 0);
+    assert(indices_view[1] == 1);
+    assert(indices_view[2] == 2);
+    assert(indices_view[3] == 3);
+    assert(indices_view[4] == 4);
+
+    // Check that the view is a range
+    static_assert(std::ranges::range<decltype(indices_view)>);
+  }
+
+  //   {
+  //     // Check that the indices view works as expected
+  //     auto indices_view = std::ranges::views::indices(IntegerLike{5});
+  //     assert(indices_view.size() == 5);
+
+  //     // Check that the view is a range
+  //     static_assert(std::ranges::range<decltype(indices_view)>);
+
+  //     // This should be valid, as indices_view is a range of integers
+  //     assert(indices_view[0] == 0);
+  //     assert(indices_view[1] == 1);
+  //     assert(indices_view[2] == 2);
+  //     assert(indices_view[3] == 3);
+  //     assert(indices_view[4] == 4);
+  //   }
+
+  {
+    std::vector v(5, 0);
+
+    // Check that the indices view works as expected
+    auto indices_view = std::ranges::views::indices(std::ranges::size(v));
+    assert(indices_view.size() == 5);
+
+    // Check that the view is a range
+    static_assert(std::ranges::range<decltype(indices_view)>);
+
+    // This should be valid, as indices_view is a range of integers
+    assert(indices_view[0] == 0);
+    assert(indices_view[1] == 1);
+    assert(indices_view[2] == 2);
+    assert(indices_view[3] == 3);
+    assert(indices_view[4] == 4);
+  }
+
+  {
+    std::vector v(5, SomeInt{});
+
+    // Check that the indices view works as expected
+    auto indices_view = std::ranges::views::indices(std::ranges::size(v));
+    assert(indices_view.size() == 5);
+
+    // Check that the view is a range
+    static_assert(std::ranges::range<decltype(indices_view)>);
+
+    // This should be valid, as indices_view is a range of integers
+    assert(indices_view[0] == 0);
+    assert(indices_view[1] == 1);
+    assert(indices_view[2] == 2);
+    assert(indices_view[3] == 3);
+    assert(indices_view[4] == 4);
+  }
+
+  return true;
+}
+
+int main(int, char**) {
+  test_SFIANE();
+
+  test();
+  static_assert(test());
+
+  return 0;
+}

>From 5e04a2e352acf783d6c5aa89580daf60395e03a7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 09:41:11 +0300
Subject: [PATCH 03/14] Update version

---
 libcxx/docs/FeatureTestMacroTable.rst         |   2 +
 libcxx/include/version                        |   2 +
 .../ranges.version.compile.pass.cpp           |  27 +++++
 .../version.version.compile.pass.cpp          |  27 +++++
 .../range.iota.view/indices.pass.cpp          | 105 +-----------------
 .../generate_feature_test_macro_components.py |   5 +
 6 files changed, 69 insertions(+), 99 deletions(-)

diff --git a/libcxx/docs/FeatureTestMacroTable.rst b/libcxx/docs/FeatureTestMacroTable.rst
index 61805726a4ff0..8c2f38e075d45 100644
--- a/libcxx/docs/FeatureTestMacroTable.rst
+++ b/libcxx/docs/FeatureTestMacroTable.rst
@@ -488,6 +488,8 @@ Status
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_ranges_concat``                                *unimplemented*
     ---------------------------------------------------------- -----------------
+    ``__cpp_lib_ranges_indices``                               ``202506L``
+    ---------------------------------------------------------- -----------------
     ``__cpp_lib_ratio``                                        ``202306L``
     ---------------------------------------------------------- -----------------
     ``__cpp_lib_rcu``                                          *unimplemented*
diff --git a/libcxx/include/version b/libcxx/include/version
index d98049bd57046..d0b2e865c75bf 100644
--- a/libcxx/include/version
+++ b/libcxx/include/version
@@ -205,6 +205,7 @@ __cpp_lib_ranges_chunk_by                               202202L <ranges>
 __cpp_lib_ranges_concat                                 202403L <ranges>
 __cpp_lib_ranges_contains                               202207L <algorithm>
 __cpp_lib_ranges_find_last                              202207L <algorithm>
+__cpp_lib_ranges_indices                                202506L <ranges>
 __cpp_lib_ranges_iota                                   202202L <numeric>
 __cpp_lib_ranges_join_with                              202202L <ranges>
 __cpp_lib_ranges_repeat                                 202207L <ranges>
@@ -590,6 +591,7 @@ __cpp_lib_void_t                                        201411L <type_traits>
 # define __cpp_lib_out_ptr                              202311L
 // # define __cpp_lib_philox_engine                        202406L
 // # define __cpp_lib_ranges_concat                        202403L
+# define __cpp_lib_ranges_indices                       202506L
 # define __cpp_lib_ratio                                202306L
 // # define __cpp_lib_rcu                                  202306L
 # define __cpp_lib_reference_wrapper                    202403L
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
index df19f03e7dba1..5116864879485 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/ranges.version.compile.pass.cpp
@@ -48,6 +48,10 @@
 #    error "__cpp_lib_ranges_concat should not be defined before c++26"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_join_with
 #    error "__cpp_lib_ranges_join_with should not be defined before c++23"
 #  endif
@@ -98,6 +102,10 @@
 #    error "__cpp_lib_ranges_concat should not be defined before c++26"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_join_with
 #    error "__cpp_lib_ranges_join_with should not be defined before c++23"
 #  endif
@@ -148,6 +156,10 @@
 #    error "__cpp_lib_ranges_concat should not be defined before c++26"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_join_with
 #    error "__cpp_lib_ranges_join_with should not be defined before c++23"
 #  endif
@@ -201,6 +213,10 @@
 #    error "__cpp_lib_ranges_concat should not be defined before c++26"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_join_with
 #    error "__cpp_lib_ranges_join_with should not be defined before c++23"
 #  endif
@@ -278,6 +294,10 @@
 #    error "__cpp_lib_ranges_concat should not be defined before c++26"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifndef __cpp_lib_ranges_join_with
 #    error "__cpp_lib_ranges_join_with should be defined in c++23"
 #  endif
@@ -400,6 +420,13 @@
 #    endif
 #  endif
 
+#  ifndef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should be defined in c++26"
+#  endif
+#  if __cpp_lib_ranges_indices != 202506L
+#    error "__cpp_lib_ranges_indices should have the value 202506L in c++26"
+#  endif
+
 #  ifndef __cpp_lib_ranges_join_with
 #    error "__cpp_lib_ranges_join_with should be defined in c++26"
 #  endif
diff --git a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
index 962688e06188a..36c3ac86c5d86 100644
--- a/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
+++ b/libcxx/test/std/language.support/support.limits/support.limits.general/version.version.compile.pass.cpp
@@ -664,6 +664,10 @@
 #    error "__cpp_lib_ranges_find_last should not be defined before c++23"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_iota
 #    error "__cpp_lib_ranges_iota should not be defined before c++23"
 #  endif
@@ -1604,6 +1608,10 @@
 #    error "__cpp_lib_ranges_find_last should not be defined before c++23"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_iota
 #    error "__cpp_lib_ranges_iota should not be defined before c++23"
 #  endif
@@ -2715,6 +2723,10 @@
 #    error "__cpp_lib_ranges_find_last should not be defined before c++23"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_iota
 #    error "__cpp_lib_ranges_iota should not be defined before c++23"
 #  endif
@@ -4099,6 +4111,10 @@
 #    error "__cpp_lib_ranges_find_last should not be defined before c++23"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifdef __cpp_lib_ranges_iota
 #    error "__cpp_lib_ranges_iota should not be defined before c++23"
 #  endif
@@ -5678,6 +5694,10 @@
 #    error "__cpp_lib_ranges_find_last should have the value 202207L in c++23"
 #  endif
 
+#  ifdef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should not be defined before c++26"
+#  endif
+
 #  ifndef __cpp_lib_ranges_iota
 #    error "__cpp_lib_ranges_iota should be defined in c++23"
 #  endif
@@ -7602,6 +7622,13 @@
 #    error "__cpp_lib_ranges_find_last should have the value 202207L in c++26"
 #  endif
 
+#  ifndef __cpp_lib_ranges_indices
+#    error "__cpp_lib_ranges_indices should be defined in c++26"
+#  endif
+#  if __cpp_lib_ranges_indices != 202506L
+#    error "__cpp_lib_ranges_indices should have the value 202506L in c++26"
+#  endif
+
 #  ifndef __cpp_lib_ranges_iota
 #    error "__cpp_lib_ranges_iota should be defined in c++26"
 #  endif
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
index 01806c27a896f..12f92eed7171f 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
@@ -19,86 +19,11 @@
 
 #include "types.h"
 
-// #include <compare>
-
-// class IntegerLike {
-//   int value;
-
-// public:
-//   // Constructor
-//   IntegerLike(int v = 0) : value(v) {}
-
-//   // Conversion to int
-//   operator int() const { return value; }
-
-//   // Conversion to std::size_t
-//   // This is necessary for std::ranges::views::indices to work with IntegerLike
-//   operator std::size_t() const { return static_cast<std::size_t>(value); }
-
-//   // Equality and comparison
-//   auto operator<=>(const IntegerLike&) const = default;
-
-//   // Arithmetic
-//   IntegerLike operator+(const IntegerLike& other) const { return IntegerLike(value + other.value); }
-
-//   IntegerLike operator-(const IntegerLike& other) const { return IntegerLike(value - other.value); }
-
-//   IntegerLike operator*(const IntegerLike& other) const { return IntegerLike(value * other.value); }
-
-//   IntegerLike operator/(const IntegerLike& other) const { return IntegerLike(value / other.value); }
-
-//   // Compound assignment
-//   IntegerLike& operator+=(const IntegerLike& other) {
-//     value += other.value;
-//     return *this;
-//   }
-
-//   IntegerLike& operator-=(const IntegerLike& other) {
-//     value -= other.value;
-//     return *this;
-//   }
-
-//   IntegerLike& operator*=(const IntegerLike& other) {
-//     value *= other.value;
-//     return *this;
-//   }
-
-//   IntegerLike& operator/=(const IntegerLike& other) {
-//     value /= other.value;
-//     return *this;
-//   }
-
-//   // Increment / Decrement
-//   IntegerLike& operator++() {
-//     ++value;
-//     return *this;
-//   }
-
-//   IntegerLike operator++(int) {
-//     IntegerLike tmp = *this;
-//     ++(*this);
-//     return tmp;
-//   }
-
-//   IntegerLike& operator--() {
-//     --value;
-//     return *this;
-//   }
-
-//   IntegerLike operator--(int) {
-//     IntegerLike tmp = *this;
-//     --(*this);
-//     return tmp;
-//   }
-// };
-
 // Test SFINAE.
 
 template <typename SizeType>
 concept HasIndices = requires(SizeType s) { std::ranges::views::indices(s); };
 
-struct NotIntegerLike {};
-
 struct IntegerTypesTest {
   template <class T>
   constexpr void operator()() {
@@ -106,10 +31,13 @@ struct IntegerTypesTest {
   }
 };
 
+struct NotIntegerLike {};
+
 void test_SFIANE() {
   static_assert(HasIndices<std::size_t>);
   types::for_each(types::integer_types(), IntegerTypesTest{});
 
+  // Not integer-like types should not satisfy HasIndices
   static_assert(!HasIndices<bool>);
   static_assert(!HasIndices<float>);
   static_assert(!HasIndices<void>);
@@ -119,48 +47,28 @@ void test_SFIANE() {
 
 constexpr bool test() {
   {
-    // Check that the indices view works as expected
     auto indices_view = std::ranges::views::indices(5);
     assert(indices_view.size() == 5);
 
-    // This should be valid, as indices_view is a range of integers
+    // Check that the view is a range
+    static_assert(std::ranges::range<decltype(indices_view)>);
+
     assert(indices_view[0] == 0);
     assert(indices_view[1] == 1);
     assert(indices_view[2] == 2);
     assert(indices_view[3] == 3);
     assert(indices_view[4] == 4);
-
-    // Check that the view is a range
-    static_assert(std::ranges::range<decltype(indices_view)>);
   }
 
-  //   {
-  //     // Check that the indices view works as expected
-  //     auto indices_view = std::ranges::views::indices(IntegerLike{5});
-  //     assert(indices_view.size() == 5);
-
-  //     // Check that the view is a range
-  //     static_assert(std::ranges::range<decltype(indices_view)>);
-
-  //     // This should be valid, as indices_view is a range of integers
-  //     assert(indices_view[0] == 0);
-  //     assert(indices_view[1] == 1);
-  //     assert(indices_view[2] == 2);
-  //     assert(indices_view[3] == 3);
-  //     assert(indices_view[4] == 4);
-  //   }
-
   {
     std::vector v(5, 0);
 
-    // Check that the indices view works as expected
     auto indices_view = std::ranges::views::indices(std::ranges::size(v));
     assert(indices_view.size() == 5);
 
     // Check that the view is a range
     static_assert(std::ranges::range<decltype(indices_view)>);
 
-    // This should be valid, as indices_view is a range of integers
     assert(indices_view[0] == 0);
     assert(indices_view[1] == 1);
     assert(indices_view[2] == 2);
@@ -178,7 +86,6 @@ constexpr bool test() {
     // Check that the view is a range
     static_assert(std::ranges::range<decltype(indices_view)>);
 
-    // This should be valid, as indices_view is a range of integers
     assert(indices_view[0] == 0);
     assert(indices_view[1] == 1);
     assert(indices_view[2] == 2);
diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py
index fe175fd758726..7d5dd984b3fd5 100644
--- a/libcxx/utils/generate_feature_test_macro_components.py
+++ b/libcxx/utils/generate_feature_test_macro_components.py
@@ -1116,6 +1116,11 @@ def add_version_header(tc):
             "values": {"c++23": 202207},
             "headers": ["algorithm"],
         },
+        {
+            "name": "__cpp_lib_ranges_indices",
+            "values": {"c++26": 202506},
+            "headers": ["ranges"],
+        },
         {
             "name": "__cpp_lib_ranges_iota",
             "values": {"c++23": 202202},

>From 225dd4c5fc928fbcda2a0c8b2e0c2d0afeb126fb Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 09:46:13 +0300
Subject: [PATCH 04/14] Add release notes

---
 libcxx/docs/ReleaseNotes/21.rst | 1 +
 1 file changed, 1 insertion(+)

diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index d31ca0130cb80..1901560857cc7 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -53,6 +53,7 @@ Implemented Papers
 - P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
 - P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
 - P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
+- P3060R2: Add ``std::views::indices(n)``
 
 Improvements and New Features
 -----------------------------

>From 2a14a04ce80d653fe22a00ad56ec28dce4ac7389 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 09:48:44 +0300
Subject: [PATCH 05/14] Cleanup

---
 libcxx/include/__ranges/iota_view.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 732a501c07857..c477fadce31f2 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -371,7 +371,6 @@ template <class _Start, class _BoundSentinel>
 inline constexpr bool enable_borrowed_range<iota_view<_Start, _BoundSentinel>> = true;
 
 namespace views {
-
 namespace __iota {
 struct __fn {
   template <class _Start>

>From 69d4edd045d9eeabf2975985573ad0db716650bc Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 09:55:43 +0300
Subject: [PATCH 06/14] House keeping

---
 libcxx/include/ranges                                        | 5 +++++
 .../ranges/range.factories/range.iota.view/indices.pass.cpp  | 4 ++++
 2 files changed, 9 insertions(+)

diff --git a/libcxx/include/ranges b/libcxx/include/ranges
index 96d7a6b897188..cfaa66a0831b3 100644
--- a/libcxx/include/ranges
+++ b/libcxx/include/ranges
@@ -267,6 +267,11 @@ namespace std::ranges {
   template<class W, class Bound>
     inline constexpr bool enable_borrowed_range<iota_view<W, Bound>> = true;
 
+  namespace views {
+    inline constexpr unspecified iota = unspecified;
+    inline constexpr unspecified indices = unspecified; // Since C++26
+  }
+
   // [range.repeat], repeat view
   template<class T>
     concept integer-like-with-usable-difference-type =  // exposition only
diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
index 12f92eed7171f..3d4b2bbbb89f9 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
@@ -8,6 +8,10 @@
 
 // REQUIRES: std-at-least-c++26
 
+// ranges
+
+// inline constexpr unspecified indices = unspecified;
+
 #include <cassert>
 #include <cstddef>
 #include <ranges>

>From 4ccd8f9708ddcbe616a874ee504795feaa39f2e2 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Thu, 3 Jul 2025 23:25:51 +0300
Subject: [PATCH 07/14] Addressed review comments

---
 libcxx/docs/ReleaseNotes/21.rst     | 2 +-
 libcxx/include/__ranges/iota_view.h | 1 -
 libcxx/modules/std/ranges.inc       | 3 +++
 3 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index 1901560857cc7..edb9a96edf9bd 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -53,7 +53,7 @@ Implemented Papers
 - P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
 - P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
 - P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
-- P3060R2: Add ``std::views::indices(n)``
+- P3060R3: Add ``std::views::indices(n)``
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index c477fadce31f2..7593de9fa8b88 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -393,7 +393,6 @@ inline namespace __cpo {
 inline constexpr auto iota = __iota::__fn{};
 } // namespace __cpo
 
-
 #  if _LIBCPP_STD_VER >= 26
 
 inline constexpr auto indices = [](__integer_like auto __size) {
diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc
index 7ede42e4f7b0a..4b562299debd7 100644
--- a/libcxx/modules/std/ranges.inc
+++ b/libcxx/modules/std/ranges.inc
@@ -114,6 +114,9 @@ export namespace std {
 
     namespace views {
       using std::ranges::views::iota;
+#if _LIBCPP_STD_VER >= 23
+      using std::ranges::views::indices;
+#endif
     } // namespace views
 
 #if _LIBCPP_STD_VER >= 23

>From b0c1c6567151c5f879ca562f1b135f509aed361d Mon Sep 17 00:00:00 2001
From: Hristo Hristov <zingam at outlook.com>
Date: Fri, 4 Jul 2025 06:45:00 +0300
Subject: [PATCH 08/14] Update libcxx/modules/std/ranges.inc

Co-authored-by: A. Jiang <de34 at live.cn>
---
 libcxx/modules/std/ranges.inc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/modules/std/ranges.inc b/libcxx/modules/std/ranges.inc
index 4b562299debd7..cc7daa3cd1aec 100644
--- a/libcxx/modules/std/ranges.inc
+++ b/libcxx/modules/std/ranges.inc
@@ -114,7 +114,7 @@ export namespace std {
 
     namespace views {
       using std::ranges::views::iota;
-#if _LIBCPP_STD_VER >= 23
+#if _LIBCPP_STD_VER >= 26
       using std::ranges::views::indices;
 #endif
     } // namespace views

>From 4462459a79cd40a8738b660e70d43b2a075737cb Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 4 Jul 2025 08:02:21 +0300
Subject: [PATCH 09/14] Add CPO test

---
 .../customization.point.object/cpo.compile.pass.cpp            | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
index 4e24dbe810165..5cd39a4140905 100644
--- a/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
+++ b/libcxx/test/std/library/description/conventions/customization.point.object/cpo.compile.pass.cpp
@@ -81,6 +81,9 @@ static_assert(test(std::ranges::ssize, a));
 // views::empty<T> is not a CPO
 static_assert(test(std::views::iota, 1));
 static_assert(test(std::views::iota, 1, 10));
+#if TEST_STD_VER >= 26
+static_assert(test(std::views::indices, 10));
+#endif
 //static_assert(test(std::views::istream<int>, 1);
 static_assert(test(std::views::single, 4));
 

>From 9926713a03849c0861188c44a252d606eb612293 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Fri, 4 Jul 2025 10:52:50 +0300
Subject: [PATCH 10/14] Made the lambda `static`

---
 libcxx/include/__ranges/iota_view.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/include/__ranges/iota_view.h b/libcxx/include/__ranges/iota_view.h
index 7593de9fa8b88..2fca20eacb1dc 100644
--- a/libcxx/include/__ranges/iota_view.h
+++ b/libcxx/include/__ranges/iota_view.h
@@ -395,7 +395,7 @@ inline constexpr auto iota = __iota::__fn{};
 
 #  if _LIBCPP_STD_VER >= 26
 
-inline constexpr auto indices = [](__integer_like auto __size) {
+inline constexpr auto indices = [](__integer_like auto __size) static {
   return ranges::views::iota(decltype(__size){}, __size);
 };
 

>From ba59dcf62dc0dd2422abe242b22fcc29fe3ac2cf Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 13 Jul 2025 08:40:09 +0300
Subject: [PATCH 11/14] Updated status

---
 libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index febb0c176f9c4..dab154692147a 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -149,7 +149,7 @@
 "`P3503R3 <https://wg21.link/P3503R3>`__","Make type-erased allocator use in ``promise`` and ``packaged_task`` consistent","2025-06 (Sofia)","","",""
 "`P3008R6 <https://wg21.link/P3008R6>`__","Atomic floating-point min/max","2025-06 (Sofia)","","",""
 "`P3111R8 <https://wg21.link/P3111R8>`__","Atomic Reduction Operations","2025-06 (Sofia)","","",""
-"`P3060R3 <https://wg21.link/P3060R3>`__","Add ``std::views::indices(n)``","2025-06 (Sofia)","","",""
+"`P3060R3 <https://wg21.link/P3060R3>`__","Add ``std::views::indices(n)``","2025-06 (Sofia)","|Complete|","21",""
 "`P2319R5 <https://wg21.link/P2319R5>`__","Prevent ``path`` presentation problems","2025-06 (Sofia)","","",""
 "`P3223R2 <https://wg21.link/P3223R2>`__","Making ``std::istream::ignore`` less surprising","2025-06 (Sofia)","","",""
 "`P2781R9 <https://wg21.link/P2781R9>`__","``std::constant_wrapper``","2025-06 (Sofia)","","",""

>From 1406f636dd1889ca247cb016f9ff21d21acae2c7 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Sun, 13 Jul 2025 08:44:10 +0300
Subject: [PATCH 12/14] Update test

---
 .../range.iota.view/indices.pass.cpp           | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
index 3d4b2bbbb89f9..1f5fab0bbb8f2 100644
--- a/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
+++ b/libcxx/test/std/ranges/range.factories/range.iota.view/indices.pass.cpp
@@ -41,7 +41,7 @@ void test_SFIANE() {
   static_assert(HasIndices<std::size_t>);
   types::for_each(types::integer_types(), IntegerTypesTest{});
 
-  // Not integer-like types should not satisfy HasIndices
+  // Non-integer-like types should not satisfy HasIndices
   static_assert(!HasIndices<bool>);
   static_assert(!HasIndices<float>);
   static_assert(!HasIndices<void>);
@@ -52,11 +52,10 @@ void test_SFIANE() {
 constexpr bool test() {
   {
     auto indices_view = std::ranges::views::indices(5);
-    assert(indices_view.size() == 5);
-
-    // Check that the view is a range
     static_assert(std::ranges::range<decltype(indices_view)>);
 
+    assert(indices_view.size() == 5);
+
     assert(indices_view[0] == 0);
     assert(indices_view[1] == 1);
     assert(indices_view[2] == 2);
@@ -68,11 +67,10 @@ constexpr bool test() {
     std::vector v(5, 0);
 
     auto indices_view = std::ranges::views::indices(std::ranges::size(v));
-    assert(indices_view.size() == 5);
-
-    // Check that the view is a range
     static_assert(std::ranges::range<decltype(indices_view)>);
 
+    assert(indices_view.size() == 5);
+
     assert(indices_view[0] == 0);
     assert(indices_view[1] == 1);
     assert(indices_view[2] == 2);
@@ -83,13 +81,11 @@ constexpr bool test() {
   {
     std::vector v(5, SomeInt{});
 
-    // Check that the indices view works as expected
     auto indices_view = std::ranges::views::indices(std::ranges::size(v));
-    assert(indices_view.size() == 5);
-
-    // Check that the view is a range
     static_assert(std::ranges::range<decltype(indices_view)>);
 
+    assert(indices_view.size() == 5);
+
     assert(indices_view[0] == 0);
     assert(indices_view[1] == 1);
     assert(indices_view[2] == 2);

>From 47afc9c1a41010d3c1ac081d2d93a69022fc382d Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hghristov.rmm at gmail.com>
Date: Tue, 22 Jul 2025 20:16:46 +0300
Subject: [PATCH 13/14] LLVM22

---
 libcxx/docs/ReleaseNotes/21.rst    | 1 -
 libcxx/docs/ReleaseNotes/22.rst    | 1 +
 libcxx/docs/Status/Cxx2cPapers.csv | 2 +-
 3 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/libcxx/docs/ReleaseNotes/21.rst b/libcxx/docs/ReleaseNotes/21.rst
index edb9a96edf9bd..d31ca0130cb80 100644
--- a/libcxx/docs/ReleaseNotes/21.rst
+++ b/libcxx/docs/ReleaseNotes/21.rst
@@ -53,7 +53,6 @@ Implemented Papers
 - P2711R1: Making multi-param constructors of ``views`` ``explicit`` (`Github <https://github.com/llvm/llvm-project/issues/105252>`__)
 - P2770R0: Stashing stashing ``iterators`` for proper flattening (`Github <https://github.com/llvm/llvm-project/issues/105250>`__)
 - P2655R3: ``common_reference_t`` of ``reference_wrapper`` Should Be a Reference Type (`Github <https://github.com/llvm/llvm-project/issues/105260>`__)
-- P3060R3: Add ``std::views::indices(n)``
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index 15bf46d44b07f..b2d29c41b9880 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -39,6 +39,7 @@ Implemented Papers
 ------------------
 
 - P2321R2: ``zip`` (`Github <https://github.com/llvm/llvm-project/issues/105169>`__) (The paper is partially implemented. ``zip_transform_view`` is implemented in this release)
+- P3060R3: Add ``std::views::indices(n)`` (`Github <https://github.com/llvm/llvm-project/issues/105169>`__)
 
 Improvements and New Features
 -----------------------------
diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv
index dab154692147a..fe2c73655a530 100644
--- a/libcxx/docs/Status/Cxx2cPapers.csv
+++ b/libcxx/docs/Status/Cxx2cPapers.csv
@@ -149,7 +149,7 @@
 "`P3503R3 <https://wg21.link/P3503R3>`__","Make type-erased allocator use in ``promise`` and ``packaged_task`` consistent","2025-06 (Sofia)","","",""
 "`P3008R6 <https://wg21.link/P3008R6>`__","Atomic floating-point min/max","2025-06 (Sofia)","","",""
 "`P3111R8 <https://wg21.link/P3111R8>`__","Atomic Reduction Operations","2025-06 (Sofia)","","",""
-"`P3060R3 <https://wg21.link/P3060R3>`__","Add ``std::views::indices(n)``","2025-06 (Sofia)","|Complete|","21",""
+"`P3060R3 <https://wg21.link/P3060R3>`__","Add ``std::views::indices(n)``","2025-06 (Sofia)","|Complete|","22",""
 "`P2319R5 <https://wg21.link/P2319R5>`__","Prevent ``path`` presentation problems","2025-06 (Sofia)","","",""
 "`P3223R2 <https://wg21.link/P3223R2>`__","Making ``std::istream::ignore`` less surprising","2025-06 (Sofia)","","",""
 "`P2781R9 <https://wg21.link/P2781R9>`__","``std::constant_wrapper``","2025-06 (Sofia)","","",""

>From 75d0616515c16c9807ca087c48492e1fe5e112a6 Mon Sep 17 00:00:00 2001
From: Hristo Hristov <hristo.goshev.hristov at gmail.com>
Date: Tue, 22 Jul 2025 20:19:06 +0300
Subject: [PATCH 14/14] Update libcxx/docs/ReleaseNotes/22.rst

---
 libcxx/docs/ReleaseNotes/22.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/libcxx/docs/ReleaseNotes/22.rst b/libcxx/docs/ReleaseNotes/22.rst
index b2d29c41b9880..b0907e8a02c1c 100644
--- a/libcxx/docs/ReleaseNotes/22.rst
+++ b/libcxx/docs/ReleaseNotes/22.rst
@@ -39,7 +39,7 @@ Implemented Papers
 ------------------
 
 - P2321R2: ``zip`` (`Github <https://github.com/llvm/llvm-project/issues/105169>`__) (The paper is partially implemented. ``zip_transform_view`` is implemented in this release)
-- P3060R3: Add ``std::views::indices(n)`` (`Github <https://github.com/llvm/llvm-project/issues/105169>`__)
+- P3060R3: Add ``std::views::indices(n)`` (`Github <https://github.com/llvm/llvm-project/issues/148175>`__)
 
 Improvements and New Features
 -----------------------------



More information about the libcxx-commits mailing list