about summary refs log tree commit diff
diff options
context:
space:
mode:
authoronestacked <chrisi.schrefl@gmail.com>2022-09-30 17:16:59 +0200
committeronestacked <chrisi.schrefl@gmail.com>2022-09-30 17:16:59 +0200
commitb73241aa5b0eab8aebf1600c598180bbd33be31c (patch)
treea8ab003b577c19409da8077e8fdd4f061676a306
parentf914b82a754c6d85c0a909ab152f5b611defef73 (diff)
downloadrust-b73241aa5b0eab8aebf1600c598180bbd33be31c.tar.gz
rust-b73241aa5b0eab8aebf1600c598180bbd33be31c.zip
Added more const_closure functionality.
-rw-r--r--library/core/src/cmp.rs4
-rw-r--r--library/core/src/const_closure.rs79
-rw-r--r--library/core/src/iter/adapters/array_chunks.rs12
-rw-r--r--library/core/src/iter/adapters/by_ref_sized.rs10
-rw-r--r--library/core/src/iter/adapters/mod.rs6
5 files changed, 62 insertions, 49 deletions
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index f0fa2e1d2c1..5033e744def 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1267,7 +1267,7 @@ where
     {
         f(v1).cmp(&f(v2))
     }
-    min_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
+    min_by(v1, v2, ConstFnMutClosure { data: &mut f, func: imp })
 }
 
 /// Compares and returns the maximum of two values.
@@ -1352,7 +1352,7 @@ where
     {
         f(v1).cmp(&f(v2))
     }
-    max_by(v1, v2, ConstFnMutClosure::new(&mut f, imp))
+    max_by(v1, v2, ConstFnMutClosure { data: &mut f, func: imp })
 }
 
 // Implementation of PartialEq, Eq, PartialOrd and Ord for primitive types
diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs
index d2e80e8e7e5..23b3f87e721 100644
--- a/library/core/src/const_closure.rs
+++ b/library/core/src/const_closure.rs
@@ -16,48 +16,45 @@ use crate::marker::Destruct;
 /// assert!(7 == cl(2));
 /// assert!(8 == cl(1));
 /// ```
-pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> {
-    data: &'a mut CapturedData,
-    func: Function,
+pub(crate) struct ConstFnMutClosure<CapturedData, Function> {
+    /// The Data captured by the Closure.
+    /// Must be either a (mutable) reference or a tuple of (mutable) references.
+    pub data: CapturedData,
+    /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn
+    pub func: Function,
 }
 
-impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> {
-    /// Function for creating a new closure.
-    ///
-    /// `data` is the a mutable borrow of data that is captured from the environment.
-    ///
-    /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
-    ///   and return the return value of the closure.
-    pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
-        data: &'a mut CapturedData,
-        func: Function,
-    ) -> Self
-    where
-        Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
-    {
-        Self { data, func }
-    }
-}
-
-impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
-    FnOnce<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
-where
-    Function:
-        ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
-{
-    type Output = ClosureReturnValue;
+macro_rules! impl_fn_mut_tuple {
+    ($($var:ident)*) => {
+      #[allow(unused_parens)]
+      impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
+        FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
+      where
+        Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
+      {
+        type Output = ClosureReturnValue;
 
-    extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
-        self.call_mut(args)
-    }
-}
+        extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
+          self.call_mut(args)
+        }
+      }
+      #[allow(unused_parens)]
+      impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
+        FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
+      where
+        Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
+      {
+        extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
+          #[allow(non_snake_case)]
+          let ($($var),*) = &mut self.data;
+          (self.func)(($($var),*), args)
+        }
+      }
 
-impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
-    FnMut<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
-where
-    Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
-{
-    extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
-        (self.func)(self.data, args)
-    }
-}
+    };
+  }
+impl_fn_mut_tuple!(A);
+impl_fn_mut_tuple!(A B);
+impl_fn_mut_tuple!(A B C);
+impl_fn_mut_tuple!(A B C D);
+impl_fn_mut_tuple!(A B C D E);
diff --git a/library/core/src/iter/adapters/array_chunks.rs b/library/core/src/iter/adapters/array_chunks.rs
index 489fb13c0dc..02abce986cb 100644
--- a/library/core/src/iter/adapters/array_chunks.rs
+++ b/library/core/src/iter/adapters/array_chunks.rs
@@ -88,7 +88,11 @@ where
         Self: Sized,
         F: FnMut(B, Self::Item) -> B,
     {
-        self.try_fold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0
+        self.try_fold(
+            init,
+            ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp },
+        )
+        .0
     }
 }
 
@@ -132,7 +136,11 @@ where
         Self: Sized,
         F: FnMut(B, Self::Item) -> B,
     {
-        self.try_rfold(init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp)).0
+        self.try_rfold(
+            init,
+            ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp },
+        )
+        .0
     }
 }
 
diff --git a/library/core/src/iter/adapters/by_ref_sized.rs b/library/core/src/iter/adapters/by_ref_sized.rs
index 1945e402ff5..f3b8cfdb47b 100644
--- a/library/core/src/iter/adapters/by_ref_sized.rs
+++ b/library/core/src/iter/adapters/by_ref_sized.rs
@@ -44,8 +44,12 @@ impl<I: Iterator> Iterator for ByRefSized<'_, I> {
         F: FnMut(B, Self::Item) -> B,
     {
         // `fold` needs ownership, so this can't forward directly.
-        I::try_fold(self.0, init, ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp))
-            .0
+        I::try_fold(
+            self.0,
+            init,
+            ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp },
+        )
+        .0
     }
 
     #[inline]
@@ -84,7 +88,7 @@ impl<I: DoubleEndedIterator> DoubleEndedIterator for ByRefSized<'_, I> {
         I::try_rfold(
             self.0,
             init,
-            ConstFnMutClosure::new(&mut f, NeverShortCircuit::wrap_mut_2_imp),
+            ConstFnMutClosure { data: &mut f, func: NeverShortCircuit::wrap_mut_2_imp },
         )
         .0
     }
diff --git a/library/core/src/iter/adapters/mod.rs b/library/core/src/iter/adapters/mod.rs
index de3a534f81b..8f8748feae4 100644
--- a/library/core/src/iter/adapters/mod.rs
+++ b/library/core/src/iter/adapters/mod.rs
@@ -209,7 +209,11 @@ where
         Self: Sized,
         F: FnMut(B, Self::Item) -> B,
     {
-        self.try_fold(init, ConstFnMutClosure::new(&mut fold, NeverShortCircuit::wrap_mut_2_imp)).0
+        self.try_fold(
+            init,
+            ConstFnMutClosure { data: &mut fold, func: NeverShortCircuit::wrap_mut_2_imp },
+        )
+        .0
     }
 }