From: Patrick Palka Date: Sat, 25 Jul 2026 20:12:16 +0000 (-0400) Subject: libstdc++: Implement LWG 4074 changes to join_with_view's constraints X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=368574dc98d3ad15fd099080965826e2afda963c;p=thirdparty%2Fgcc.git 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 --- diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index 3e0df8d083c..07e26542f9e 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -7363,22 +7363,51 @@ namespace views::__adaptor #ifdef __cpp_lib_ranges_join_with // C++ >= 23 namespace __detail { - template - concept __compatible_joinable_ranges - = common_with, range_value_t<_Pattern>> - && common_reference_with, - range_reference_t<_Pattern>> - && common_reference_with, - range_rvalue_reference_t<_Pattern>>; - template concept __bidirectional_common = bidirectional_range<_Range> && common_range<_Range>; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 4074. compatible-joinable-ranges is underconstrained + template + using __concat_reference_t = common_reference_t...>; + + template + using __concat_value_t = common_type_t...>; + + template + using __concat_rvalue_reference_t + = common_reference_t...>; + + template + concept __concat_indirectly_readable_impl = requires(const _It __it) { + { *__it } -> convertible_to<_Ref>; + { ranges::iter_move(__it) } -> convertible_to<_RRef>; + }; + + template + 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 + concept __concatable = requires { + typename __concat_reference_t<_Rs...>; + typename __concat_value_t<_Rs...>; + typename __concat_rvalue_reference_t<_Rs...>; + } && __concat_indirectly_readable<_Rs...>; } template requires view<_Vp> && view<_Pattern> && input_range> - && __detail::__compatible_joinable_ranges, _Pattern> + && __detail::__concatable, _Pattern> class join_with_view : public view_interface> { using _InnerRange = range_reference_t<_Vp>; @@ -7495,6 +7524,7 @@ namespace views::__adaptor && forward_range && is_reference_v> && input_range> + && __detail::__concatable, const _Pattern> { return _Iterator{*this, ranges::begin(_M_base)}; } constexpr auto @@ -7516,6 +7546,7 @@ namespace views::__adaptor && forward_range && is_reference_v> && input_range> + && __detail::__concatable, const _Pattern> { using _InnerConstRange = range_reference_t; if constexpr (forward_range<_InnerConstRange> @@ -7539,7 +7570,7 @@ namespace views::__adaptor template requires view<_Vp> && view<_Pattern> && input_range> - && __detail::__compatible_joinable_ranges, _Pattern> + && __detail::__concatable, _Pattern> template class join_with_view<_Vp, _Pattern>::_Iterator : public __iter_cat<_Const> { @@ -7828,7 +7859,7 @@ namespace views::__adaptor template requires view<_Vp> && view<_Pattern> && input_range> - && __detail::__compatible_joinable_ranges, _Pattern> + && __detail::__concatable, _Pattern> template class join_with_view<_Vp, _Pattern>::_Sentinel { @@ -9810,41 +9841,6 @@ namespace ranges { namespace __detail { - template - using __concat_reference_t = common_reference_t...>; - - template - using __concat_value_t = common_type_t...>; - - template - using __concat_rvalue_reference_t - = common_reference_t...>; - - template - concept __concat_indirectly_readable_impl = requires(const _It __it) { - { *__it } -> convertible_to<_Ref>; - { ranges::iter_move(__it) } -> convertible_to<_RRef>; - }; - - template - 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 - concept __concatable = requires { - typename __concat_reference_t<_Rs...>; - typename __concat_value_t<_Rs...>; - typename __concat_rvalue_reference_t<_Rs...>; - } && __concat_indirectly_readable<_Rs...>; - template struct __all_but_last_common {