]> git.lizzy.rs Git - rust.git/blob - src/libcore/tuple.rs
Auto merge of #29256 - alexcrichton:less-flaky, r=brson
[rust.git] / src / libcore / tuple.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! A finite heterogeneous sequence, `(T, U, ..)`
12 //!
13 //! To access a single element of a tuple one can use the `.0`
14 //! field access syntax.
15 //!
16 //! Indexing starts from zero, so `.0` returns first value, `.1`
17 //! returns second value, and so on. In general, a tuple with *N*
18 //! elements has field accessors from 0 to *N* - 1.
19 //!
20 //! If every type inside a tuple implements one of the following
21 //! traits, then a tuple itself also implements it.
22 //!
23 //! * `Clone`
24 //! * `PartialEq`
25 //! * `Eq`
26 //! * `PartialOrd`
27 //! * `Ord`
28 //! * `Default`
29
30 #![stable(feature = "rust1", since = "1.0.0")]
31
32 use clone::Clone;
33 use cmp::*;
34 use cmp::Ordering::*;
35 use default::Default;
36 use option::Option;
37 use option::Option::Some;
38
39 // FIXME(#19630) Remove this work-around
40 macro_rules! e {
41     ($e:expr) => { $e }
42 }
43
44 // macro for implementing n-ary tuple functions and operations
45 macro_rules! tuple_impls {
46     ($(
47         $Tuple:ident {
48             $(($idx:tt) -> $T:ident)+
49         }
50     )+) => {
51         $(
52             #[stable(feature = "rust1", since = "1.0.0")]
53             impl<$($T:Clone),+> Clone for ($($T,)+) {
54                 fn clone(&self) -> ($($T,)+) {
55                     ($(e!(self.$idx.clone()),)+)
56                 }
57             }
58
59             #[stable(feature = "rust1", since = "1.0.0")]
60             impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
61                 #[inline]
62                 fn eq(&self, other: &($($T,)+)) -> bool {
63                     e!($(self.$idx == other.$idx)&&+)
64                 }
65                 #[inline]
66                 fn ne(&self, other: &($($T,)+)) -> bool {
67                     e!($(self.$idx != other.$idx)||+)
68                 }
69             }
70
71             #[stable(feature = "rust1", since = "1.0.0")]
72             impl<$($T:Eq),+> Eq for ($($T,)+) {}
73
74             #[stable(feature = "rust1", since = "1.0.0")]
75             impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
76                 #[inline]
77                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
78                     lexical_partial_cmp!($(self.$idx, other.$idx),+)
79                 }
80                 #[inline]
81                 fn lt(&self, other: &($($T,)+)) -> bool {
82                     lexical_ord!(lt, $(self.$idx, other.$idx),+)
83                 }
84                 #[inline]
85                 fn le(&self, other: &($($T,)+)) -> bool {
86                     lexical_ord!(le, $(self.$idx, other.$idx),+)
87                 }
88                 #[inline]
89                 fn ge(&self, other: &($($T,)+)) -> bool {
90                     lexical_ord!(ge, $(self.$idx, other.$idx),+)
91                 }
92                 #[inline]
93                 fn gt(&self, other: &($($T,)+)) -> bool {
94                     lexical_ord!(gt, $(self.$idx, other.$idx),+)
95                 }
96             }
97
98             #[stable(feature = "rust1", since = "1.0.0")]
99             impl<$($T:Ord),+> Ord for ($($T,)+) {
100                 #[inline]
101                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
102                     lexical_cmp!($(self.$idx, other.$idx),+)
103                 }
104             }
105
106             #[stable(feature = "rust1", since = "1.0.0")]
107             impl<$($T:Default),+> Default for ($($T,)+) {
108                 #[stable(feature = "rust1", since = "1.0.0")]
109                 #[inline]
110                 fn default() -> ($($T,)+) {
111                     ($({ let x: $T = Default::default(); x},)+)
112                 }
113             }
114         )+
115     }
116 }
117
118 // Constructs an expression that performs a lexical ordering using method $rel.
119 // The values are interleaved, so the macro invocation for
120 // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
121 // a3, b3)` (and similarly for `lexical_cmp`)
122 macro_rules! lexical_ord {
123     ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
124         if $a != $b { lexical_ord!($rel, $a, $b) }
125         else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
126     };
127     ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
128 }
129
130 macro_rules! lexical_partial_cmp {
131     ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
132         match ($a).partial_cmp(&$b) {
133             Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
134             ordering   => ordering
135         }
136     };
137     ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
138 }
139
140 macro_rules! lexical_cmp {
141     ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
142         match ($a).cmp(&$b) {
143             Equal => lexical_cmp!($($rest_a, $rest_b),+),
144             ordering   => ordering
145         }
146     };
147     ($a:expr, $b:expr) => { ($a).cmp(&$b) };
148 }
149
150 tuple_impls! {
151     Tuple1 {
152         (0) -> A
153     }
154     Tuple2 {
155         (0) -> A
156         (1) -> B
157     }
158     Tuple3 {
159         (0) -> A
160         (1) -> B
161         (2) -> C
162     }
163     Tuple4 {
164         (0) -> A
165         (1) -> B
166         (2) -> C
167         (3) -> D
168     }
169     Tuple5 {
170         (0) -> A
171         (1) -> B
172         (2) -> C
173         (3) -> D
174         (4) -> E
175     }
176     Tuple6 {
177         (0) -> A
178         (1) -> B
179         (2) -> C
180         (3) -> D
181         (4) -> E
182         (5) -> F
183     }
184     Tuple7 {
185         (0) -> A
186         (1) -> B
187         (2) -> C
188         (3) -> D
189         (4) -> E
190         (5) -> F
191         (6) -> G
192     }
193     Tuple8 {
194         (0) -> A
195         (1) -> B
196         (2) -> C
197         (3) -> D
198         (4) -> E
199         (5) -> F
200         (6) -> G
201         (7) -> H
202     }
203     Tuple9 {
204         (0) -> A
205         (1) -> B
206         (2) -> C
207         (3) -> D
208         (4) -> E
209         (5) -> F
210         (6) -> G
211         (7) -> H
212         (8) -> I
213     }
214     Tuple10 {
215         (0) -> A
216         (1) -> B
217         (2) -> C
218         (3) -> D
219         (4) -> E
220         (5) -> F
221         (6) -> G
222         (7) -> H
223         (8) -> I
224         (9) -> J
225     }
226     Tuple11 {
227         (0) -> A
228         (1) -> B
229         (2) -> C
230         (3) -> D
231         (4) -> E
232         (5) -> F
233         (6) -> G
234         (7) -> H
235         (8) -> I
236         (9) -> J
237         (10) -> K
238     }
239     Tuple12 {
240         (0) -> A
241         (1) -> B
242         (2) -> C
243         (3) -> D
244         (4) -> E
245         (5) -> F
246         (6) -> G
247         (7) -> H
248         (8) -> I
249         (9) -> J
250         (10) -> K
251         (11) -> L
252     }
253 }