]> git.lizzy.rs Git - rust.git/blob - library/core/src/const_closure.rs
Rollup merge of #106202 - estebank:trim-paths, r=Nilstrieb
[rust.git] / library / core / src / const_closure.rs
1 use crate::marker::Destruct;
2 use crate::marker::Tuple;
3
4 /// Struct representing a closure with mutably borrowed data.
5 ///
6 /// Example:
7 /// ```no_build
8 /// #![feature(const_mut_refs)]
9 /// use crate::const_closure::ConstFnMutClosure;
10 /// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 {
11 ///   *state += arg;
12 ///   *state
13 /// }
14 /// let mut i = 5;
15 /// let mut cl = ConstFnMutClosure::new(&mut i, imp);
16 ///
17 /// assert!(7 == cl(2));
18 /// assert!(8 == cl(1));
19 /// ```
20 pub(crate) struct ConstFnMutClosure<CapturedData, Function> {
21     /// The Data captured by the Closure.
22     /// Must be either a (mutable) reference or a tuple of (mutable) references.
23     pub data: CapturedData,
24     /// The Function of the Closure, must be: Fn(CapturedData, ClosureArgs) -> ClosureReturn
25     pub func: Function,
26 }
27 impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<&'a mut CapturedData, Function> {
28     /// Function for creating a new closure.
29     ///
30     /// `data` is the a mutable borrow of data that is captured from the environment.
31     /// If you want Data to be a tuple of mutable Borrows, the struct must be constructed manually.
32     ///
33     /// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
34     ///   and return the return value of the closure.
35     pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
36         data: &'a mut CapturedData,
37         func: Function,
38     ) -> Self
39     where
40         Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
41     {
42         Self { data, func }
43     }
44 }
45
46 macro_rules! impl_fn_mut_tuple {
47     ($($var:ident)*) => {
48         #[allow(unused_parens)]
49         impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
50             FnOnce<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
51         where
52             Function: ~const Fn(($(&mut $var),*), ClosureArguments) -> ClosureReturnValue+ ~const Destruct,
53         {
54             type Output = ClosureReturnValue;
55
56             extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
57             self.call_mut(args)
58             }
59         }
60         #[allow(unused_parens)]
61         impl<'a, $($var,)* ClosureArguments: Tuple, Function, ClosureReturnValue> const
62             FnMut<ClosureArguments> for ConstFnMutClosure<($(&'a mut $var),*), Function>
63         where
64             Function: ~const Fn(($(&mut $var),*), ClosureArguments)-> ClosureReturnValue,
65         {
66             extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
67                 #[allow(non_snake_case)]
68                 let ($($var),*) = &mut self.data;
69                 (self.func)(($($var),*), args)
70             }
71         }
72     };
73 }
74 impl_fn_mut_tuple!(A);
75 impl_fn_mut_tuple!(A B);
76 impl_fn_mut_tuple!(A B C);
77 impl_fn_mut_tuple!(A B C D);
78 impl_fn_mut_tuple!(A B C D E);