Add missing move_constructible && regular_invocable constrains on functor type,
for invocations of `views::zip_transform` without range arguments.

libstdc++-v3/ChangeLog:

        * include/std/ranges (_ZipTransform::operator()):
        Add `move_constructible` and `regular_invocable` constraints
        * testsuite/std/ranges/zip_transform/1.cc: New tests
---
 Tested on x86_64-linux. OK for trunk?

 libstdc++-v3/include/std/ranges                |  3 ++-
 .../testsuite/std/ranges/zip_transform/1.cc    | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/include/std/ranges b/libstdc++-v3/include/std/ranges
index e21f5284b46..33e9926b89f 100644
--- a/libstdc++-v3/include/std/ranges
+++ b/libstdc++-v3/include/std/ranges
@@ -5332,7 +5332,8 @@ namespace views::__adaptor
     struct _ZipTransform
     {
       template<typename _Fp, typename... _Ts>
-       requires (sizeof...(_Ts) == 0) || 
__detail::__can_zip_transform_view<_Fp, _Ts...>
+       requires (sizeof...(_Ts) == 0) && move_constructible<decay_t<_Fp>> && 
regular_invocable<decay_t<_Fp>&>
+         || __detail::__can_zip_transform_view<_Fp, _Ts...>
        constexpr auto
        operator() [[nodiscard]] (_Fp&& __f, _Ts&&... __ts) const
        {
diff --git a/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc 
b/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc
index 20abdcba0f8..67839261cc7 100644
--- a/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc
+++ b/libstdc++-v3/testsuite/std/ranges/zip_transform/1.cc
@@ -9,6 +9,20 @@
 namespace ranges = std::ranges;
 namespace views = std::views;
 
+template<typename T>
+concept can_zip_transform = requires (T t) {
+  views::zip_transform(std::forward<T>(t));
+};
+
+static_assert(!can_zip_transform<int>);
+
+struct NonMovable {
+  NonMovable(NonMovable&&) = delete;
+};
+
+static_assert(!can_zip_transform<NonMovable>);
+static_assert(!can_zip_transform<NonMovable&>);
+
 constexpr bool
 test01()
 {
@@ -46,6 +60,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<ranges::range_value_t<decltype(z4)>, int> );
+
   return true;
 }
 
-- 
2.48.1

Reply via email to