(index<- )        ./libcore/tuple.rs

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