diff options
| author | onestacked <chrisi.schrefl@gmail.com> | 2022-09-23 13:42:31 +0200 |
|---|---|---|
| committer | onestacked <chrisi.schrefl@gmail.com> | 2022-09-23 13:42:31 +0200 |
| commit | 0b2f717dfaf4835aa644d925a12c93db8f15dd61 (patch) | |
| tree | 90c475a538129ca582c7e6bd74526fb2fdb253ff | |
| parent | bc4d574ff2ffcfe76db36116cc4f193384065985 (diff) | |
| download | rust-0b2f717dfaf4835aa644d925a12c93db8f15dd61.tar.gz rust-0b2f717dfaf4835aa644d925a12c93db8f15dd61.zip | |
Added const_closure
| -rw-r--r-- | library/core/src/const_closure.rs | 178 | ||||
| -rw-r--r-- | library/core/src/lib.rs | 2 |
2 files changed, 180 insertions, 0 deletions
diff --git a/library/core/src/const_closure.rs b/library/core/src/const_closure.rs new file mode 100644 index 00000000000..bd24c10bd00 --- /dev/null +++ b/library/core/src/const_closure.rs @@ -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) + } +} diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 21775c0a6ab..6fbe7ade732 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -356,6 +356,8 @@ mod bool; mod tuple; mod unit; +mod const_closure; + #[stable(feature = "core_primitive", since = "1.43.0")] pub mod primitive; |
