1 use crate::marker::Destruct;
3 use crate::marker::Tuple;
5 /// Struct representing a closure with mutably borrowed data.
9 /// #![feature(const_mut_refs)]
10 /// use crate::const_closure::ConstFnMutClosure;
11 /// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 {
16 /// let mut cl = ConstFnMutClosure::new(&mut i, imp);
18 /// assert!(7 == cl(2));
19 /// assert!(8 == cl(1));
21 pub(crate) struct ConstFnMutClosure<CapturedData, Function> {
22 /// The Data captured by the Closure.
23 /// Must be either a (mutable) reference or a tuple of (mutable) references.
24 pub data: CapturedData,
25 /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn
28 impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> {
29 /// Function for creating a new closure.
31 /// `data` is the a mutable borrow of data that is captured from the environment.
32 /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually.
34 /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
35 /// and return the return value of the closure.
36 pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
37 data: &'a mut CapturedData,
41 Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
47 macro_rules! impl_fn_mut_tuple {
50 #[allow(unused_parens)]
51 impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
52 FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
54 Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
56 type Output = ClosureReturnValue;
58 extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
63 #[allow(unused_parens)]
64 impl<'a, $($var,)* ClosureArguments, Function, ClosureReturnValue> const
65 FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
67 Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
69 extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
70 #[allow(non_snake_case)]
71 let ($($var),*) = &mut self.data;
72 (self.func)(($($var),*), args)
75 #[cfg(not(bootstrap))]
76 #[allow(unused_parens)]
77 impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
78 FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
80 Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
82 type Output = ClosureReturnValue;
84 extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
88 #[cfg(not(bootstrap))]
89 #[allow(unused_parens)]
90 impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
91 FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
93 Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
95 extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
96 #[allow(non_snake_case)]
97 let ($($var),*) = &mut self.data;
98 (self.func)(($($var),*), args)
103 impl_fn_mut_tuple!(A);
104 impl_fn_mut_tuple!(A B);
105 impl_fn_mut_tuple!(A B C);
106 impl_fn_mut_tuple!(A B C D);
107 impl_fn_mut_tuple!(A B C D E);