Sat, 22 Oct 2022 22:28:04 +0300
Convert iteration utilities to GATs
| 0 | 1 | // |
| 2 | // Tuple tools | |
| 3 | // | |
| 4 | ||
| 5 | /// A trait for removing the first item from a tuple and returning the rest. | |
| 6 | /// Only implemented for a few low dimensions. | |
| 7 | pub trait TupleOps : Sized { | |
| 8 | type Head; | |
| 9 | type Tail; | |
| 10 | type Nested; | |
| 11 | ||
| 12 | /// Remove the first item from a tuple and returning the rest. | |
| 13 | fn tail(self) -> Self::Tail { self.split_tail().1 } | |
| 14 | fn split_tail(self) -> (Self::Head, Self::Tail); | |
| 15 | fn nest(self) -> Self::Nested; | |
| 16 | fn from_nested(nested : Self::Nested) -> Self; | |
| 17 | fn from_head_tail(head : Self::Head, tail : Self::Tail) -> Self; | |
| 18 | } | |
| 19 | ||
| 20 | macro_rules! nest { | |
| 21 | ($t1:ident) => { ($t1,) }; | |
| 22 | ($t1:ident $($ts:ident)+) => { ($t1, nest!($($ts)+)) }; | |
| 23 | } | |
| 24 | ||
| 25 | macro_rules! impl_tuple_ops { | |
| 26 | (@do $type1:ident $($types:ident)*, $var1:ident $($vars:ident)*) => { | |
| 27 | impl<$type1, $($types),*> TupleOps for ($type1, $($types),*) { | |
| 28 | type Head = $type1; | |
| 29 | type Tail = ($($types,)*); | |
| 30 | type Nested = nest!($type1 $($types)*); | |
| 31 | ||
| 32 | #[inline] | |
| 33 | fn split_tail(self) -> (Self::Head, Self::Tail) { | |
| 34 | let ($var1, $($vars),*) = self; | |
| 35 | ($var1, ($($vars,)*)) | |
| 36 | } | |
| 37 | ||
| 38 | #[inline] | |
| 39 | fn nest(self) -> Self::Nested { | |
| 40 | let ($var1, $($vars),*) = self; | |
| 41 | nest!($var1 $($vars)*) | |
| 42 | } | |
| 43 | ||
| 44 | #[inline] | |
| 45 | fn from_nested(nested : Self::Nested) -> Self { | |
| 46 | let nest!($var1 $($vars)*) = nested; | |
| 47 | ($var1, $($vars),*) | |
| 48 | } | |
| 49 | ||
| 50 | #[inline] | |
| 51 | fn from_head_tail($var1 : Self::Head, tail : Self::Tail) -> Self { | |
| 52 | let ($($vars,)*) = tail; | |
| 53 | ($var1, $($vars),*) | |
| 54 | } | |
| 55 | } | |
| 56 | }; | |
| 57 | ($type1:ident $($types:ident)+, $var1:ident $($vars:ident)+) => { | |
| 58 | impl_tuple_ops!(@do $type1 $($types)+, $var1 $($vars)+); | |
| 59 | impl_tuple_ops!($($types)+, $($vars)+); | |
| 60 | }; | |
| 61 | ($type1:ident, $var1:ident) => { | |
| 62 | impl_tuple_ops!(@do $type1, $var1); | |
| 63 | }; | |
| 64 | } | |
| 65 | ||
| 66 | 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, | |
| 67 | 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); | |
| 68 | ||
| 69 |