Skip to content

Commit

Permalink
Added const_closure
Browse files Browse the repository at this point in the history
  • Loading branch information
onestacked committed Sep 23, 2022
1 parent bc4d574 commit 0b2f717
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 0 deletions.
178 changes: 178 additions & 0 deletions library/core/src/const_closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
use crate::marker::Destruct;

/// Struct representing a closure with owned data.
///
/// Example:
/// ```rust
/// use const_closure::ConstFnOnceClosure;
/// const fn imp(state: i32, (arg,): (i32,)) -> i32 {
/// state + arg
/// }
/// let i = 5;
/// let cl = ConstFnOnceClosure::new(i, imp);
///
/// assert!(7 == cl(2));
/// ```
pub(crate) struct ConstFnOnceClosure<CapturedData, Function> {
data: CapturedData,
func: Function,
}
impl<CapturedData, Function> ConstFnOnceClosure<CapturedData, Function> {
/// Function for creating a new closure.
///
/// `data` is the owned data that is captured from the environment (this data must be `~const Destruct`).
///
/// `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.
#[allow(dead_code)]
pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
data: CapturedData,
func: Function,
) -> Self
where
CapturedData: ~const Destruct,
Function: ~const Fn(CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
{
Self { data, func }
}
}
impl<CapturedData, ClosureArguments, Function> const FnOnce<ClosureArguments>
for ConstFnOnceClosure<CapturedData, Function>
where
CapturedData: ~const Destruct,
Function: ~const Fn<(CapturedData, ClosureArguments)> + ~const Destruct,
{
type Output = Function::Output;

extern "rust-call" fn call_once(self, args: ClosureArguments) -> Self::Output {
(self.func)(self.data, args)
}
}
/// Struct representing a closure with mutably borrowed data.
///
/// Example:
/// ```rust
/// #![feature(const_mut_refs)]
/// use const_closure::ConstFnMutClosure;
/// const fn imp(state: &mut i32, (arg,): (i32,)) -> i32 {
/// *state += arg;
/// *state
/// }
/// let mut i = 5;
/// let mut cl = ConstFnMutClosure::new(&mut i, imp);
///
/// assert!(7 == cl(2));
/// assert!(8 == cl(1));
/// ```
pub(crate) struct ConstFnMutClosure<'a, CapturedData: ?Sized, Function> {
data: &'a mut CapturedData,
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;

extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
self.call_mut(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)
}
}

/// Struct representing a closure with borrowed data.
///
/// Example:
/// ```rust
/// use const_closure::ConstFnClosure;
///
/// const fn imp(state: &i32, (arg,): (i32,)) -> i32 {
/// *state + arg
/// }
/// let i = 5;
/// let cl = ConstFnClosure::new(&i, imp);
///
/// assert!(7 == cl(2));
/// assert!(6 == cl(1));
/// ```
pub(crate) struct ConstFnClosure<'a, CapturedData: ?Sized, Function> {
data: &'a CapturedData,
func: Function,
}
impl<'a, CapturedData: ?Sized, Function> ConstFnClosure<'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.
#[allow(dead_code)]
pub(crate) const fn new<ClosureArguments, ClosureReturnValue>(
data: &'a CapturedData,
func: Function,
) -> Self
where
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue,
{
Self { data, func }
}
}
impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const
FnOnce<ClosureArguments> for ConstFnClosure<'a, CapturedData, Function>
where
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue + ~const Destruct,
{
type Output = ClosureReturnValue;

extern "rust-call" fn call_once(mut self, args: ClosureArguments) -> Self::Output {
self.call_mut(args)
}
}
impl<'a, CapturedData: ?Sized, Function, ClosureArguments, ClosureReturnValue> const
FnMut<ClosureArguments> for ConstFnClosure<'a, CapturedData, Function>
where
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue,
{
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
self.call(args)
}
}
impl<
'a,
CapturedData: ?Sized,
Function: ~const Fn(&CapturedData, ClosureArguments) -> ClosureReturnValue,
ClosureArguments,
ClosureReturnValue,
> const Fn<ClosureArguments> for ConstFnClosure<'a, CapturedData, Function>
{
extern "rust-call" fn call(&self, args: ClosureArguments) -> Self::Output {
(self.func)(self.data, args)
}
}
2 changes: 2 additions & 0 deletions library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,8 @@ mod bool;
mod tuple;
mod unit;

mod const_closure;

#[stable(feature = "core_primitive", since = "1.43.0")]
pub mod primitive;

Expand Down

0 comments on commit 0b2f717

Please sign in to comment.