]> git.lizzy.rs Git - rust.git/blob - src/libstd/tuple.rs
auto merge of #13600 : brandonw/rust/master, r=brson
[rust.git] / src / libstd / 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 //! Operations on tuples
12
13 #![allow(missing_doc)]
14
15 use clone::Clone;
16 #[cfg(not(test))] use cmp::*;
17 #[cfg(not(test))] use default::Default;
18 use fmt;
19 use result::{Ok, Err};
20
21 // macro for implementing n-ary tuple functions and operations
22 macro_rules! tuple_impls {
23     ($(
24         $Tuple:ident {
25             $(($valN:ident, $refN:ident, $mutN:ident) -> $T:ident {
26                 ($($x:ident),+) => $ret:expr
27             })+
28         }
29     )+) => {
30         $(
31             pub trait $Tuple<$($T),+> {
32                 $(fn $valN(self) -> $T;)+
33                 $(fn $refN<'a>(&'a self) -> &'a $T;)+
34                 $(fn $mutN<'a>(&'a mut self) -> &'a mut $T;)+
35             }
36
37             impl<$($T),+> $Tuple<$($T),+> for ($($T,)+) {
38                 $(
39                     #[inline]
40                     #[allow(unused_variable)]
41                     fn $valN(self) -> $T {
42                         let ($($x,)+) = self; $ret
43                     }
44
45                     #[inline]
46                     #[allow(unused_variable)]
47                     fn $refN<'a>(&'a self) -> &'a $T {
48                         let ($(ref $x,)+) = *self; $ret
49                     }
50
51                     #[inline]
52                     #[allow(unused_variable)]
53                     fn $mutN<'a>(&'a mut self) -> &'a mut $T {
54                         let ($(ref mut $x,)+) = *self; $ret
55                     }
56                 )+
57             }
58
59             impl<$($T:Clone),+> Clone for ($($T,)+) {
60                 fn clone(&self) -> ($($T,)+) {
61                     ($(self.$refN().clone(),)+)
62                 }
63             }
64
65             #[cfg(not(test))]
66             impl<$($T:Eq),+> Eq for ($($T,)+) {
67                 #[inline]
68                 fn eq(&self, other: &($($T,)+)) -> bool {
69                     $(*self.$refN() == *other.$refN())&&+
70                 }
71                 #[inline]
72                 fn ne(&self, other: &($($T,)+)) -> bool {
73                     $(*self.$refN() != *other.$refN())||+
74                 }
75             }
76
77             #[cfg(not(test))]
78             impl<$($T:TotalEq),+> TotalEq for ($($T,)+) {}
79
80             #[cfg(not(test))]
81             impl<$($T:Ord + Eq),+> Ord for ($($T,)+) {
82                 #[inline]
83                 fn lt(&self, other: &($($T,)+)) -> bool {
84                     lexical_ord!(lt, $(self.$refN(), other.$refN()),+)
85                 }
86                 #[inline]
87                 fn le(&self, other: &($($T,)+)) -> bool {
88                     lexical_ord!(le, $(self.$refN(), other.$refN()),+)
89                 }
90                 #[inline]
91                 fn ge(&self, other: &($($T,)+)) -> bool {
92                     lexical_ord!(ge, $(self.$refN(), other.$refN()),+)
93                 }
94                 #[inline]
95                 fn gt(&self, other: &($($T,)+)) -> bool {
96                     lexical_ord!(gt, $(self.$refN(), other.$refN()),+)
97                 }
98             }
99
100             #[cfg(not(test))]
101             impl<$($T:TotalOrd),+> TotalOrd for ($($T,)+) {
102                 #[inline]
103                 fn cmp(&self, other: &($($T,)+)) -> Ordering {
104                     lexical_cmp!($(self.$refN(), other.$refN()),+)
105                 }
106             }
107
108             #[cfg(not(test))]
109             impl<$($T:Default),+> Default for ($($T,)+) {
110                 #[inline]
111                 fn default() -> ($($T,)+) {
112                     ($({ let x: $T = Default::default(); x},)+)
113                 }
114             }
115
116             impl<$($T: fmt::Show),+> fmt::Show for ($($T,)+) {
117                 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
118                     write_tuple!(f.buf, $(self.$refN()),+)
119                 }
120             }
121         )+
122     }
123 }
124
125 // Constructs an expression that performs a lexical ordering using method $rel.
126 // The values are interleaved, so the macro invocation for
127 // `(a1, a2, a3) < (b1, b2, b3)` would be `lexical_ord!(lt, a1, b1, a2, b2,
128 // a3, b3)` (and similarly for `lexical_cmp`)
129 macro_rules! lexical_ord {
130     ($rel: ident, $a:expr, $b:expr, $($rest_a:expr, $rest_b:expr),+) => {
131         if *$a != *$b { lexical_ord!($rel, $a, $b) }
132         else { lexical_ord!($rel, $($rest_a, $rest_b),+) }
133     };
134     ($rel: ident, $a:expr, $b:expr) => { (*$a) . $rel ($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 macro_rules! write_tuple {
148     ($buf:expr, $x:expr) => (
149         write!($buf, "({},)", *$x)
150     );
151     ($buf:expr, $hd:expr, $($tl:expr),+) => ({
152         try!(write!($buf, "("));
153         try!(write!($buf, "{}", *$hd));
154         $(try!(write!($buf, ", {}", *$tl));)+
155         write!($buf, ")")
156     });
157 }
158
159 tuple_impls! {
160     Tuple1 {
161         (val0, ref0, mut0) -> A { (a) => a }
162     }
163     Tuple2 {
164         (val0, ref0, mut0) -> A { (a, b) => a }
165         (val1, ref1, mut1) -> B { (a, b) => b }
166     }
167     Tuple3 {
168         (val0, ref0, mut0) -> A { (a, b, c) => a }
169         (val1, ref1, mut1) -> B { (a, b, c) => b }
170         (val2, ref2, mut2) -> C { (a, b, c) => c }
171     }
172     Tuple4 {
173         (val0, ref0, mut0) -> A { (a, b, c, d) => a }
174         (val1, ref1, mut1) -> B { (a, b, c, d) => b }
175         (val2, ref2, mut2) -> C { (a, b, c, d) => c }
176         (val3, ref3, mut3) -> D { (a, b, c, d) => d }
177     }
178     Tuple5 {
179         (val0, ref0, mut0) -> A { (a, b, c, d, e) => a }
180         (val1, ref1, mut1) -> B { (a, b, c, d, e) => b }
181         (val2, ref2, mut2) -> C { (a, b, c, d, e) => c }
182         (val3, ref3, mut3) -> D { (a, b, c, d, e) => d }
183         (val4, ref4, mut4) -> E { (a, b, c, d, e) => e }
184     }
185     Tuple6 {
186         (val0, ref0, mut0) -> A { (a, b, c, d, e, f) => a }
187         (val1, ref1, mut1) -> B { (a, b, c, d, e, f) => b }
188         (val2, ref2, mut2) -> C { (a, b, c, d, e, f) => c }
189         (val3, ref3, mut3) -> D { (a, b, c, d, e, f) => d }
190         (val4, ref4, mut4) -> E { (a, b, c, d, e, f) => e }
191         (val5, ref5, mut5) -> F { (a, b, c, d, e, f) => f }
192     }
193     Tuple7 {
194         (val0, ref0, mut0) -> A { (a, b, c, d, e, f, g) => a }
195         (val1, ref1, mut1) -> B { (a, b, c, d, e, f, g) => b }
196         (val2, ref2, mut2) -> C { (a, b, c, d, e, f, g) => c }
197         (val3, ref3, mut3) -> D { (a, b, c, d, e, f, g) => d }
198         (val4, ref4, mut4) -> E { (a, b, c, d, e, f, g) => e }
199         (val5, ref5, mut5) -> F { (a, b, c, d, e, f, g) => f }
200         (val6, ref6, mut6) -> G { (a, b, c, d, e, f, g) => g }
201     }
202     Tuple8 {
203         (val0, ref0, mut0) -> A { (a, b, c, d, e, f, g, h) => a }
204         (val1, ref1, mut1) -> B { (a, b, c, d, e, f, g, h) => b }
205         (val2, ref2, mut2) -> C { (a, b, c, d, e, f, g, h) => c }
206         (val3, ref3, mut3) -> D { (a, b, c, d, e, f, g, h) => d }
207         (val4, ref4, mut4) -> E { (a, b, c, d, e, f, g, h) => e }
208         (val5, ref5, mut5) -> F { (a, b, c, d, e, f, g, h) => f }
209         (val6, ref6, mut6) -> G { (a, b, c, d, e, f, g, h) => g }
210         (val7, ref7, mut7) -> H { (a, b, c, d, e, f, g, h) => h }
211     }
212     Tuple9 {
213         (val0, ref0, mut0) -> A { (a, b, c, d, e, f, g, h, i) => a }
214         (val1, ref1, mut1) -> B { (a, b, c, d, e, f, g, h, i) => b }
215         (val2, ref2, mut2) -> C { (a, b, c, d, e, f, g, h, i) => c }
216         (val3, ref3, mut3) -> D { (a, b, c, d, e, f, g, h, i) => d }
217         (val4, ref4, mut4) -> E { (a, b, c, d, e, f, g, h, i) => e }
218         (val5, ref5, mut5) -> F { (a, b, c, d, e, f, g, h, i) => f }
219         (val6, ref6, mut6) -> G { (a, b, c, d, e, f, g, h, i) => g }
220         (val7, ref7, mut7) -> H { (a, b, c, d, e, f, g, h, i) => h }
221         (val8, ref8, mut8) -> I { (a, b, c, d, e, f, g, h, i) => i }
222     }
223     Tuple10 {
224         (val0, ref0, mut0) -> A { (a, b, c, d, e, f, g, h, i, j) => a }
225         (val1, ref1, mut1) -> B { (a, b, c, d, e, f, g, h, i, j) => b }
226         (val2, ref2, mut2) -> C { (a, b, c, d, e, f, g, h, i, j) => c }
227         (val3, ref3, mut3) -> D { (a, b, c, d, e, f, g, h, i, j) => d }
228         (val4, ref4, mut4) -> E { (a, b, c, d, e, f, g, h, i, j) => e }
229         (val5, ref5, mut5) -> F { (a, b, c, d, e, f, g, h, i, j) => f }
230         (val6, ref6, mut6) -> G { (a, b, c, d, e, f, g, h, i, j) => g }
231         (val7, ref7, mut7) -> H { (a, b, c, d, e, f, g, h, i, j) => h }
232         (val8, ref8, mut8) -> I { (a, b, c, d, e, f, g, h, i, j) => i }
233         (val9, ref9, mut9) -> J { (a, b, c, d, e, f, g, h, i, j) => j }
234     }
235     Tuple11 {
236         (val0,  ref0,  mut0)  -> A { (a, b, c, d, e, f, g, h, i, j, k) => a }
237         (val1,  ref1,  mut1)  -> B { (a, b, c, d, e, f, g, h, i, j, k) => b }
238         (val2,  ref2,  mut2)  -> C { (a, b, c, d, e, f, g, h, i, j, k) => c }
239         (val3,  ref3,  mut3)  -> D { (a, b, c, d, e, f, g, h, i, j, k) => d }
240         (val4,  ref4,  mut4)  -> E { (a, b, c, d, e, f, g, h, i, j, k) => e }
241         (val5,  ref5,  mut5)  -> F { (a, b, c, d, e, f, g, h, i, j, k) => f }
242         (val6,  ref6,  mut6)  -> G { (a, b, c, d, e, f, g, h, i, j, k) => g }
243         (val7,  ref7,  mut7)  -> H { (a, b, c, d, e, f, g, h, i, j, k) => h }
244         (val8,  ref8,  mut8)  -> I { (a, b, c, d, e, f, g, h, i, j, k) => i }
245         (val9,  ref9,  mut9)  -> J { (a, b, c, d, e, f, g, h, i, j, k) => j }
246         (val10, ref10, mut10) -> K { (a, b, c, d, e, f, g, h, i, j, k) => k }
247     }
248     Tuple12 {
249         (val0,  ref0,  mut0)  -> A { (a, b, c, d, e, f, g, h, i, j, k, l) => a }
250         (val1,  ref1,  mut1)  -> B { (a, b, c, d, e, f, g, h, i, j, k, l) => b }
251         (val2,  ref2,  mut2)  -> C { (a, b, c, d, e, f, g, h, i, j, k, l) => c }
252         (val3,  ref3,  mut3)  -> D { (a, b, c, d, e, f, g, h, i, j, k, l) => d }
253         (val4,  ref4,  mut4)  -> E { (a, b, c, d, e, f, g, h, i, j, k, l) => e }
254         (val5,  ref5,  mut5)  -> F { (a, b, c, d, e, f, g, h, i, j, k, l) => f }
255         (val6,  ref6,  mut6)  -> G { (a, b, c, d, e, f, g, h, i, j, k, l) => g }
256         (val7,  ref7,  mut7)  -> H { (a, b, c, d, e, f, g, h, i, j, k, l) => h }
257         (val8,  ref8,  mut8)  -> I { (a, b, c, d, e, f, g, h, i, j, k, l) => i }
258         (val9,  ref9,  mut9)  -> J { (a, b, c, d, e, f, g, h, i, j, k, l) => j }
259         (val10, ref10, mut10) -> K { (a, b, c, d, e, f, g, h, i, j, k, l) => k }
260         (val11, ref11, mut11) -> L { (a, b, c, d, e, f, g, h, i, j, k, l) => l }
261     }
262 }
263
264 #[cfg(test)]
265 mod tests {
266     use super::*;
267     use clone::Clone;
268     use cmp::*;
269
270     #[test]
271     fn test_clone() {
272         let a = (1, ~"2");
273         let b = a.clone();
274         assert_eq!(a, b);
275     }
276
277     #[test]
278     fn test_getters() {
279         macro_rules! test_getter(
280             ($x:expr, $valN:ident, $refN:ident, $mutN:ident,
281              $init:expr, $incr:expr, $result:expr) => ({
282                 assert_eq!($x.$valN(), $init);
283                 assert_eq!(*$x.$refN(), $init);
284                 *$x.$mutN() += $incr;
285                 assert_eq!(*$x.$refN(), $result);
286             })
287         )
288         let mut x = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64);
289         test_getter!(x, val0,  ref0,  mut0,  0,    1,   1);
290         test_getter!(x, val1,  ref1,  mut1,  1,    1,   2);
291         test_getter!(x, val2,  ref2,  mut2,  2,    1,   3);
292         test_getter!(x, val3,  ref3,  mut3,  3,    1,   4);
293         test_getter!(x, val4,  ref4,  mut4,  4,    1,   5);
294         test_getter!(x, val5,  ref5,  mut5,  5,    1,   6);
295         test_getter!(x, val6,  ref6,  mut6,  6,    1,   7);
296         test_getter!(x, val7,  ref7,  mut7,  7,    1,   8);
297         test_getter!(x, val8,  ref8,  mut8,  8,    1,   9);
298         test_getter!(x, val9,  ref9,  mut9,  9,    1,   10);
299         test_getter!(x, val10, ref10, mut10, 10.0, 1.0, 11.0);
300         test_getter!(x, val11, ref11, mut11, 11.0, 1.0, 12.0);
301     }
302
303     #[test]
304     fn test_tuple_cmp() {
305         let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
306
307         let nan = 0.0/0.0;
308
309         // Eq
310         assert_eq!(small, small);
311         assert_eq!(big, big);
312         assert!(small != big);
313         assert!(big != small);
314
315         // Ord
316         assert!(small < big);
317         assert!(!(small < small));
318         assert!(!(big < small));
319         assert!(!(big < big));
320
321         assert!(small <= small);
322         assert!(big <= big);
323
324         assert!(big > small);
325         assert!(small >= small);
326         assert!(big >= small);
327         assert!(big >= big);
328
329         assert!(!((1.0, 2.0) < (nan, 3.0)));
330         assert!(!((1.0, 2.0) <= (nan, 3.0)));
331         assert!(!((1.0, 2.0) > (nan, 3.0)));
332         assert!(!((1.0, 2.0) >= (nan, 3.0)));
333         assert!(((1.0, 2.0) < (2.0, nan)));
334         assert!(!((2.0, 2.0) < (2.0, nan)));
335
336         // TotalOrd
337         assert!(small.cmp(&small) == Equal);
338         assert!(big.cmp(&big) == Equal);
339         assert!(small.cmp(&big) == Less);
340         assert!(big.cmp(&small) == Greater);
341     }
342
343     #[test]
344     fn test_show() {
345         assert_eq!(format!("{}", (1,)), ~"(1,)");
346         assert_eq!(format!("{}", (1, true)), ~"(1, true)");
347         assert_eq!(format!("{}", (1, ~"hi", true)), ~"(1, hi, true)");
348     }
349 }