[gcc r16-9408] libstdc++: Implement LWG 4074 changes to join_with_view's constraints
Patrick Palka
ppalka@gcc.gnu.org
Sun Jul 26 14:05:29 GMT 2026
https://gcc.gnu.org/g:67669313cebbb618d5a9046baaeb69ca885183f2
commit r16-9408-g67669313cebbb618d5a9046baaeb69ca885183f2
Author: Patrick Palka <ppalka@redhat.com>
Date: Sat Jul 25 16:12:16 2026 -0400
libstdc++: Implement LWG 4074 changes to join_with_view's constraints
libstdc++-v3/ChangeLog:
* include/std/ranges (__detail::__compatible_joinable_ranges):
Remove.
(__detail::__concat_reference_t): Move definition up.
(__detail::__concat_value_t): Likewise.
(__detail::__concat_rvalue_reference_t): Likewise.
(__detail::__concat_indirectly_readable_impl): Likewise.
(__detail::__concat_indirectly_readable): Likewise.
(__detail::__concatable): Likewise.
(join_with_view): Use __concatable instead of
__compatible_joinable_ranges in constraints as per LWG 4074.
(join_with_view::begin): Add __concatable constraint as per
LWG 4074.
(join_with_view::end): Likewise.
(join_with_view::_Iterator): Adjust out-of-line declaration.
(join_with_view::_Sentinel): Likewise.
Reviewed-by: Jonathan Wakely <jwakely@redhat.com>
(cherry picked from commit 368574dc98d3ad15fd099080965826e2afda963c)
Diff:
---
libstdc++-v3/include/std/ranges | 88 ++++++++++++++++++++---------------------
1 file changed, 42 insertions(+), 46 deletions(-)
diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index 686ed93a916d..92a2ae6db0f7 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -7347,22 +7347,51 @@ namespace views::__adaptor
#ifdef __cpp_lib_ranges_join_with // C++ >= 23
namespace __detail
{
- template<typename _Range, typename _Pattern>
- concept __compatible_joinable_ranges
- = common_with<range_value_t<_Range>, range_value_t<_Pattern>>
- && common_reference_with<range_reference_t<_Range>,
- range_reference_t<_Pattern>>
- && common_reference_with<range_rvalue_reference_t<_Range>,
- range_rvalue_reference_t<_Pattern>>;
-
template<typename _Range>
concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>;
+
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 4074. compatible-joinable-ranges is underconstrained
+ template<typename... _Rs>
+ using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
+
+ template<typename... _Rs>
+ using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
+
+ template<typename... _Rs>
+ using __concat_rvalue_reference_t
+ = common_reference_t<range_rvalue_reference_t<_Rs>...>;
+
+ template<typename _Ref, typename _RRef, typename _It>
+ concept __concat_indirectly_readable_impl = requires(const _It __it) {
+ { *__it } -> convertible_to<_Ref>;
+ { ranges::iter_move(__it) } -> convertible_to<_RRef>;
+ };
+
+ template<typename... _Rs>
+ concept __concat_indirectly_readable
+ = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
+ && common_reference_with<__concat_reference_t<_Rs...>&&,
+ __concat_rvalue_reference_t<_Rs...>&&>
+ && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
+ __concat_value_t<_Rs...> const&>
+ && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
+ __concat_rvalue_reference_t<_Rs...>,
+ iterator_t<_Rs>>
+ && ...);
+
+ template<typename... _Rs>
+ concept __concatable = requires {
+ typename __concat_reference_t<_Rs...>;
+ typename __concat_value_t<_Rs...>;
+ typename __concat_rvalue_reference_t<_Rs...>;
+ } && __concat_indirectly_readable<_Rs...>;
}
template<input_range _Vp, forward_range _Pattern>
requires view<_Vp> && view<_Pattern>
&& input_range<range_reference_t<_Vp>>
- && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
+ && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
class join_with_view : public view_interface<join_with_view<_Vp, _Pattern>>
{
using _InnerRange = range_reference_t<_Vp>;
@@ -7479,6 +7508,7 @@ namespace views::__adaptor
&& forward_range<const _Pattern>
&& is_reference_v<range_reference_t<const _Vp>>
&& input_range<range_reference_t<const _Vp>>
+ && __detail::__concatable<range_reference_t<const _Vp>, const _Pattern>
{ return _Iterator<true>{*this, ranges::begin(_M_base)}; }
constexpr auto
@@ -7500,6 +7530,7 @@ namespace views::__adaptor
&& forward_range<const _Pattern>
&& is_reference_v<range_reference_t<const _Vp>>
&& input_range<range_reference_t<const _Vp>>
+ && __detail::__concatable<range_reference_t<const _Vp>, const _Pattern>
{
using _InnerConstRange = range_reference_t<const _Vp>;
if constexpr (forward_range<_InnerConstRange>
@@ -7523,7 +7554,7 @@ namespace views::__adaptor
template<input_range _Vp, forward_range _Pattern>
requires view<_Vp> && view<_Pattern>
&& input_range<range_reference_t<_Vp>>
- && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
+ && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
template<bool _Const>
class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const>
{
@@ -7812,7 +7843,7 @@ namespace views::__adaptor
template<input_range _Vp, forward_range _Pattern>
requires view<_Vp> && view<_Pattern>
&& input_range<range_reference_t<_Vp>>
- && __detail::__compatible_joinable_ranges<range_reference_t<_Vp>, _Pattern>
+ && __detail::__concatable<range_reference_t<_Vp>, _Pattern>
template<bool _Const>
class join_with_view<_Vp, _Pattern>::_Sentinel
{
@@ -9791,41 +9822,6 @@ namespace ranges
{
namespace __detail
{
- template<typename... _Rs>
- using __concat_reference_t = common_reference_t<range_reference_t<_Rs>...>;
-
- template<typename... _Rs>
- using __concat_value_t = common_type_t<range_value_t<_Rs>...>;
-
- template<typename... _Rs>
- using __concat_rvalue_reference_t
- = common_reference_t<range_rvalue_reference_t<_Rs>...>;
-
- template<typename _Ref, typename _RRef, typename _It>
- concept __concat_indirectly_readable_impl = requires(const _It __it) {
- { *__it } -> convertible_to<_Ref>;
- { ranges::iter_move(__it) } -> convertible_to<_RRef>;
- };
-
- template<typename... _Rs>
- concept __concat_indirectly_readable
- = common_reference_with<__concat_reference_t<_Rs...>&&, __concat_value_t<_Rs...>&>
- && common_reference_with<__concat_reference_t<_Rs...>&&,
- __concat_rvalue_reference_t<_Rs...>&&>
- && common_reference_with<__concat_rvalue_reference_t<_Rs...>&&,
- __concat_value_t<_Rs...> const&>
- && (__concat_indirectly_readable_impl<__concat_reference_t<_Rs...>,
- __concat_rvalue_reference_t<_Rs...>,
- iterator_t<_Rs>>
- && ...);
-
- template<typename... _Rs>
- concept __concatable = requires {
- typename __concat_reference_t<_Rs...>;
- typename __concat_value_t<_Rs...>;
- typename __concat_rvalue_reference_t<_Rs...>;
- } && __concat_indirectly_readable<_Rs...>;
-
template<bool _Const, typename _Range, typename... _Rs>
struct __all_but_last_common
{
More information about the Libstdc++-cvs
mailing list