(index<- ) ./libstd/tuple.rs
git branch: * master c7553ea auto merge of #13609 : richo/rust/str-type-vim, r=alexcrichton
modified: Sat Apr 19 11:22:39 2014
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 use str::StrSlice;
270
271 #[test]
272 fn test_clone() {
273 let a = (1, "2".to_owned());
274 let b = a.clone();
275 assert_eq!(a, b);
276 }
277
278 #[test]
279 fn test_getters() {
280 macro_rules! test_getter(
281 ($x:expr, $valN:ident, $refN:ident, $mutN:ident,
282 $init:expr, $incr:expr, $result:expr) => ({
283 assert_eq!($x.$valN(), $init);
284 assert_eq!(*$x.$refN(), $init);
285 *$x.$mutN() += $incr;
286 assert_eq!(*$x.$refN(), $result);
287 })
288 )
289 let mut x = (0u8, 1u16, 2u32, 3u64, 4u, 5i8, 6i16, 7i32, 8i64, 9i, 10f32, 11f64);
290 test_getter!(x, val0, ref0, mut0, 0, 1, 1);
291 test_getter!(x, val1, ref1, mut1, 1, 1, 2);
292 test_getter!(x, val2, ref2, mut2, 2, 1, 3);
293 test_getter!(x, val3, ref3, mut3, 3, 1, 4);
294 test_getter!(x, val4, ref4, mut4, 4, 1, 5);
295 test_getter!(x, val5, ref5, mut5, 5, 1, 6);
296 test_getter!(x, val6, ref6, mut6, 6, 1, 7);
297 test_getter!(x, val7, ref7, mut7, 7, 1, 8);
298 test_getter!(x, val8, ref8, mut8, 8, 1, 9);
299 test_getter!(x, val9, ref9, mut9, 9, 1, 10);
300 test_getter!(x, val10, ref10, mut10, 10.0, 1.0, 11.0);
301 test_getter!(x, val11, ref11, mut11, 11.0, 1.0, 12.0);
302 }
303
304 #[test]
305 fn test_tuple_cmp() {
306 let (small, big) = ((1u, 2u, 3u), (3u, 2u, 1u));
307
308 let nan = 0.0/0.0;
309
310 // Eq
311 assert_eq!(small, small);
312 assert_eq!(big, big);
313 assert!(small != big);
314 assert!(big != small);
315
316 // Ord
317 assert!(small < big);
318 assert!(!(small < small));
319 assert!(!(big < small));
320 assert!(!(big < big));
321
322 assert!(small <= small);
323 assert!(big <= big);
324
325 assert!(big > small);
326 assert!(small >= small);
327 assert!(big >= small);
328 assert!(big >= big);
329
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) >= (nan, 3.0)));
334 assert!(((1.0, 2.0) < (2.0, nan)));
335 assert!(!((2.0, 2.0) < (2.0, nan)));
336
337 // TotalOrd
338 assert!(small.cmp(&small) == Equal);
339 assert!(big.cmp(&big) == Equal);
340 assert!(small.cmp(&big) == Less);
341 assert!(big.cmp(&small) == Greater);
342 }
343
344 #[test]
345 fn test_show() {
346 assert_eq!(format!("{}", (1,)), "(1,)".to_owned());
347 assert_eq!(format!("{}", (1, true)), "(1, true)".to_owned());
348 assert_eq!(format!("{}", (1, "hi".to_owned(), true)), "(1, hi, true)".to_owned());
349 }
350 }