about summary refs log tree commit diff
diff options
context:
space:
mode:
authoronestacked <chrisi.schrefl@gmail.com>2022-09-23 13:42:31 +0200
committeronestacked <chrisi.schrefl@gmail.com>2022-09-23 13:42:31 +0200
commit0b2f717dfaf4835aa644d925a12c93db8f15dd61 (patch)
tree90c475a538129ca582c7e6bd74526fb2fdb253ff
parentbc4d574ff2ffcfe76db36116cc4f193384065985 (diff)
downloadrust-0b2f717dfaf4835aa644d925a12c93db8f15dd61.tar.gz
rust-0b2f717dfaf4835aa644d925a12c93db8f15dd61.zip
Added const_closure
-rw-r--r--library/core/src/const_closure.rs178
-rw-r--r--library/core/src/lib.rs2
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;