(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  }