(index<- )        ./libcore/num/int_macros.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-2014 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  #![macro_escape]
  12  #![doc(hidden)]
  13  
  14  macro_rules! int_module (($T:ty, $bits:expr) => (
  15  
  16  // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
  17  // calling the `mem::size_of` function.
  18  pub static BITS : uint = $bits;
  19  // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
  20  // calling the `mem::size_of` function.
  21  pub static BYTES : uint = ($bits / 8);
  22  
  23  // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
  24  // calling the `Bounded::min_value` function.
  25  pub static MIN: $T = (-1 as $T) << (BITS - 1);
  26  // FIXME(#9837): Compute MIN like this so the high bits that shouldn't exist are 0.
  27  // FIXME(#11621): Should be deprecated once CTFE is implemented in favour of
  28  // calling the `Bounded::max_value` function.
  29  pub static MAX: $T = !MIN;
  30  
  31  #[cfg(not(test))]
  32  impl Ord for $T {
  33      #[inline]
  34      fn lt(&self, other&$T) -> bool { *self < *other }
  35  }
  36  #[cfg(not(test))]
  37  impl TotalEq for $T {}
  38  #[cfg(not(test))]
  39  impl Eq for $T {
  40      #[inline]
  41      fn eq(&self, other&$T) -> bool { *self == *other }
  42  }
  43  #[cfg(not(test))]
  44  impl TotalOrd for $T {
  45      #[inline]
  46      fn cmp(&self, other&$T) -> Ordering {
  47          if *self < *other { Less }
  48          else if *self > *other { Greater }
  49          else { Equal }
  50      }
  51  }
  52  
  53  impl Num for $T {}
  54  
  55  impl Zero for $T {
  56      #[inline]
  57      fn zero() -> $T { 0 }
  58  
  59      #[inline]
  60      fn is_zero(&self) -> bool { *self == 0 }
  61  }
  62  
  63  impl One for $T {
  64      #[inline]
  65      fn one() -> $T { 1 }
  66  }
  67  
  68  #[cfg(not(test))]
  69  impl Add<$T,$T> for $T {
  70      #[inline]
  71      fn add(&self, other&$T) -> $T { *self + *other }
  72  }
  73  
  74  #[cfg(not(test))]
  75  impl Sub<$T,$T> for $T {
  76      #[inline]
  77      fn sub(&self, other&$T) -> $T { *self - *other }
  78  }
  79  
  80  #[cfg(not(test))]
  81  impl Mul<$T,$T> for $T {
  82      #[inline]
  83      fn mul(&self, other&$T) -> $T { *self * *other }
  84  }
  85  
  86  #[cfg(not(test))]
  87  impl Div<$T,$T> for $T {
  88      /// Integer division, truncated towards 0.
  89      ///
  90      /// # Examples
  91      ///
  92      /// ~~~
  93      /// assert!( 8 /  3 ==  2);
  94      /// assert!( 8 / -3 == -2);
  95      /// assert!(-8 /  3 == -2);
  96      /// assert!(-8 / -3 ==  2);
  97      ///
  98      /// assert!( 1 /  2 ==  0);
  99      /// assert!( 1 / -2 ==  0);
 100      /// assert!(-1 /  2 ==  0);
 101      /// assert!(-1 / -2 ==  0);
 102      /// ~~~
 103      #[inline]
 104      fn div(&self, other&$T) -> $T { *self / *other }
 105  }
 106  
 107  #[cfg(not(test))]
 108  impl Rem<$T,$T> for $T {
 109      /// Returns the integer remainder after division, satisfying:
 110      ///
 111      /// ~~~
 112      /// # let n = 1;
 113      /// # let d = 2;
 114      /// assert!((n / d) * d + (n % d) == n)
 115      /// ~~~
 116      ///
 117      /// # Examples
 118      ///
 119      /// ~~~
 120      /// assert!( 8 %  3 ==  2);
 121      /// assert!( 8 % -3 ==  2);
 122      /// assert!(-8 %  3 == -2);
 123      /// assert!(-8 % -3 == -2);
 124      ///
 125      /// assert!( 1 %  2 ==  1);
 126      /// assert!( 1 % -2 ==  1);
 127      /// assert!(-1 %  2 == -1);
 128      /// assert!(-1 % -2 == -1);
 129      /// ~~~
 130      #[inline]
 131      fn rem(&self, other&$T) -> $T { *self % *other }
 132  }
 133  
 134  #[cfg(not(test))]
 135  impl Neg<$T> for $T {
 136      #[inline]
 137      fn neg(&self) -> $T { -*self }
 138  }
 139  
 140  impl Signed for $T {
 141      /// Computes the absolute value
 142      #[inline]
 143      fn abs(&self) -> $T {
 144          if self.is_negative() { -*self } else { *self }
 145      }
 146  
 147      ///
 148      /// The positive difference of two numbers. Returns `0` if the number is less than or
 149      /// equal to `other`, otherwise the difference between`self` and `other` is returned.
 150      ///
 151      #[inline]
 152      fn abs_sub(&self, other&$T) -> $T {
 153          if *self <= *other { 0 } else { *self - *other }
 154      }
 155  
 156      ///
 157      /// # Returns
 158      ///
 159      /// - `0` if the number is zero
 160      /// - `1` if the number is positive
 161      /// - `-1` if the number is negative
 162      ///
 163      #[inline]
 164      fn signum(&self) -> $T {
 165          match *self {
 166              n if n > 0 =>  1,
 167              0          =>  0,
 168              _          => -1,
 169          }
 170      }
 171  
 172      /// Returns true if the number is positive
 173      #[inline]
 174      fn is_positive(&self) -> bool { *self > 0 }
 175  
 176      /// Returns true if the number is negative
 177      #[inline]
 178      fn is_negative(&self) -> bool { *self < 0 }
 179  }
 180  
 181  #[cfg(not(test))]
 182  impl BitOr<$T,$T> for $T {
 183      #[inline]
 184      fn bitor(&self, other&$T) -> $T { *self | *other }
 185  }
 186  
 187  #[cfg(not(test))]
 188  impl BitAnd<$T,$T> for $T {
 189      #[inline]
 190      fn bitand(&self, other&$T) -> $T { *self & *other }
 191  }
 192  
 193  #[cfg(not(test))]
 194  impl BitXor<$T,$T> for $T {
 195      #[inline]
 196      fn bitxor(&self, other&$T) -> $T { *self ^ *other }
 197  }
 198  
 199  #[cfg(not(test))]
 200  impl Shl<$T,$T> for $T {
 201      #[inline]
 202      fn shl(&self, other&$T) -> $T { *self << *other }
 203  }
 204  
 205  #[cfg(not(test))]
 206  impl Shr<$T,$T> for $T {
 207      #[inline]
 208      fn shr(&self, other&$T) -> $T { *self >> *other }
 209  }
 210  
 211  #[cfg(not(test))]
 212  impl Not<$T> for $T {
 213      #[inline]
 214      fn not(&self) -> $T { !*self }
 215  }
 216  
 217  impl Bounded for $T {
 218      #[inline]
 219      fn min_value() -> $T { MIN }
 220  
 221      #[inline]
 222      fn max_value() -> $T { MAX }
 223  }
 224  
 225  impl CheckedDiv for $T {
 226      #[inline]
 227      fn checked_div(&self, v&$T) -> Option<$T> {
 228          if *v == 0 || (*self == MIN && *v == -1) {
 229              None
 230          } else {
 231              Some(self / *v)
 232          }
 233      }
 234  }
 235  
 236  impl Default for $T {
 237      #[inline]
 238      fn default() -> $T { 0 }
 239  }
 240  
 241  impl Int for $T {}
 242  
 243  impl Primitive for $T {}
 244  
 245  #[cfg(test)]
 246  mod tests {
 247      use prelude::*;
 248      use super::*;
 249  
 250      use int;
 251      use num;
 252      use num::Bitwise;
 253      use num::CheckedDiv;
 254  
 255      #[test]
 256      fn test_overflows() {
 257          assert!(MAX > 0);
 258          assert!(MIN <= 0);
 259          assert!(MIN + MAX + 1 == 0);
 260      }
 261  
 262      #[test]
 263      fn test_num() {
 264          num::test_num(10 as $T, 2 as $T);
 265      }
 266  
 267      #[test]
 268      pub fn test_abs() {
 269          assert!((1 as $T).abs() == 1 as $T);
 270          assert!((0 as $T).abs() == 0 as $T);
 271          assert!((-1 as $T).abs() == 1 as $T);
 272      }
 273  
 274      #[test]
 275      fn test_abs_sub() {
 276          assert!((-1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
 277          assert!((1 as $T).abs_sub(&(1 as $T)) == 0 as $T);
 278          assert!((1 as $T).abs_sub(&(0 as $T)) == 1 as $T);
 279          assert!((1 as $T).abs_sub(&(-1 as $T)) == 2 as $T);
 280      }
 281  
 282      #[test]
 283      fn test_signum() {
 284          assert!((1 as $T).signum() == 1 as $T);
 285          assert!((0 as $T).signum() == 0 as $T);
 286          assert!((-0 as $T).signum() == 0 as $T);
 287          assert!((-1 as $T).signum() == -1 as $T);
 288      }
 289  
 290      #[test]
 291      fn test_is_positive() {
 292          assert!((1 as $T).is_positive());
 293          assert!(!(0 as $T).is_positive());
 294          assert!(!(-0 as $T).is_positive());
 295          assert!(!(-1 as $T).is_positive());
 296      }
 297  
 298      #[test]
 299      fn test_is_negative() {
 300          assert!(!(1 as $T).is_negative());
 301          assert!(!(0 as $T).is_negative());
 302          assert!(!(-0 as $T).is_negative());
 303          assert!((-1 as $T).is_negative());
 304      }
 305  
 306      #[test]
 307      fn test_bitwise() {
 308          assert!(0b1110 as $T == (0b1100 as $T).bitor(&(0b1010 as $T)));
 309          assert!(0b1000 as $T == (0b1100 as $T).bitand(&(0b1010 as $T)));
 310          assert!(0b0110 as $T == (0b1100 as $T).bitxor(&(0b1010 as $T)));
 311          assert!(0b1110 as $T == (0b0111 as $T).shl(&(1 as $T)));
 312          assert!(0b0111 as $T == (0b1110 as $T).shr(&(1 as $T)));
 313          assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not());
 314      }
 315  
 316      #[test]
 317      fn test_count_ones() {
 318          assert!((0b0101100 as $T).count_ones() == 3);
 319          assert!((0b0100001 as $T).count_ones() == 2);
 320          assert!((0b1111001 as $T).count_ones() == 5);
 321      }
 322  
 323      #[test]
 324      fn test_count_zeros() {
 325          assert!((0b0101100 as $T).count_zeros() == BITS as $T - 3);
 326          assert!((0b0100001 as $T).count_zeros() == BITS as $T - 2);
 327          assert!((0b1111001 as $T).count_zeros() == BITS as $T - 5);
 328      }
 329  
 330      #[test]
 331      fn test_signed_checked_div() {
 332          assert!(10i.checked_div(&2) == Some(5));
 333          assert!(5i.checked_div(&0) == None);
 334          assert!(int::MIN.checked_div(&-1) == None);
 335      }
 336  }
 337  
 338  ))