]> git.lizzy.rs Git - rust.git/blob - src/libcore/tuple.rs
Rollup merge of #31220 - steveklabnik:gh30632, r=nikomatsakis
[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 use clone::Clone;
31 use cmp::*;
32 use cmp::Ordering::*;
33 use default::Default;
34 use option::Option;
35 use option::Option::Some;
36
37 // FIXME(#19630) Remove this work-around
38 macro_rules! e {
39     ($e:expr) => { $e }
40 }
41
42 // macro for implementing n-ary tuple functions and operations
43 macro_rules! tuple_impls {
44     ($(
45         $Tuple:ident {
46             $(($idx:tt) -> $T:ident)+
47         }
48     )+) => {
49         $(
50             #[stable(feature = "rust1", since = "1.0.0")]
51             impl<$($T:Clone),+> Clone for ($($T,)+) {
52                 fn clone(&self) -> ($($T,)+) {
53                     ($(e!(self.$idx.clone()),)+)
54                 }
55             }
56
57             #[stable(feature = "rust1", since = "1.0.0")]
58             impl<$($T:PartialEq),+> PartialEq for ($($T,)+) {
59                 #[inline]
60                 fn eq(&self, other: &($($T,)+)) -> bool {
61                     e!($(self.$idx == other.$idx)&&+)
62                 }
63                 #[inline]
64                 fn ne(&self, other: &($($T,)+)) -> bool {
65                     e!($(self.$idx != other.$idx)||+)
66                 }
67             }
68
69             #[stable(feature = "rust1", since = "1.0.0")]
70             impl<$($T:Eq),+> Eq for ($($T,)+) {}
71
72             #[stable(feature = "rust1", since = "1.0.0")]
73             impl<$($T:PartialOrd + PartialEq),+> PartialOrd for ($($T,)+) {
74                 #[inline]
75                 fn partial_cmp(&self, other: &($($T,)+)) -> Option<Ordering> {
76                     lexical_partial_cmp!($(self.$idx, other.$idx),+)
77                 }
78                 #[inline]
79                 fn lt(&self, other: &($($T,)+)) -> bool {
80                     lexical_ord!(lt, $(self.$idx, other.$idx),+)
81                 }
82                 #[inline]
83                 fn le(&self, other: &($($T,)+)) -> bool {
84                     lexical_ord!(le, $(self.$idx, other.$idx),+)
85                 }
86                 #[inline]
87                 fn ge(&self, other: &($($T,)+)) -> bool {
88                     lexical_ord!(ge, $(self.$idx, other.$idx),+)
89                 }
90                 #[inline]
91                 fn gt(&self, other: &($($T,)+)) -> bool {
92                     lexical_ord!(gt, $(self.$idx, other.$idx),+)
93                 }
94             }
95
96             #[stable(feature = "rust1", since = "1.0.0")]
97             impl<$($T:Ord),+> Ord for ($($T,)+) {
98                 #[inline]
99                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
100                     lexical_cmp!($(self.$idx, other.$idx),+)
101                 }
102             }
103
104             #[stable(feature = "rust1", since = "1.0.0")]
105             impl<$($T:Default),+> Default for ($($T,)+) {
106                 #[inline]
107                 fn default() -> ($($T,)+) {
108                     ($({ let x: $T = Default::default(); x},)+)
109                 }
110             }
111         )+
112     }
113 }
114
115 // Constructs an expression that performs a lexical ordering using method $rel.
116 // The values are interleaved, so the macro invocation for
117 // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
118 // a3, b3)` (and similarly for `lexical_cmp`)
119 macro_rules! lexical_ord {
120     ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
121         if $a != $b { lexical_ord!($rel, $a, $b) }
122         else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
123     };
124     ($rel: ident, $a:expr, $b:expr) => { ($a) . $rel (& $b) };
125 }
126
127 macro_rules! lexical_partial_cmp {
128     ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
129         match ($a).partial_cmp(&$b) {
130             Some(Equal) => lexical_partial_cmp!($($rest_a, $rest_b),+),
131             ordering   => ordering
132         }
133     };
134     ($a:expr, $b:expr) => { ($a).partial_cmp(&$b) };
135 }
136
137 macro_rules! lexical_cmp {
138     ($a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
139         match ($a).cmp(&$b) {
140             Equal => lexical_cmp!($($rest_a, $rest_b),+),
141             ordering   => ordering
142         }
143     };
144     ($a:expr, $b:expr) => { ($a).cmp(&$b) };
145 }
146
147 tuple_impls! {
148     Tuple1 {
149         (0) -> A
150     }
151     Tuple2 {
152         (0) -> A
153         (1) -> B
154     }
155     Tuple3 {
156         (0) -> A
157         (1) -> B
158         (2) -> C
159     }
160     Tuple4 {
161         (0) -> A
162         (1) -> B
163         (2) -> C
164         (3) -> D
165     }
166     Tuple5 {
167         (0) -> A
168         (1) -> B
169         (2) -> C
170         (3) -> D
171         (4) -> E
172     }
173     Tuple6 {
174         (0) -> A
175         (1) -> B
176         (2) -> C
177         (3) -> D
178         (4) -> E
179         (5) -> F
180     }
181     Tuple7 {
182         (0) -> A
183         (1) -> B
184         (2) -> C
185         (3) -> D
186         (4) -> E
187         (5) -> F
188         (6) -> G
189     }
190     Tuple8 {
191         (0) -> A
192         (1) -> B
193         (2) -> C
194         (3) -> D
195         (4) -> E
196         (5) -> F
197         (6) -> G
198         (7) -> H
199     }
200     Tuple9 {
201         (0) -> A
202         (1) -> B
203         (2) -> C
204         (3) -> D
205         (4) -> E
206         (5) -> F
207         (6) -> G
208         (7) -> H
209         (8) -> I
210     }
211     Tuple10 {
212         (0) -> A
213         (1) -> B
214         (2) -> C
215         (3) -> D
216         (4) -> E
217         (5) -> F
218         (6) -> G
219         (7) -> H
220         (8) -> I
221         (9) -> J
222     }
223     Tuple11 {
224         (0) -> A
225         (1) -> B
226         (2) -> C
227         (3) -> D
228         (4) -> E
229         (5) -> F
230         (6) -> G
231         (7) -> H
232         (8) -> I
233         (9) -> J
234         (10) -> K
235     }
236     Tuple12 {
237         (0) -> A
238         (1) -> B
239         (2) -> C
240         (3) -> D
241         (4) -> E
242         (5) -> F
243         (6) -> G
244         (7) -> H
245         (8) -> I
246         (9) -> J
247         (10) -> K
248         (11) -> L
249     }
250 }