#![recursion_limit = "512"]
use paste::paste;
macro_rules! apply_args_reverse {
($macro_id:tt [] $($reversed:tt)*) => {
$macro_id!($($reversed) *);
};
($macro_id:tt [$first:tt $($rest:tt)*] $($reversed:tt)*) => {
apply_args_reverse!($macro_id [$($rest)*] $first $($reversed)*);
};
($macro_id:tt, $($t:tt)*) => {
apply_args_reverse!($macro_id [ $($t)* ]);
};
}
macro_rules! tuple_trait {
($i:literal) => {
paste! {
pub trait [<TupleMap$i>]<R, F> {
type Output;
fn [<map$i>](self, f: F) -> Self::Output;
}
}
};
($($trait_number:literal),*) => {
$(tuple_trait!($trait_number);)*
}
}
macro_rules! impl_traits_for_tuples {
($max_size:literal $($smaller_sizes:literal)*) => {
apply_args_reverse!(impl_traits_for_tuple, $max_size $($smaller_sizes)*);
impl_traits_for_tuples!($($smaller_sizes)*);
};
() => {}
}
macro_rules! impl_traits_for_tuple {
($zero:literal $($positive_nums:literal)*) => {
impl_traits_for_tuple!( | $zero $($positive_nums)*);
};
($($before:literal)* | $i:literal $($after:literal)*) => {
paste! {
impl<R, F, $([<T$before>],)* [<T$i>], $([<T$after>],)*>
[<TupleMap$i>]<R, F> for ($([<T$before>],)* [<T$i>], $([<T$after>],)*)
where
F: Fn([<T$i>]) -> R,
{
type Output = ($([<T$before>],)* R, $([<T$after>],)*);
fn [<map$i>](self, f: F) -> Self::Output {
($(self.$before,)* f(self.$i), $(self.$after,)*)
}
}
}
impl_traits_for_tuple!($($before)* $i | $($after)*);
};
($($implemented:literal)+ | ) => {};
}
macro_rules! do_all_for_trait {
($($all:literal),*) => {
tuple_trait!($($all),*);
apply_args_reverse!(impl_traits_for_tuples, $($all)*);
};
}
#[cfg(not(feature = "tuple16"))]
do_all_for_trait!(0, 1, 2, 3, 4, 5, 6, 7);
#[cfg(all(feature = "tuple16", not(feature = "tuple32"),))]
do_all_for_trait!(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
#[cfg(all(feature = "tuple32", not(feature = "tuple64"),))]
do_all_for_trait!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31
);
#[cfg(all(feature = "tuple64", not(feature = "tuple128"),))]
do_all_for_trait!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
);
#[cfg(feature = "tuple128")]
do_all_for_trait!(
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97,
98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127
);
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn tuples_to_8() {
let _tuple = (0, 1, 2, 3, 4, 5, 6, 7)
.map7(|val| val.to_string())
.map3(|val| val as u32)
.map2(|val| val as f64 * 3.5);
}
#[cfg(feature = "tuple16")]
#[test]
fn tuples_to_16() {
let _tuple = (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
.map7(|val| val.to_string())
.map3(|val| val as u32)
.map2(|val| val as f64 * 3.5)
.map8(|val| val.to_string())
.map15(|val| val as u32)
.map0(|val| val as f64 * 3.5);
}
#[cfg(feature = "tuple32")]
#[test]
fn tuples_to_32() {
let _tuple = (
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
)
.map7(|val| val.to_string())
.map3(|val| val as u32)
.map2(|val| val as f64 * 3.5)
.map8(|val| val.to_string())
.map15(|val| val as u32)
.map0(|val| val as f64 * 3.5)
.map16(|val| val.to_string())
.map29(|val| val as u32)
.map31(|val| val as f64 * 3.5);
}
#[cfg(feature = "tuple64")]
#[test]
fn tuples_to_64() {
let _tuple = (
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
)
.map7(|val| val.to_string())
.map3(|val| val as u32)
.map2(|val| val as f64 * 3.5)
.map8(|val| val.to_string())
.map15(|val| val as u32)
.map0(|val| val as f64 * 3.5)
.map16(|val| val.to_string())
.map29(|val| val as u32)
.map31(|val| val as f64 * 3.5)
.map32(|val| val.to_string())
.map45(|val| val as u32)
.map63(|val| val as f64 * 3.5);
}
#[cfg(feature = "tuple128")]
#[test]
fn tuples_to_128() {
let _tuple = (
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89,
90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108,
109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
126, 127,
)
.map7(|val| val.to_string())
.map3(|val| val as u32)
.map2(|val| val as f64 * 3.5)
.map8(|val| val.to_string())
.map15(|val| val as u32)
.map0(|val| val as f64 * 3.5)
.map16(|val| val.to_string())
.map29(|val| val as u32)
.map31(|val| val as f64 * 3.5)
.map32(|val| val.to_string())
.map45(|val| val as u32)
.map63(|val| val as f64 * 3.5)
.map89(|val| val.to_string())
.map110(|val| val as u32)
.map127(|val| val as f64 * 3.5);
}
}