On Wed, Oct 15, 2025 at 12:21 AM Jonathan Wakely <[email protected]> wrote: > > On Tue, 14 Oct 2025 at 17:08, Yuao Ma <[email protected]> wrote: > > > > 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. > > static operator() is a C++23 feature, so wasn't an option for the > original C++20 views. > > I'm not sure it makes much difference on the ABI used for most of our > supported targets, and it should be optimized away anyway. In fact, we > could add [[__gnu__::__always_inline__]] to the operator() here, since > it's incredibly simple. > > > > The testcase got updated, testing against different type and size. But > > ranges::__detail::max_{size, diff}_type not working here: > > Ah yes, that's a problem. If you create > views::indices(ranges::distance(views::iota(0ULL, 1ULL))) then you > need to create an iota_view of the difference type of iota(0ULL, > 1ULL), but that can't be represented. You would need an integer-like > type wider than our widest integer-like type. > > That might be a defect in the wording for views::indices, but that's > not your concern. There's no need to test it with that type then. >
Thanks for the explanation! I also remember that P1522 seems to solve the previous size_t problem about iota. The updated patch is rfr now. Testcase updated with noexcept check. Yuao
From c6318d68f3b3064bc279eaeb9bc282c8484049ad Mon Sep 17 00:00:00 2001 From: Yuao Ma <[email protected]> Date: Wed, 15 Oct 2025 00:28:48 +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 | 31 +++++++++++++++++++ 4 files changed, 62 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..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..805b29e358f --- /dev/null +++ b/libstdc++-v3/testsuite/std/ranges/indices/1.cc @@ -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)); +} -- 2.43.0
