]> git.lizzy.rs Git - rust.git/blob - library/core/src/tuple.rs
Auto merge of #94598 - scottmcm:prefix-free-hasher-methods, r=Amanieu
[rust.git] / library / core / src / tuple.rs
1 // See src/libstd/primitive_docs.rs for documentation.
2
3 use crate::cmp::Ordering::*;
4 use crate::cmp::*;
5
6 // Recursive macro for implementing n-ary tuple functions and operations
7 //
8 // Also provides implementations for tuples with lesser arity. For example, tuple_impls!(A B C)
9 // will implement everything for (A, B, C), (A, B) and (A,).
10 macro_rules! tuple_impls {
11     // Stopping criteria (1-ary tuple)
12     ($T:ident) => {
13         tuple_impls!(@impl $T);
14     };
15     // Running criteria (n-ary tuple, with n >= 2)
16     ($T:ident $( $U:ident )+) => {
17         tuple_impls!($( $U )+);
18         tuple_impls!(@impl $T $( $U )+);
19     };
20     // "Private" internal implementation
21     (@impl $( $T:ident )+) => {
22         #[stable(feature = "rust1", since = "1.0.0")]
23         impl<$($T:PartialEq),+> PartialEq for ($($T,)+)
24         where
25             last_type!($($T,)+): ?Sized
26         {
27             #[inline]
28             fn eq(&self, other: &($($T,)+)) -> bool {
29                 $( ${ignore(T)} self.${index()} == other.${index()} )&&+
30             }
31             #[inline]
32             fn ne(&self, other: &($($T,)+)) -> bool {
33                 $( ${ignore(T)} self.${index()} != other.${index()} )||+
34             }
35         }
36
37         #[stable(feature = "rust1", since = "1.0.0")]
38         impl<$($T:Eq),+> Eq for ($($T,)+)
39         where
40             last_type!($($T,)+): ?Sized
41         {}
42
43         #[stable(feature = "rust1", since = "1.0.0")]
44         impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+)
45         where
46             last_type!($($T,)+): ?Sized
47         {
48             #[inline]
49             fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
50                 lexical_partial_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+)
51             }
52             #[inline]
53             fn lt(&self, other: &($($T,)+)) -> bool {
54                 lexical_ord!(lt, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
55             }
56             #[inline]
57             fn le(&self, other: &($($T,)+)) -> bool {
58                 lexical_ord!(le, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
59             }
60             #[inline]
61             fn ge(&self, other: &($($T,)+)) -> bool {
62                 lexical_ord!(ge, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
63             }
64             #[inline]
65             fn gt(&self, other: &($($T,)+)) -> bool {
66                 lexical_ord!(gt, $( ${ignore(T)} self.${index()}, other.${index()} ),+)
67             }
68         }
69
70         #[stable(feature = "rust1", since = "1.0.0")]
71         impl<$($T:Ord),+> Ord for ($($T,)+)
72         where
73             last_type!($($T,)+): ?Sized
74         {
75             #[inline]
76             fn cmp(&self, other: &($($T,)+)) -> Ordering {
77                 lexical_cmp!($( ${ignore(T)} self.${index()}, other.${index()} ),+)
78             }
79         }
80
81         #[stable(feature = "rust1", since = "1.0.0")]
82         impl<$($T:Default),+> Default for ($($T,)+) {
83             #[inline]
84             fn default() -> ($($T,)+) {
85                 ($({ let x: $T = Default::default(); x},)+)
86             }
87         }
88     }
89 }
90
91 // Constructs an expression that performs a lexical ordering using method $rel.
92 // The values are interleaved, so the macro invocation for
93 // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
94 // a3, b3)` (and similarly for `lexical_cmp`)
95 macro_rules! lexical_ord {
96     ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
97         if $a != $b { lexical_ord!($rel, $a, $b) }
98         else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
99     };
100     ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
101 }
102
103 macro_rules! lexical_partial_cmp {
104     ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
105         match ($a).partial_cmp(&$b) {
106             Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
107             ordering   => ordering
108         }
109     };
110     ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
111 }
112
113 macro_rules! lexical_cmp {
114     ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
115         match ($a).cmp(&$b) {
116             Equal => lexical_cmp!($($rest_a, $rest_b),+),
117             ordering   => ordering
118         }
119     };
120     ($a:expr, $b:expr) => { ($a).cmp(&$b) };
121 }
122
123 macro_rules! last_type {
124     ($a:ident,) => { $a };
125     ($a:ident, $($rest_a:ident,)+) => { last_type!($($rest_a,)+) };
126 }
127
128 tuple_impls!(A B C D E F G H I J K L);