[gcc r17-66] libstdc++: Reject using views::iota on iota_view.

Tomasz Kaminski tkaminsk@gcc.gnu.org
Fri Apr 24 12:11:06 GMT 2026


https://gcc.gnu.org/g:9a00a26364360c8db8c06fffee86a4c722531f19

commit r17-66-g9a00a26364360c8db8c06fffee86a4c722531f19
Author: Tomasz Kamiński <tkaminsk@redhat.com>
Date:   Fri Apr 24 13:02:22 2026 +0200

    libstdc++: Reject using views::iota on iota_view.
    
    Resolves LWG4096, views::iota(views::iota(0)) should be rejected.
    
    For __e of type _Tp that is specialization of iota_view, the CTAD based
    expression iota_view(__e) is well formed, and creates a copy of __e.
    As iota_view<decay_t<_Tp>> is ill-formed in this case (iota_view is not
    weakly_incrementable), using that type in return type explicitly, removes
    the overload from overload resolution in this case.
    
    The (now redudant) __detail::__can_iota_view constrain in template head is
    preserved, to provide error messages consistent with adaptors for other
    non-incrementable types.
    
    libstdc++-v3/ChangeLog:
    
            * include/std/ranges (_Iota::operator()(_Tp&&)): Replace
            auto return type and CTAD with iota_view<decay_t<_Tp>>.
            * testsuite/std/ranges/iota/iota_view.cc: Tests if
            views::iota(iota_view) is rejected.
    
    Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
    Signed-off-by: Tomasz Kamiński <tkaminsk@redhat.com>

Diff:
---
 libstdc++-v3/include/std/ranges                     |  6 ++++--
 libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc | 11 +++++++++++
 2 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 24416b659c10..55d3c520ba4c 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -900,10 +900,12 @@ namespace views
 
   struct _Iota
   {
+    // _GLIBCXX_RESOLVE_LIB_DEFECTS
+    // 4096. views::iota(views::iota(0)) should be rejected
     template<__detail::__can_iota_view _Tp>
-      constexpr auto
+      constexpr iota_view<decay_t<_Tp>>
       operator() [[nodiscard]] (_Tp&& __e) const
-      { return iota_view(std::forward<_Tp>(__e)); }
+      { return iota_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
 
     template<typename _Tp, typename _Up>
       requires __detail::__can_iota_view<_Tp, _Up>
diff --git a/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc b/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc
index f3fddbd3531f..7b748cf9c3a9 100644
--- a/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc
+++ b/libstdc++-v3/testsuite/std/ranges/iota/iota_view.cc
@@ -22,6 +22,17 @@
 #include <vector>
 #include <testsuite_hooks.h>
 
+template<typename Inc>
+concept can_iota = requires (Inc&& __inc)
+{ std::views::iota(__inc); };
+
+static_assert( can_iota<int> );
+static_assert( can_iota<int*> );
+static_assert( !can_iota<std::ranges::iota_view<int>> );
+static_assert( !can_iota<const std::ranges::iota_view<int>> );
+static_assert( !can_iota<std::ranges::iota_view<int>&> );
+static_assert( !can_iota<const std::ranges::iota_view<int>&> );
+
 void
 test01()
 {


More information about the Libstdc++-cvs mailing list