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));
+}