Macro specialize_call::specialize_call
source · macro_rules! specialize_call { (@single_mapping, ( $($acc_p:pat),* ), ( $($acc_t:ty),* ), $func:tt, $args:tt, $select:tt, [ ($p:pat => $($t:ty),+ ) $(, $p_t:tt)* $(,)* ], $mappings:tt ) => { ... }; (@single_mapping, $acc_p:tt, $acc_t: tt, $func:tt, $args:tt, $select:tt, [], $mappings:tt ) => { ... }; (@specialize_call, $acc_p:tt, $acc_t:tt, $func:tt, $args:tt, $select:tt, ($head:tt $(, $tail:tt)*) ) => { ... }; (@specialize_call, $acc_p:tt, $acc_t:tt, $func:tt, $args:tt, $select:tt, () ) => { ... }; (@maybe_invoke, ( $($acc_p:pat),* ), ( $($acc_t:ty),* ), $select:expr, $func:ident, ($($arg:expr),*) ) => { ... }; ($func:ident, ($($arg:expr),* $(,)*), $select:expr, $($mapping:tt),+ $(,)*) => { ... }; }
Expand description
A macro producing the invocations of the specified generic function with specific types, depending on the value available in runtime.
Examples:
struct A<const I: usize>();
struct B<const I: usize>();
struct C<const I: usize>();
#[derive(Debug)]
enum Select<const I: usize> {
A,
B,
C,
}
use core::any::type_name as tn;
#[test]
fn specialize_call_1() {
// there is a function `do_it` that takes one runtime argument, and one type-parameter.
fn do_it<T>(_arg: usize) -> &'static str {
tn::<T>()
}
assert_eq!(
specialize_call!(
// invoke `do_it::<?>`
do_it,
// use `(1)` as the arguments list
(1),
// choose the type-parameter depending on this value
Select::<1>::A,
// the choice map
[
// if the provided value is `Select::A`, then invoke `do_it::<A>`
(Select::<1>::A => A::<1>),
// if the provided value is `Select::B`, then invoke `do_it::<B>`
(Select::<1>::B => B::<1>),
]),
Some(tn::<A<1>>())
);
assert_eq!(
specialize_call!(do_it, (2), Select::<1>::B, [
(Select::<1>::A => A::<1>),
(Select::<1>::B => B::<1>),
]),
Some(tn::<B<1>>()),
);
assert_eq!(
specialize_call!(do_it, (3), Select::<1>::C, [
(Select::<1>::A => A::<1>),
(Select::<1>::B => B::<1>),
]),
None::<&str>,
);
}