use core::marker::{Destruct, Tuple};
pub struct ConstClosure<CapturedData, Function> {
data: CapturedData,
func: Function,
}
impl<CapturedData: Tuple, Function> ConstClosure<CapturedData, Function> {
pub const fn new(data: CapturedData, func: Function) -> Self {
Self { data, func }
}
}
macro_rules! impl_const_closure {
($A:ident) => {
impl_const_closure!(@impl [
#[doc = "This trait is implemented for tuples up to twelve items long."]] $A);
};
($A:ident $B:ident) => {
impl_const_closure!($B);
impl_const_closure!(@impl [
#[doc = "This trait is implemented for tuples up to twelve items long."]] $A $B);
};
($T:ident $B:ident $($U:ident)+) => {
impl_const_closure!($B $($U)+);
impl_const_closure!(@impl
[#[doc(hidden)]] $T $B $( $U )+);
};
(@impl $([#[$meta:meta]])? $($var:ident)+) => {
$(#[$meta])?
impl<$($var,)+ ClosureArguments: Tuple, Function, ClosureReturnValue> const
FnOnce<ClosureArguments> for ConstClosure<($($var,)+), Function>
where
Function:
~const FnOnce(($($var,)+), ClosureArguments) -> ClosureReturnValue + ~const Destruct,
Self: ~const Destruct
{
type Output = ClosureReturnValue;
extern "rust-call" fn call_once(self, args: ClosureArguments) -> Self::Output {
(self.func)(self.data, args)
}
}
$(#[$meta])?
impl<'a, $($var,)+ ClosureArguments: Tuple, Function, ClosureReturnValue> const
FnMut<ClosureArguments> for ConstClosure<($(&'a mut $var,)+), Function>
where
Function:
~const FnMut(($(&mut $var,)+), ClosureArguments) -> ClosureReturnValue + ~const Destruct,
{
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
#[allow(non_snake_case)]
let ($($var,)*) = &mut self.data;
(self.func)(($($var,)*), args)
}
}
$(#[$meta])?
impl<'a, $($var,)+ ClosureArguments: Tuple, Function, ClosureReturnValue> const
FnMut<ClosureArguments> for ConstClosure<($(&'a $var,)+), Function>
where
Function:
~const FnMut(($(&$var,)+), ClosureArguments) -> ClosureReturnValue + ~const Destruct,
{
extern "rust-call" fn call_mut(&mut self, args: ClosureArguments) -> Self::Output {
(self.func)(self.data, args)
}
}
$(#[$meta])?
impl<'a, $($var,)+ ClosureArguments: Tuple, Function, ClosureReturnValue> const
Fn<ClosureArguments> for ConstClosure<($(&'a $var,)+), Function>
where
Function:
~const Fn(($(&$var,)+), ClosureArguments) -> ClosureReturnValue + ~const Destruct,
{
extern "rust-call" fn call(&self, args: ClosureArguments) -> Self::Output {
(self.func)(self.data, args)
}
}
};
}
impl_const_closure!(A B C D E F G H I J K L);