diff options
| author | onestacked <chrisi.schrefl@gmail.com> | 2022-09-30 17:16:59 +0200 |
|---|---|---|
| committer | onestacked <chrisi.schrefl@gmail.com> | 2022-09-30 17:16:59 +0200 |
| commit | b73241aa5b0eab8aebf1600c598180bbd33be31c (patch) | |
| tree | a8ab003b577c19409da8077e8fdd4f061676a306 | |
| parent | f914b82a754c6d85c0a909ab152f5b611defef73 (diff) | |
| download | rust-b73241aa5b0eab8aebf1600c598180bbd33be31c.tar.gz rust-b73241aa5b0eab8aebf1600c598180bbd33be31c.zip | |
Added more const_closure functionality.
| -rw-r--r-- | library/core/src/cmp.rs | 4 | ||||
| -rw-r--r-- | library/core/src/const_closure.rs | 79 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/array_chunks.rs | 12 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/by_ref_sized.rs | 10 | ||||
| -rw-r--r-- | library/core/src/iter/adapters/mod.rs | 6 |
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 } } |
