Tue, 25 Oct 2022 23:05:40 +0300
Added NormExponent trait for exponents of norms
| 5 | 1 | /*! |
| 2 | Helper traits for working with tuples. | |
| 3 | */ | |
| 0 | 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 { | |
| 5 | 8 | /// First element of the tuple. |
| 0 | 9 | type Head; |
| 5 | 10 | /// Rest of the tuple. |
| 0 | 11 | type Tail; |
| 5 | 12 | |
| 13 | /// Nested 2-tuple conversioon of an n-tuple. | |
| 0 | 14 | type Nested; |
| 15 | ||
| 5 | 16 | /// Remove the first item from a tuple and return the rest. |
| 0 | 17 | fn tail(self) -> Self::Tail { self.split_tail().1 } |
| 5 | 18 | |
| 19 | /// Return the first element and the rest of the tuple | |
| 0 | 20 | fn split_tail(self) -> (Self::Head, Self::Tail); |
| 5 | 21 | |
| 22 | /// Convert `(a,b,c,…)` into `(a, (b, (c, …)))`. | |
| 0 | 23 | fn nest(self) -> Self::Nested; |
| 5 | 24 | |
| 25 | /// Convert `(a, (b, (c, …)))` into `(a,b,c,…)`. | |
| 0 | 26 | fn from_nested(nested : Self::Nested) -> Self; |
| 5 | 27 | |
| 28 | // Convert `head` and `tail` into `(head, tail…)`. | |
| 0 | 29 | fn from_head_tail(head : Self::Head, tail : Self::Tail) -> Self; |
| 30 | } | |
| 31 | ||
| 32 | macro_rules! nest { | |
| 33 | ($t1:ident) => { ($t1,) }; | |
| 34 | ($t1:ident $($ts:ident)+) => { ($t1, nest!($($ts)+)) }; | |
| 35 | } | |
| 36 | ||
| 37 | macro_rules! impl_tuple_ops { | |
| 38 | (@do $type1:ident $($types:ident)*, $var1:ident $($vars:ident)*) => { | |
| 39 | impl<$type1, $($types),*> TupleOps for ($type1, $($types),*) { | |
| 40 | type Head = $type1; | |
| 41 | type Tail = ($($types,)*); | |
| 42 | type Nested = nest!($type1 $($types)*); | |
| 43 | ||
| 44 | #[inline] | |
| 45 | fn split_tail(self) -> (Self::Head, Self::Tail) { | |
| 46 | let ($var1, $($vars),*) = self; | |
| 47 | ($var1, ($($vars,)*)) | |
| 48 | } | |
| 49 | ||
| 50 | #[inline] | |
| 51 | fn nest(self) -> Self::Nested { | |
| 52 | let ($var1, $($vars),*) = self; | |
| 53 | nest!($var1 $($vars)*) | |
| 54 | } | |
| 55 | ||
| 56 | #[inline] | |
| 57 | fn from_nested(nested : Self::Nested) -> Self { | |
| 58 | let nest!($var1 $($vars)*) = nested; | |
| 59 | ($var1, $($vars),*) | |
| 60 | } | |
| 61 | ||
| 62 | #[inline] | |
| 63 | fn from_head_tail($var1 : Self::Head, tail : Self::Tail) -> Self { | |
| 64 | let ($($vars,)*) = tail; | |
| 65 | ($var1, $($vars),*) | |
| 66 | } | |
| 67 | } | |
| 68 | }; | |
| 69 | ($type1:ident $($types:ident)+, $var1:ident $($vars:ident)+) => { | |
| 70 | impl_tuple_ops!(@do $type1 $($types)+, $var1 $($vars)+); | |
| 71 | impl_tuple_ops!($($types)+, $($vars)+); | |
| 72 | }; | |
| 73 | ($type1:ident, $var1:ident) => { | |
| 74 | impl_tuple_ops!(@do $type1, $var1); | |
| 75 | }; | |
| 76 | } | |
| 77 | ||
| 78 | 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, | |
| 79 | 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); | |
| 80 | ||
| 81 |