]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Add missing constraints to views::indices
authorJonathan Wakely <jwakely@redhat.com>
Tue, 21 Oct 2025 20:21:45 +0000 (21:21 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Wed, 22 Oct 2025 08:59:36 +0000 (09:59 +0100)
Calling views::indices(n) should be expression equivalent to
views::iota(decltype(n)(0), n), which means it should have the same
constraints as views::iota and be SFINAE-friendly.

libstdc++-v3/ChangeLog:

* include/std/ranges (indices::operator()): Constrain using
__can_iota_view concept.
* testsuite/std/ranges/indices/1.cc: Check SFINAE-friendliness
required by expression equivalence. Replace unused <vector>
header with <stddef.h> needed for size_t.

libstdc++-v3/include/std/ranges
libstdc++-v3/testsuite/std/ranges/indices/1.cc

index 25d2e28e72ffa5b0dbd0a0c250fde6290a1785d2..158692d92a70e69eec3d5cacdf2dd429055bb5b7 100644 (file)
@@ -791,6 +791,7 @@ namespace views
   struct _Indices
   {
     template<ranges::__detail::__is_integer_like _Tp>
+      requires __detail::__can_iota_view<_Tp>
       [[nodiscard]] constexpr auto
       operator() (_Tp __e) const noexcept
       { return iota(_Tp{}, __e); }
index 805b29e358f76865b31dc5b68ecf9f7d336cbafd..038b38f0ce0d8cdcbb137b1c9665f29664d0bbdb 100644 (file)
@@ -4,7 +4,7 @@
 
 #include <ranges>
 #include <type_traits>
-#include <vector>
+#include <stddef.h>
 
 template <typename T>
 constexpr bool test(T n) {
@@ -29,3 +29,17 @@ int main() {
   VERIFY(test<size_t>(44));
   static_assert(test<size_t>(44));
 }
+
+template<typename T>
+constexpr size_t test_wider(T n)
+{
+  // If indices(n) works, try again with ranges::distance(indices(n)),
+  // which will be a wider type, until we get to an unsupported type.
+  // This verifies that indices(n) is SFINAE-friendly, because otherwise we
+  // would get a hard error outside the immediate context checked by requires.
+  if constexpr (requires { std::views::indices(n); })
+    return test_wider(std::ranges::distance(std::views::indices(n)));
+  return sizeof(T);
+}
+
+static_assert(test_wider(0) > sizeof(long long));