[PATCH v1] libstdc++: separate std::ranges::subrange declarations from ranges_util.h
yuao via Sourceware Forge
forge-bot+yuao@forge-stage.sourceware.org
Tue Sep 29 14:24:46 GMT 2026
From: Yuao Ma <c8ef@outlook.com>
gcc/testsuite/ChangeLog:
* g++.dg/modules/inst-8_a.C: Include <new> for placement new,
previously included transitively via <tuple>.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Regenerate.
* include/Makefile.in: Add subrangefwd.h.
* include/bits/ranges_util.h: Include <bits/subrangefwd.h>.
(subrange_kind): Move to <bits/subrangefwd.h>.
(subrange): Remove default template arguments, now on the
declaration in <bits/subrangefwd.h>.
(get): Use non-deduced return type.
(__is_subrange, __is_tuple_like_v, tuple_size, tuple_element):
Move specializations for subrange to <bits/subrangefwd.h>.
* include/std/tuple: Include <bits/subrangefwd.h> instead of
<bits/ranges_util.h>.
* include/bits/subrangefwd.h: New file.
---
```
gcc/testsuite/ChangeLog:
* g++.dg/modules/inst-8_a.C: Include <new> for placement new,
previously included transitively via <tuple>.
libstdc++-v3/ChangeLog:
* include/Makefile.am: Regenerate.
* include/Makefile.in: Add subrangefwd.h.
* include/bits/ranges_util.h: Include <bits/subrangefwd.h>.
(subrange_kind): Move to <bits/subrangefwd.h>.
(subrange): Remove default template arguments, now on the
declaration in <bits/subrangefwd.h>.
(get): Use non-deduced return type.
(__is_subrange, __is_tuple_like_v, tuple_size, tuple_element):
Move specializations for subrange to <bits/subrangefwd.h>.
* include/std/tuple: Include <bits/subrangefwd.h> instead of
<bits/ranges_util.h>.
* include/bits/subrangefwd.h: New file.
```
This is a forge pull request published on the gcc-patches mailing list mailing list
as requested by yuao via Sourceware Forge <forge-bot+yuao@forge-stage.sourceware.org>.
Forge discussion: https://forge.sourceware.org/gcc/gcc/pulls/235
Get it locally using:
```
git fetch forge-upstream "+refs/versioned_pull/235/*:refs/versioned_pull/235/*"
git switch -c "pr-235-v1" "refs/versioned_pull/235/1/head"
```
Or, download the patch at: https://forge.sourceware.org/gcc/gcc/pulls/235.diff
Created on: 2026-09-29 14:23:56+00:00
Latest update: 2026-09-29 14:24:46+00:00
Changes: 6 changed files, 118 additions, 42 deletions
Head revision: yuao/gcc ref tuple-range commit 23d9f6413438e344cd93346f74f3eb3ffd81c36f
Base revision: gcc/gcc ref trunk commit db655b1fdce54adaf3d983ad73dd02db6cbdedf8 r17-4418-gdb655b1fdce54a
Merge base: db655b1fdce54adaf3d983ad73dd02db6cbdedf8
Requested Reviewers: redi
Changed files:
- A: libstdc++-v3/include/bits/subrangefwd.h
- M: gcc/testsuite/g++.dg/modules/inst-8_a.C
- M: libstdc++-v3/include/Makefile.am
- M: libstdc++-v3/include/Makefile.in
- M: libstdc++-v3/include/bits/ranges_util.h
- M: libstdc++-v3/include/std/tuple
gcc/testsuite/g++.dg/modules/inst-8_a.C | 1 +
libstdc++-v3/include/Makefile.am | 1 +
libstdc++-v3/include/Makefile.in | 1 +
libstdc++-v3/include/bits/ranges_util.h | 46 ++--------
libstdc++-v3/include/bits/subrangefwd.h | 109 ++++++++++++++++++++++++
libstdc++-v3/include/std/tuple | 2 +-
6 files changed, 118 insertions(+), 42 deletions(-)
create mode 100644 libstdc++-v3/include/bits/subrangefwd.h
diff --git a/gcc/testsuite/g++.dg/modules/inst-8_a.C b/gcc/testsuite/g++.dg/modules/inst-8_a.C
index 1b0a47978cb2d..da8afd35beab7 100644
--- a/gcc/testsuite/g++.dg/modules/inst-8_a.C
+++ b/gcc/testsuite/g++.dg/modules/inst-8_a.C
@@ -5,6 +5,7 @@
module;
#include <coroutine>
+#include <new>
#include <tuple>
#include <typeinfo>
export module std;
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 3c30aa21d6b55..ebdb3410df15f 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -185,6 +185,7 @@ bits_freestanding = \
${bits_srcdir}/stl_raw_storage_iter.h \
${bits_srcdir}/stl_relops.h \
${bits_srcdir}/stl_uninitialized.h \
+ ${bits_srcdir}/subrangefwd.h \
${bits_srcdir}/text_encoding-data.h \
${bits_srcdir}/version.h \
${bits_srcdir}/string_view.tcc \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index d081481293fff..333d17cb6c154 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -543,6 +543,7 @@ bits_freestanding = \
${bits_srcdir}/stl_raw_storage_iter.h \
${bits_srcdir}/stl_relops.h \
${bits_srcdir}/stl_uninitialized.h \
+ ${bits_srcdir}/subrangefwd.h \
${bits_srcdir}/text_encoding-data.h \
${bits_srcdir}/version.h \
${bits_srcdir}/string_view.tcc \
diff --git a/libstdc++-v3/include/bits/ranges_util.h b/libstdc++-v3/include/bits/ranges_util.h
index 423767f00fcb6..6f78c6c460a78 100644
--- a/libstdc++-v3/include/bits/ranges_util.h
+++ b/libstdc++-v3/include/bits/ranges_util.h
@@ -35,6 +35,7 @@
# include <bits/utility.h>
# include <bits/invoke.h>
# include <bits/cpp_type_traits.h> // __can_use_memchr_for_find
+# include <bits/subrangefwd.h> // subrange, get, tuple_size
#if __glibcxx_tuple_like // >= C++23
# include <bits/stl_pair.h> // __pair_like, __is_tuple_like_v
#endif
@@ -259,12 +260,8 @@ namespace ranges
namespace views { struct _Drop; } // defined in <ranges>
- enum class subrange_kind : bool { unsized, sized };
-
- /// The ranges::subrange class template
- template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
- subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
- ? subrange_kind::sized : subrange_kind::unsized>
+ template<input_or_output_iterator _It, sentinel_for<_It> _Sent,
+ subrange_kind _Kind>
requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
class subrange : public view_interface<subrange<_It, _Sent, _Kind>>
{
@@ -450,7 +447,7 @@ namespace ranges
// constrain I to be copyable when N == 0
template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
requires ((_Num == 0 && copyable<_It>) || _Num == 1)
- constexpr auto
+ constexpr __conditional_t<_Num == 0, _It, _Sent>
get(const subrange<_It, _Sent, _Kind>& __r)
{
if constexpr (_Num == 0)
@@ -461,7 +458,7 @@ namespace ranges
template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
requires (_Num < 2)
- constexpr auto
+ constexpr __conditional_t<_Num == 0, _It, _Sent>
get(subrange<_It, _Sent, _Kind>&& __r)
{
if constexpr (_Num == 0)
@@ -478,18 +475,8 @@ namespace ranges
using borrowed_subrange_t = __conditional_t<borrowed_range<_Range>,
subrange<iterator_t<_Range>>,
dangling>;
-
- // __is_subrange is defined in <bits/utility.h>.
- template<typename _Iter, typename _Sent, subrange_kind _Kind>
- inline constexpr bool __detail::__is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
} // namespace ranges
-#if __glibcxx_tuple_like // >= C++23
- // __is_tuple_like_v is defined in <bits/stl_pair.h>.
- template<typename _It, typename _Sent, ranges::subrange_kind _Kind>
- inline constexpr bool __is_tuple_like_v<ranges::subrange<_It, _Sent, _Kind>> = true;
-#endif
-
// The following ranges algorithms are used by <ranges>, and are defined here
// so that <ranges> can avoid including all of <bits/ranges_algo.h>.
namespace ranges
@@ -827,29 +814,6 @@ namespace ranges
} // namespace ranges
- using ranges::get;
-
- template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
- struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
- : integral_constant<size_t, 2>
- { };
-
- template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
- struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
- { using type = _Iter; };
-
- template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
- struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
- { using type = _Sent; };
-
- template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
- struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
- { using type = _Iter; };
-
- template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
- struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
- { using type = _Sent; };
-
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // library concepts
diff --git a/libstdc++-v3/include/bits/subrangefwd.h b/libstdc++-v3/include/bits/subrangefwd.h
new file mode 100644
index 0000000000000..2a7c83b54f5bb
--- /dev/null
+++ b/libstdc++-v3/include/bits/subrangefwd.h
@@ -0,0 +1,109 @@
+// Forward declarations for std::ranges::subrange -*- C++ -*-
+
+// Copyright (C) 2026 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/subrangefwd.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{ranges}
+ */
+
+#ifndef _SUBRANGEFWD_H
+#define _SUBRANGEFWD_H 1
+
+#ifdef _GLIBCXX_SYSHDR
+#pragma GCC system_header
+#endif
+
+#include <bits/version.h>
+
+#ifdef __glibcxx_ranges // C++ >= 20 && concepts
+#include <bits/stl_iterator_base_types.h>
+#include <bits/utility.h>
+#if __glibcxx_tuple_like // >= C++23
+# include <bits/stl_pair.h>
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+namespace ranges
+{
+ enum class subrange_kind : bool { unsized, sized };
+
+ /// The ranges::subrange class template.
+ template<input_or_output_iterator _It, sentinel_for<_It> _Sent = _It,
+ subrange_kind _Kind = sized_sentinel_for<_Sent, _It>
+ ? subrange_kind::sized : subrange_kind::unsized>
+ requires (_Kind == subrange_kind::sized || !sized_sentinel_for<_Sent, _It>)
+ class subrange;
+
+ template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
+ requires ((_Num == 0 && copyable<_It>) || _Num == 1)
+ constexpr __conditional_t<_Num == 0, _It, _Sent>
+ get(const subrange<_It, _Sent, _Kind>& __r);
+
+ template<size_t _Num, class _It, class _Sent, subrange_kind _Kind>
+ requires (_Num < 2)
+ constexpr __conditional_t<_Num == 0, _It, _Sent>
+ get(subrange<_It, _Sent, _Kind>&& __r);
+
+ // __is_subrange is defined in <bits/utility.h>.
+ template<typename _Iter, typename _Sent, subrange_kind _Kind>
+ inline constexpr bool
+ __detail::__is_subrange<subrange<_Iter, _Sent, _Kind>> = true;
+} // namespace ranges
+
+ using ranges::get;
+
+#if __glibcxx_tuple_like // >= C++23
+ // __is_tuple_like_v is defined in <bits/stl_pair.h>.
+ template<typename _It, typename _Sent, ranges::subrange_kind _Kind>
+ inline constexpr bool
+ __is_tuple_like_v<ranges::subrange<_It, _Sent, _Kind>> = true;
+#endif
+
+ template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+ struct tuple_size<ranges::subrange<_Iter, _Sent, _Kind>>
+ : integral_constant<size_t, 2>
+ { };
+
+ template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+ struct tuple_element<0, ranges::subrange<_Iter, _Sent, _Kind>>
+ { using type = _Iter; };
+
+ template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+ struct tuple_element<1, ranges::subrange<_Iter, _Sent, _Kind>>
+ { using type = _Sent; };
+
+ template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+ struct tuple_element<0, const ranges::subrange<_Iter, _Sent, _Kind>>
+ { using type = _Iter; };
+
+ template<typename _Iter, typename _Sent, ranges::subrange_kind _Kind>
+ struct tuple_element<1, const ranges::subrange<_Iter, _Sent, _Kind>>
+ { using type = _Sent; };
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+#endif // __glibcxx_ranges
+#endif // _SUBRANGEFWD_H
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 63b4010c0b5e8..67be8374cf1fa 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -43,7 +43,7 @@
#include <bits/invoke.h> // for std::__invoke
#if __cplusplus > 201703L
# include <compare>
-# include <bits/ranges_util.h> // for std::ranges::subrange
+# include <bits/subrangefwd.h> // for std::ranges::subrange
#endif
#define __glibcxx_want_constexpr_tuple
--
2.54.0
More information about the Libstdc++
mailing list