[gcc r16-9408] libstdc++: Implement LWG 4074 changes to join_with_view's constraints
Patrick Palka via Gcc-cvs <[email protected]>
| Newsgroups | gmane.comp.gcc.cvs |
|---|---|
| Message-ID | <20260726140529.90F394BA5434__39149.9589941063$1785074738$gmane$org@sourceware.org> |
https://gcc.gnu.org/g:67669313cebbb618d5a9046baaeb69ca885183f2 commit r16-9408-g67669313cebbb618d5a9046baaeb69ca885183f2 Author: Patrick Palka <[email protected]> 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 <[email protected]> (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 {