1 //! Implementation for `arr!` macro. 2 3 use super::ArrayLength; 4 use core::ops::Add; 5 use typenum::U1; 6 7 /// Helper trait for `arr!` macro 8 pub trait AddLength<T, N: ArrayLength<T>>: ArrayLength<T> { 9 /// Resulting length 10 type Output: ArrayLength<T>; 11 } 12 13 impl<T, N1, N2> AddLength<T, N2> for N1 14 where 15 N1: ArrayLength<T> + Add<N2>, 16 N2: ArrayLength<T>, 17 <N1 as Add<N2>>::Output: ArrayLength<T>, 18 { 19 type Output = <N1 as Add<N2>>::Output; 20 } 21 22 /// Helper type for `arr!` macro 23 pub type Inc<T, U> = <U as AddLength<T, U1>>::Output; 24 25 #[doc(hidden)] 26 #[macro_export] 27 macro_rules! arr_impl { 28 ($T:ty; $N:ty, [$($x:expr),*], []) => ({ 29 unsafe { $crate::transmute::<_, $crate::GenericArray<$T, $N>>([$($x),*]) } 30 }); 31 ($T:ty; $N:ty, [], [$x1:expr]) => ( 32 arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], []) 33 ); 34 ($T:ty; $N:ty, [], [$x1:expr, $($x:expr),+]) => ( 35 arr_impl!($T; $crate::arr::Inc<$T, $N>, [$x1 as $T], [$($x),+]) 36 ); 37 ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr]) => ( 38 arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], []) 39 ); 40 ($T:ty; $N:ty, [$($y:expr),+], [$x1:expr, $($x:expr),+]) => ( 41 arr_impl!($T; $crate::arr::Inc<$T, $N>, [$($y),+, $x1 as $T], [$($x),+]) 42 ); 43 } 44 45 /// Macro allowing for easy generation of Generic Arrays. 46 /// Example: `let test = arr![u32; 1, 2, 3];` 47 #[macro_export] 48 macro_rules! arr { 49 ($T:ty; $(,)*) => ({ 50 unsafe { $crate::transmute::<[$T; 0], $crate::GenericArray<$T, $crate::typenum::U0>>([]) } 51 }); 52 ($T:ty; $($x:expr),* $(,)*) => ( 53 arr_impl!($T; $crate::typenum::U0, [], [$($x),*]) 54 ); 55 ($($x:expr,)+) => (arr![$($x),*]); 56 () => ("""Macro requires a type, e.g. `let array = arr![u32; 1, 2, 3];`") 57 } 58