macro_rules! impl_function_common_methods {
($name:ident<$t:ident, $r:ident>, (Fn(&$arg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@one Function, $t, $r, shared, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $r:ident>, (Fn(&mut $arg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@one MutatingFunction, $t, $r, shared_mut, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $r:ident>, (FnMut(&$arg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@one StatefulFunction, $t, $r, stateful, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $r:ident>, (FnMut(&mut $arg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@one StatefulMutatingFunction, $t, $r, stateful_mut, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $r:ident>, (FnOnce(&$arg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@one FunctionOnce, $t, $r, shared, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $r:ident>, (FnOnce(&mut $arg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@one MutatingFunctionOnce, $t, $r, shared_mut, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $u:ident, $r:ident>, (Fn(&$a:ident, &$barg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@two BiFunction, $t, $u, $r, shared, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $u:ident, $r:ident>, (Fn(&mut $a:ident, &mut $barg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@two BiMutatingFunction, $t, $u, $r, shared_mut, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $u:ident, $r:ident>, (FnOnce(&$a:ident, &$barg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@two BiFunctionOnce, $t, $u, $r, shared, ($($b)+), |$f| $w); };
($name:ident<$t:ident, $u:ident, $r:ident>, (FnOnce(&mut $a:ident, &mut $barg:ident) -> $out:ident + $($b:tt)+), |$f:ident| $w:expr) => { $crate::functions::macros::impl_function_common_methods!(@two BiMutatingFunctionOnce, $t, $u, $r, shared_mut, ($($b)+), |$f| $w); };
(@one $tr:ident, $t:ident, $r:ident, shared, ($($b:tt)+), |$f:ident| $w:expr) => { crate::macros::impl_common_new_methods!(semantic ($tr<$t, $r> + $($b)+), |source| move |value: &$t| source.apply(value), |$f| $w, "function"); crate::macros::impl_common_name_methods!("function"); };
(@one $tr:ident, $t:ident, $r:ident, shared_mut, ($($b:tt)+), |$f:ident| $w:expr) => { crate::macros::impl_common_new_methods!(semantic ($tr<$t, $r> + $($b)+), |source| move |value: &mut $t| source.apply(value), |$f| $w, "function"); crate::macros::impl_common_name_methods!("function"); };
(@one $tr:ident, $t:ident, $r:ident, stateful, ($($b:tt)+), |$f:ident| $w:expr) => { crate::macros::impl_common_new_methods!(semantic_mut ($tr<$t, $r> + $($b)+), |source| move |value: &$t| source.apply(value), |$f| $w, "function"); crate::macros::impl_common_name_methods!("function"); };
(@one $tr:ident, $t:ident, $r:ident, stateful_mut, ($($b:tt)+), |$f:ident| $w:expr) => { crate::macros::impl_common_new_methods!(semantic_mut ($tr<$t, $r> + $($b)+), |source| move |value: &mut $t| source.apply(value), |$f| $w, "function"); crate::macros::impl_common_name_methods!("function"); };
(@two $tr:ident, $t:ident, $u:ident, $r:ident, shared, ($($b:tt)+), |$f:ident| $w:expr) => { crate::macros::impl_common_new_methods!(semantic ($tr<$t, $u, $r> + $($b)+), |source| move |first: &$t, second: &$u| source.apply(first, second), |$f| $w, "bi-function"); crate::macros::impl_common_name_methods!("bi-function"); };
(@two $tr:ident, $t:ident, $u:ident, $r:ident, shared_mut, ($($b:tt)+), |$f:ident| $w:expr) => { crate::macros::impl_common_new_methods!(semantic ($tr<$t, $u, $r> + $($b)+), |source| move |first: &mut $t, second: &mut $u| source.apply(first, second), |$f| $w, "bi-function"); crate::macros::impl_common_name_methods!("bi-function"); };
}
pub(crate) use impl_function_common_methods;
macro_rules! impl_function_new_callback {
($_trait:ident, BoxMutatingFunction, $t:ident, |$v:ident| $body:block) => {
BoxMutatingFunction::new(move |$v: &mut $t| $body)
};
($_trait:ident, RcMutatingFunction, $t:ident, |$v:ident| $body:block) => {
RcMutatingFunction::new(move |$v: &mut $t| $body)
};
($_trait:ident, ArcMutatingFunction, $t:ident, |$v:ident| $body:block) => {
ArcMutatingFunction::new(move |$v: &mut $t| $body)
};
($_trait:ident, BoxStatefulMutatingFunction, $t:ident, |$v:ident| $body:block) => {
BoxStatefulMutatingFunction::new(move |$v: &mut $t| $body)
};
($_trait:ident, RcStatefulMutatingFunction, $t:ident, |$v:ident| $body:block) => {
RcStatefulMutatingFunction::new(move |$v: &mut $t| $body)
};
($_trait:ident, ArcStatefulMutatingFunction, $t:ident, |$v:ident| $body:block) => {
ArcStatefulMutatingFunction::new(move |$v: &mut $t| $body)
};
($_trait:ident, BoxMutatingFunctionOnce, $t:ident, |$v:ident| $body:block) => {
BoxMutatingFunctionOnce::new(move |$v: &mut $t| $body)
};
($_trait:ident, BoxBiFunction, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
BoxBiFunction::new(move |$a: &$t, $b: &$u| $body)
};
($_trait:ident, RcBiFunction, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
RcBiFunction::new(move |$a: &$t, $b: &$u| $body)
};
($_trait:ident, ArcBiFunction, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
ArcBiFunction::new(move |$a: &$t, $b: &$u| $body)
};
($_trait:ident, BoxBiFunctionOnce, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
BoxBiFunctionOnce::new(move |$a: &$t, $b: &$u| $body)
};
($_trait:ident, BoxBiMutatingFunction, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
BoxBiMutatingFunction::new(move |$a: &mut $t, $b: &mut $u| $body)
};
($_trait:ident, RcBiMutatingFunction, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
RcBiMutatingFunction::new(move |$a: &mut $t, $b: &mut $u| $body)
};
($_trait:ident, ArcBiMutatingFunction, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
ArcBiMutatingFunction::new(move |$a: &mut $t, $b: &mut $u| $body)
};
($_trait:ident, BoxBiMutatingFunctionOnce, $t:ident, $u:ident, |$a:ident, $b:ident| $body:block) => {
BoxBiMutatingFunctionOnce::new(move |$a: &mut $t, $b: &mut $u| $body)
};
(Function, $wrapper:ident, $t:ident, |$value:ident| $body:block) => {
$wrapper::new(move |$value: &$t| $body)
};
(StatefulFunction, $wrapper:ident, $t:ident, |$value:ident| $body:block) => {
$wrapper::new(move |$value: &$t| $body)
};
(FunctionOnce, $wrapper:ident, $t:ident, |$value:ident| $body:block) => {
$wrapper::new(move |$value: &$t| $body)
};
(MutatingFunction, $wrapper:ident, $t:ident, |$value:ident| $body:block) => {
$wrapper::new(move |$value: &mut $t| $body)
};
(StatefulMutatingFunction, $wrapper:ident, $t:ident, |$value:ident| $body:block) => {
$wrapper::new(move |$value: &mut $t| $body)
};
(MutatingFunctionOnce, $wrapper:ident, $t:ident, |$value:ident| $body:block) => {
$wrapper::new(move |$value: &mut $t| $body)
};
(BiFunction, $wrapper:ident, $t:ident, $u:ident, |$first:ident, $second:ident| $body:block) => {
$wrapper::new(move |$first: &$t, $second: &$u| $body)
};
(BiFunctionOnce, $wrapper:ident, $t:ident, $u:ident, |$first:ident, $second:ident| $body:block) => {
$wrapper::new(move |$first: &$t, $second: &$u| $body)
};
(BiMutatingFunction, $wrapper:ident, $t:ident, $u:ident, |$first:ident, $second:ident| $body:block) => {
$wrapper::new(move |$first: &mut $t, $second: &mut $u| $body)
};
(BiMutatingFunctionOnce, $wrapper:ident, $t:ident, $u:ident, |$first:ident, $second:ident| $body:block) => {
$wrapper::new(move |$first: &mut $t, $second: &mut $u| $body)
};
}
pub(crate) use impl_function_new_callback;