From: Tomasz Kamiński Date: Fri, 7 Mar 2025 10:54:38 +0000 (+0100) Subject: libstdc++: Fix views::zip_transform constraints for empty range pack [PR111138] X-Git-Tag: basepoints/gcc-16~1496 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5abe571e0276fafcc6eed27c27abb28943e67c6f;p=thirdparty%2Fgcc.git libstdc++: Fix views::zip_transform constraints for empty range pack [PR111138] Add missing move_constructible && regular_invocable constrains on functor type, and is_object on functor result type for invocations of views::zip_transform without range arguments. PR libstdc++/111138 libstdc++-v3/ChangeLog: * include/std/ranges (_ZipTransform::operator()): Create separate overload for calls with empty range pack, and add move_constructible, regular_invocable and is_object_v>> constraints. * testsuite/std/ranges/zip_transform/1.cc: New tests Reviewed-by: Patrick Palka Jonathan Wakely Signed-off-by: Tomasz Kamiński --- diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges index ef277b81bd3c..34c6f113e216 100644 --- a/libstdc++-v3/include/std/ranges +++ b/libstdc++-v3/include/std/ranges @@ -5333,15 +5333,21 @@ namespace views::__adaptor struct _ZipTransform { + template + requires move_constructible> && regular_invocable&> + && is_object_v&>>> + constexpr auto + operator() [[nodiscard]] (_Fp&& __f) const + { + return views::empty&>>>; + } + template - requires (sizeof...(_Ts) == 0) || __detail::__can_zip_transform_view<_Fp, _Ts...> + requires (sizeof...(_Ts) != 0) && __detail::__can_zip_transform_view<_Fp, _Ts...> constexpr auto operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const { - if constexpr (sizeof...(_Ts) == 0) - return views::empty&>>>; - else - return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...); + return zip_transform_view(std::forward<_Fp>(__f), std::forward<_Ts>(__ts)...); } }; diff --git a/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc b/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc index 20abdcba0f85..9a0ad3814e66 100644 --- a/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc +++ b/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc @@ -9,6 +9,23 @@ namespace ranges = std::ranges; namespace views = std::views; +template +concept can_zip_transform = requires (T t) { + views::zip_transform(std::forward(t)); +}; + +static_assert(!can_zip_transform); + +struct NonMovable { + NonMovable(NonMovable&&) = delete; +}; + +static_assert(!can_zip_transform); +static_assert(!can_zip_transform); + +static_assert(!can_zip_transform); +static_assert(can_zip_transform); + constexpr bool test01() { @@ -46,6 +63,10 @@ test01() VERIFY( ranges::size(z3) == 3 ); VERIFY( ranges::equal(z3, (int[]){3, 6, 9}) ); + auto z4 = views::zip_transform([] () { return 1; }); + VERIFY( ranges::size(z4) == 0 ); + static_assert( std::same_as, int> ); + return true; }