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.

The testcase got updated, testing against different type and size. But
ranges::__detail::max_{size, diff}_type not working here:

In file included from gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:5:
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges: In
instantiation of 'constexpr auto
std::ranges::views::_Indices::operator()(_Tp) const [with _Tp =
std::ranges::__detail::__max_diff_type]':
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:11:   required from
'constexpr bool test(T) [with T =
std::ranges::__detail::__max_diff_type]'
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:27:   required from here
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:796: error:
no match for call to '(const std::ranges::views::_Iota)
(std::ranges::__detail::__max_diff_type,
std::ranges::__detail::__max_diff_type&)'
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:774: note:
there are 2 candidates
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:778: note:
candidate 1: 'template<class _Tp>  requires  __can_iota_view<_Tp>
constexpr auto std::ranges::views::_Iota::operator()(_Tp&&) const'
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:778: note:
candidate expects 1 argument, 2 provided
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:784: note:
candidate 2: 'template<class _Tp, class _Up>  requires
__can_iota_view<_Tp, _Up> constexpr auto
std::ranges::views::_Iota::operator()(_Tp&&, _Up&&) const'
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:784: note:
template argument deduction/substitution failed:
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:784: note:
constraints not satisfied
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges: In
substitution of 'template<class _Tp, class _Up>  requires
__can_iota_view<_Tp, _Up> constexpr auto
std::ranges::views::_Iota::operator()(_Tp&&, _Up&&) const [with _Tp =
std::ranges::__detail::__max_diff_type; _Up =
std::ranges::__detail::__max_diff_type&]':
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:796:
required from 'constexpr auto
std::ranges::views::_Indices::operator()(_Tp) const [with _Tp =
std::ranges::__detail::__max_diff_type]'
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:11:   required from
'constexpr bool test(T) [with T =
std::ranges::__detail::__max_diff_type]'
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:27:   required from here
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:771:
required for the satisfaction of '__can_iota_view<_Tp, _Up>' [with _Tp
= std::ranges::__detail::__max_diff_type; _Up =
std::ranges::__detail::__max_diff_type&]
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:771:   in
requirements  [with _Args = {std::ranges::__detail::__max_diff_type,
std::ranges::__detail::__max_diff_type&}]
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges:771: note:
the required expression
'(iota_view<...auto...>)((declval<_Args>)()...)' is invalid
gcc/build/x86_64-pc-linux-gnu/libstdc++-v3/include/ranges: In
instantiation of 'constexpr auto
std::ranges::views::_Indices::operator()(_Tp) const [with _Tp =
std::ranges::__detail::__max_diff_type]':
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:11:   required from
'constexpr bool test(T) [with T =
std::ranges::__detail::__max_diff_type]'
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:27:   required from here
cc1plus: note: set '-fconcepts-diagnostics-depth=' to at least 2 for more detail
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc: In function 'int main()':
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:28: error:
non-constant condition for static assertion
gcc/libstdc++-v3/testsuite/std/ranges/indices/1.cc:28: error:
'constexpr bool test(T) [with T =
std::ranges::__detail::__max_diff_type]' called in a constant
expression

Yuao
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..3932b78b806
--- /dev/null
+++ b/libstdc++-v3/testsuite/std/ranges/indices/1.cc
@@ -0,0 +1,29 @@
+// { dg-do run { target c++26 } }
+
+#include <testsuite_hooks.h>
+
+#include <ranges>
+#include <vector>
+#include <type_traits>
+
+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)>>);
+
+  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<size_t>(43));
+  static_assert(test<size_t>(43));
+  // VERIFY(test<std::ranges::__detail::__max_diff_type>(44));
+  // static_assert(test<std::ranges::__detail::__max_diff_type>(44));
+}

Reply via email to