all_tuples!() { /* proc-macro */ }
Expand description

Helper macro to generate tuple pyramids. Useful to generate scaffolding to work around Rust lacking variadics. Invoking all_tuples!(impl_foo, start, end, P, Q, ..) invokes impl_foo providing ident tuples through arity start..=end.

Examples

A single parameter.

use std::marker::PhantomData;
use bevy_utils_proc_macros::all_tuples;

struct Foo<T> {
    // ..
    _phantom: PhantomData<T>
}

trait WrappedInFoo {
    type Tup;
}

macro_rules! impl_wrapped_in_foo {
    ($($T:ident),*) => {
        impl<$($T),*> WrappedInFoo for ($($T,)*) {
            type Tup = ($(Foo<$T>,)*);
        }
    };
}

all_tuples!(impl_wrapped_in_foo, 0, 15, T);
// impl_wrapped_in_foo!();
// impl_wrapped_in_foo!(P0);
// impl_wrapped_in_foo!(P0, P1);
// ..
// impl_wrapped_in_foo!(P0 .. P14);

Multiple parameters.

use bevy_utils_proc_macros::all_tuples;

trait Append {
    type Out<Item>;
    fn append<Item>(tup: Self, item: Item) -> Self::Out<Item>;
}

impl Append for () {
    type Out<Item> = (Item,);
    fn append<Item>(_: Self, item: Item) -> Self::Out<Item> {
        (item,)
    }
}

macro_rules! impl_append {
    ($(($P:ident, $p:ident)),*) => {
        impl<$($P),*> Append for ($($P,)*) {
            type Out<Item> = ($($P),*, Item);
            fn append<Item>(($($p,)*): Self, item: Item) -> Self::Out<Item> {
                ($($p),*, item)
            }
        }
    }
}

all_tuples!(impl_append, 1, 15, P, p);
// impl_append!((P0, p0));
// impl_append!((P0, p0), (P1, p1));
// impl_append!((P0, p0), (P1, p1), (P2, p2));
// ..
// impl_append!((P0, p0) .. (P14, p14));