Sat, 22 Oct 2022 22:28:04 +0300
Convert iteration utilities to GATs
// // Tuple tools // /// A trait for removing the first item from a tuple and returning the rest. /// Only implemented for a few low dimensions. pub trait TupleOps : Sized { type Head; type Tail; type Nested; /// Remove the first item from a tuple and returning the rest. fn tail(self) -> Self::Tail { self.split_tail().1 } fn split_tail(self) -> (Self::Head, Self::Tail); fn nest(self) -> Self::Nested; fn from_nested(nested : Self::Nested) -> Self; fn from_head_tail(head : Self::Head, tail : Self::Tail) -> Self; } macro_rules! nest { ($t1:ident) => { ($t1,) }; ($t1:ident $($ts:ident)+) => { ($t1, nest!($($ts)+)) }; } macro_rules! impl_tuple_ops { (@do $type1:ident $($types:ident)*, $var1:ident $($vars:ident)*) => { impl<$type1, $($types),*> TupleOps for ($type1, $($types),*) { type Head = $type1; type Tail = ($($types,)*); type Nested = nest!($type1 $($types)*); #[inline] fn split_tail(self) -> (Self::Head, Self::Tail) { let ($var1, $($vars),*) = self; ($var1, ($($vars,)*)) } #[inline] fn nest(self) -> Self::Nested { let ($var1, $($vars),*) = self; nest!($var1 $($vars)*) } #[inline] fn from_nested(nested : Self::Nested) -> Self { let nest!($var1 $($vars)*) = nested; ($var1, $($vars),*) } #[inline] fn from_head_tail($var1 : Self::Head, tail : Self::Tail) -> Self { let ($($vars,)*) = tail; ($var1, $($vars),*) } } }; ($type1:ident $($types:ident)+, $var1:ident $($vars:ident)+) => { impl_tuple_ops!(@do $type1 $($types)+, $var1 $($vars)+); impl_tuple_ops!($($types)+, $($vars)+); }; ($type1:ident, $var1:ident) => { impl_tuple_ops!(@do $type1, $var1); }; } impl_tuple_ops!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z, a b c d e f g h i j k l m n o p q r s t u v w x y z);