@@ -16,15 +16,18 @@ use crate::marker::Destruct;
1616/// assert!(7 == cl(2));
1717/// assert!(8 == cl(1));
1818/// ```
19- pub ( crate ) struct ConstFnMutClosure < ' a , CapturedData : ?Sized , Function > {
20- data : & ' a mut CapturedData ,
21- func : Function ,
19+ pub ( crate ) struct ConstFnMutClosure < CapturedData , Function > {
20+ /// The Data captured by the Closure.
21+ /// Must be either a (mutable) reference or a tuple of (mutable) references.
22+ pub data : CapturedData ,
23+ /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn
24+ pub func : Function ,
2225}
23-
24- impl < ' a , CapturedData : ?Sized , Function > ConstFnMutClosure < ' a , CapturedData , Function > {
26+ impl < ' a , CapturedData : ?Sized , Function > ConstFnMutClosure < & ' a mut CapturedData , Function > {
2527 /// Function for creating a new closure.
2628 ///
2729 /// `data` is the a mutable borrow of data that is captured from the environment.
30+ /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually.
2831 ///
2932 /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
3033 /// and return the return value of the closure.
@@ -39,25 +42,36 @@ impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Fun
3942 }
4043}
4144
42- impl < ' a , CapturedData : ?Sized , ClosureArguments , Function , ClosureReturnValue > const
43- FnOnce < ClosureArguments > for ConstFnMutClosure < ' a , CapturedData , Function >
44- where
45- Function :
46- ~const Fn ( & mut CapturedData , ClosureArguments ) -> ClosureReturnValue + ~const Destruct ,
47- {
48- type Output = ClosureReturnValue ;
45+ macro_rules! impl_fn_mut_tuple {
46+ ( $( $var: ident) * ) => {
47+ #[ allow( unused_parens) ]
48+ impl <' a, $( $var, ) * ClosureArguments , Function , ClosureReturnValue > const
49+ FnOnce <ClosureArguments > for ConstFnMutClosure <( $( & ' a mut $var) ,* ) , Function >
50+ where
51+ Function : ~const Fn ( ( $( & mut $var) ,* ) , ClosureArguments ) -> ClosureReturnValue + ~const Destruct ,
52+ {
53+ type Output = ClosureReturnValue ;
4954
50- extern "rust-call" fn call_once ( mut self , args : ClosureArguments ) -> Self :: Output {
51- self . call_mut ( args)
52- }
53- }
54-
55- impl < ' a , CapturedData : ?Sized , ClosureArguments , Function , ClosureReturnValue > const
56- FnMut < ClosureArguments > for ConstFnMutClosure < ' a , CapturedData , Function >
57- where
58- Function : ~const Fn ( & mut CapturedData , ClosureArguments ) -> ClosureReturnValue ,
59- {
60- extern "rust-call" fn call_mut ( & mut self , args : ClosureArguments ) -> Self :: Output {
61- ( self . func ) ( self . data , args)
62- }
55+ extern "rust-call" fn call_once( mut self , args: ClosureArguments ) -> Self :: Output {
56+ self . call_mut( args)
57+ }
58+ }
59+ #[ allow( unused_parens) ]
60+ impl <' a, $( $var, ) * ClosureArguments , Function , ClosureReturnValue > const
61+ FnMut <ClosureArguments > for ConstFnMutClosure <( $( & ' a mut $var) ,* ) , Function >
62+ where
63+ Function : ~const Fn ( ( $( & mut $var) ,* ) , ClosureArguments ) -> ClosureReturnValue ,
64+ {
65+ extern "rust-call" fn call_mut( & mut self , args: ClosureArguments ) -> Self :: Output {
66+ #[ allow( non_snake_case) ]
67+ let ( $( $var) ,* ) = & mut self . data;
68+ ( self . func) ( ( $( $var) ,* ) , args)
69+ }
70+ }
71+ } ;
6372}
73+ impl_fn_mut_tuple ! ( A ) ;
74+ impl_fn_mut_tuple ! ( A B ) ;
75+ impl_fn_mut_tuple ! ( A B C ) ;
76+ impl_fn_mut_tuple ! ( A B C D ) ;
77+ impl_fn_mut_tuple ! ( A B C D E ) ;
0 commit comments