Skip to content

Commit 0b2f717

Browse files
committed
Added const_closure
1 parent bc4d574 commit 0b2f717

File tree

2 files changed

+180
-0
lines changed

2 files changed

+180
-0
lines changed

library/core/src/const_closure.rs

+178
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
use crate::marker::Destruct;
2+
3+
/// Struct representing a closure with owned data.
4+
///
5+
/// Example:
6+
/// ```rust
7+
/// use const_closure::ConstFnOnceClosure;
8+
/// const fn imp(state: i32, (arg,): (i32,)) -> i32 {
9+
/// state + arg
10+
/// }
11+
/// let i = 5;
12+
/// let cl = ConstFnOnceClosure::new(i, imp);
13+
///
14+
/// assert!(7 == cl(2));
15+
/// ```
16+
pub(crate) struct ConstFnOnceClosure<CapturedData, Function> {
17+
data: CapturedData,
18+
func: Function,
19+
}
20+
impl<CapturedData, Function> ConstFnOnceClosure<CapturedData, Function> {
21+
/// Function for creating a new closure.
22+
///
23+
/// `data` is the owned data that is captured from the environment (this data must be `~const Destruct`).
24+
///
25+
/// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
26+
/// and return the return value of the closure.
27+
#[allow(dead_code)]
28+
pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
29+
data: CapturedData,
30+
func: Function,
31+
) -> Self
32+
where
33+
CapturedData: ~const Destruct,
34+
Function: ~const Fn(CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
35+
{
36+
Self { data, func }
37+
}
38+
}
39+
impl<CapturedData, ClosureArguments, Function> const FnOnce<ClosureArguments>
40+
for ConstFnOnceClosure<CapturedData, Function>
41+
where
42+
CapturedData: ~const Destruct,
43+
Function: ~const Fn<(CapturedData, ClosureArguments)> + ~const Destruct,
44+
{
45+
type Output = Function::Output;
46+
47+
extern "rust-call" fn call_once(self, args: ClosureArguments) -> Self::Output {
48+
(self.func)(self.data, args)
49+
}
50+
}
51+
/// Struct representing a closure with mutably borrowed data.
52+
///
53+
/// Example:
54+
/// ```rust
55+
/// #![feature(const_mut_refs)]
56+
/// use const_closure::ConstFnMutClosure;
57+
/// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 {
58+
/// *state += arg;
59+
/// *state
60+
/// }
61+
/// let mut i = 5;
62+
/// let mut cl = ConstFnMutClosure::new(&mut i, imp);
63+
///
64+
/// assert!(7 == cl(2));
65+
/// assert!(8 == cl(1));
66+
/// ```
67+
pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> {
68+
data: &'a mut CapturedData,
69+
func: Function,
70+
}
71+
impl<'a, CapturedData: ?Sized, Function> ConstFnMutClosure<'a, CapturedData, Function> {
72+
/// Function for creating a new closure.
73+
///
74+
/// `data` is the a mutable borrow of data that is captured from the environment.
75+
///
76+
/// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
77+
/// and return the return value of the closure.
78+
pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
79+
data: &'a mut CapturedData,
80+
func: Function,
81+
) -> Self
82+
where
83+
Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
84+
{
85+
Self { data, func }
86+
}
87+
}
88+
impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
89+
FnOnce<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
90+
where
91+
Function:
92+
~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
93+
{
94+
type Output = ClosureReturnValue;
95+
96+
extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
97+
self.call_mut(args)
98+
}
99+
}
100+
impl<'a, CapturedData: ?Sized, ClosureArguments, Function, ClosureReturnValue> const
101+
FnMut<ClosureArguments> for ConstFnMutClosure<'a, CapturedData, Function>
102+
where
103+
Function: ~const Fn(&mut CapturedData, ClosureArguments) -> ClosureReturnValue,
104+
{
105+
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
106+
(self.func)(self.data, args)
107+
}
108+
}
109+
110+
/// Struct representing a closure with borrowed data.
111+
///
112+
/// Example:
113+
/// ```rust
114+
/// use const_closure::ConstFnClosure;
115+
///
116+
/// const fn imp(state: &i32, (arg,): (i32,)) -> i32 {
117+
/// *state + arg
118+
/// }
119+
/// let i = 5;
120+
/// let cl = ConstFnClosure::new(&i, imp);
121+
///
122+
/// assert!(7 == cl(2));
123+
/// assert!(6 == cl(1));
124+
/// ```
125+
pub(crate) struct ConstFnClosure<'a, CapturedData: ?Sized, Function> {
126+
data: &'a CapturedData,
127+
func: Function,
128+
}
129+
impl<'a, CapturedData: ?Sized, Function> ConstFnClosure<'a, CapturedData, Function> {
130+
/// Function for creating a new closure.
131+
///
132+
/// `data` is the a mutable borrow of data that is captured from the environment.
133+
///
134+
/// `func` is the function of the closure, it gets the data and a tuple of the arguments closure
135+
/// and return the return value of the closure.
136+
#[allow(dead_code)]
137+
pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
138+
data: &'a CapturedData,
139+
func: Function,
140+
) -> Self
141+
where
142+
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue,
143+
{
144+
Self { data, func }
145+
}
146+
}
147+
impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const
148+
FnOnce<ClosureArguments> for ConstFnClosure<'a, CapturedData, Function>
149+
where
150+
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
151+
{
152+
type Output = ClosureReturnValue;
153+
154+
extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
155+
self.call_mut(args)
156+
}
157+
}
158+
impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const
159+
FnMut<ClosureArguments> for ConstFnClosure<'a, CapturedData, Function>
160+
where
161+
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue,
162+
{
163+
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
164+
self.call(args)
165+
}
166+
}
167+
impl<
168+
'a,
169+
CapturedData: ?Sized,
170+
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue,
171+
ClosureArguments,
172+
ClosureReturnValue,
173+
> const Fn<ClosureArguments> for ConstFnClosure<'a, CapturedData, Function>
174+
{
175+
extern "rust-call" fn call(&self, args: ClosureArguments) -> Self::Output {
176+
(self.func)(self.data, args)
177+
}
178+
}

library/core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,8 @@ mod bool;
356356
mod tuple;
357357
mod unit;
358358

359+
mod const_closure;
360+
359361
#[stable(feature = "core_primitive", since = "1.43.0")]
360362
pub mod primitive;
361363

0 commit comments

Comments
 (0)