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 |