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.
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.
14 macro_rules! int_module (($T:ty, $bits:expr) => (
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);
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;
31 impl CheckedDiv for $T {
33 fn checked_div(&self, v: &$T) -> Option<$T> {
34 if *v == 0 || (*self == MIN && *v == -1) {
47 fn lt(&self, other: &$T) -> bool { return (*self) < (*other); }
53 fn eq(&self, other: &$T) -> bool { return (*self) == (*other); }
58 fn default() -> $T { 0 }
66 fn is_zero(&self) -> bool { *self == 0 }
75 impl Add<$T,$T> for $T {
77 fn add(&self, other: &$T) -> $T { *self + *other }
81 impl Sub<$T,$T> for $T {
83 fn sub(&self, other: &$T) -> $T { *self - *other }
87 impl Mul<$T,$T> for $T {
89 fn mul(&self, other: &$T) -> $T { *self * *other }
93 impl Div<$T,$T> for $T {
94 /// Integer division, truncated towards 0.
99 /// assert!( 8 / 3 == 2);
100 /// assert!( 8 / -3 == -2);
101 /// assert!(-8 / 3 == -2);
102 /// assert!(-8 / -3 == 2);
104 /// assert!( 1 / 2 == 0);
105 /// assert!( 1 / -2 == 0);
106 /// assert!(-1 / 2 == 0);
107 /// assert!(-1 / -2 == 0);
110 fn div(&self, other: &$T) -> $T { *self / *other }
114 impl Rem<$T,$T> for $T {
115 /// Returns the integer remainder after division, satisfying:
120 /// assert!((n / d) * d + (n % d) == n)
126 /// assert!( 8 % 3 == 2);
127 /// assert!( 8 % -3 == 2);
128 /// assert!(-8 % 3 == -2);
129 /// assert!(-8 % -3 == -2);
131 /// assert!( 1 % 2 == 1);
132 /// assert!( 1 % -2 == 1);
133 /// assert!(-1 % 2 == -1);
134 /// assert!(-1 % -2 == -1);
137 fn rem(&self, other: &$T) -> $T { *self % *other }
141 impl Neg<$T> for $T {
143 fn neg(&self) -> $T { -*self }
147 /// Computes the absolute value
149 fn abs(&self) -> $T {
150 if self.is_negative() { -*self } else { *self }
154 /// The positive difference of two numbers. Returns `0` if the number is less than or
155 /// equal to `other`, otherwise the difference between`self` and `other` is returned.
158 fn abs_sub(&self, other: &$T) -> $T {
159 if *self <= *other { 0 } else { *self - *other }
165 /// - `0` if the number is zero
166 /// - `1` if the number is positive
167 /// - `-1` if the number is negative
170 fn signum(&self) -> $T {
178 /// Returns true if the number is positive
180 fn is_positive(&self) -> bool { *self > 0 }
182 /// Returns true if the number is negative
184 fn is_negative(&self) -> bool { *self < 0 }
188 impl BitOr<$T,$T> for $T {
190 fn bitor(&self, other: &$T) -> $T { *self | *other }
194 impl BitAnd<$T,$T> for $T {
196 fn bitand(&self, other: &$T) -> $T { *self & *other }
200 impl BitXor<$T,$T> for $T {
202 fn bitxor(&self, other: &$T) -> $T { *self ^ *other }
206 impl Shl<$T,$T> for $T {
208 fn shl(&self, other: &$T) -> $T { *self << *other }
212 impl Shr<$T,$T> for $T {
214 fn shr(&self, other: &$T) -> $T { *self >> *other }
218 impl Not<$T> for $T {
220 fn not(&self) -> $T { !*self }
223 impl Bounded for $T {
225 fn min_value() -> $T { MIN }
228 fn max_value() -> $T { MAX }
233 impl Primitive for $T {}
235 // String conversion functions and impl str -> num
237 /// Parse a byte slice as a number in the given base.
239 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<$T> {
240 strconv::from_str_bytes_common(buf, radix, true, false, false,
241 strconv::ExpNone, false, false)
244 impl FromStr for $T {
246 fn from_str(s: &str) -> Option<$T> {
247 strconv::from_str_common(s, 10u, true, false, false,
248 strconv::ExpNone, false, false)
252 impl FromStrRadix for $T {
254 fn from_str_radix(s: &str, radix: uint) -> Option<$T> {
255 strconv::from_str_common(s, radix, true, false, false,
256 strconv::ExpNone, false, false)
260 // String conversion functions and impl num -> str
262 /// Convert to a string as a byte slice in a given base.
264 pub fn to_str_bytes<U>(n: $T, radix: uint, f: |v: &[u8]| -> U) -> U {
265 // The radix can be as low as 2, so we need at least 64 characters for a
266 // base 2 number, and then we need another for a possible '-' character.
267 let mut buf = [0u8, ..65];
269 strconv::int_to_str_bytes_common(n, radix, strconv::SignNeg, |i| {
276 impl ToStrRadix for $T {
277 /// Convert to a string in a given base.
279 fn to_str_radix(&self, radix: uint) -> ~str {
280 let mut buf = Vec::new();
281 strconv::int_to_str_bytes_common(*self, radix, strconv::SignNeg, |i| {
284 // We know we generated valid utf-8, so we don't need to go through that
286 unsafe { str::raw::from_utf8_owned(buf.move_iter().collect()) }
303 fn test_overflows() {
306 assert_eq!(MIN + MAX + 1, 0);
311 num::test_num(10 as $T, 2 as $T);
316 assert_eq!((1 as $T).abs(), 1 as $T);
317 assert_eq!((0 as $T).abs(), 0 as $T);
318 assert_eq!((-1 as $T).abs(), 1 as $T);
323 assert_eq!((-1 as $T).abs_sub(&(1 as $T)), 0 as $T);
324 assert_eq!((1 as $T).abs_sub(&(1 as $T)), 0 as $T);
325 assert_eq!((1 as $T).abs_sub(&(0 as $T)), 1 as $T);
326 assert_eq!((1 as $T).abs_sub(&(-1 as $T)), 2 as $T);
331 assert_eq!((1 as $T).signum(), 1 as $T);
332 assert_eq!((0 as $T).signum(), 0 as $T);
333 assert_eq!((-0 as $T).signum(), 0 as $T);
334 assert_eq!((-1 as $T).signum(), -1 as $T);
338 fn test_is_positive() {
339 assert!((1 as $T).is_positive());
340 assert!(!(0 as $T).is_positive());
341 assert!(!(-0 as $T).is_positive());
342 assert!(!(-1 as $T).is_positive());
346 fn test_is_negative() {
347 assert!(!(1 as $T).is_negative());
348 assert!(!(0 as $T).is_negative());
349 assert!(!(-0 as $T).is_negative());
350 assert!((-1 as $T).is_negative());
355 assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(&(0b1010 as $T)));
356 assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(&(0b1010 as $T)));
357 assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(&(0b1010 as $T)));
358 assert_eq!(0b1110 as $T, (0b0111 as $T).shl(&(1 as $T)));
359 assert_eq!(0b0111 as $T, (0b1110 as $T).shr(&(1 as $T)));
360 assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not());
364 fn test_count_ones() {
365 assert_eq!((0b0101100 as $T).count_ones(), 3);
366 assert_eq!((0b0100001 as $T).count_ones(), 2);
367 assert_eq!((0b1111001 as $T).count_ones(), 5);
371 fn test_count_zeros() {
372 assert_eq!((0b0101100 as $T).count_zeros(), BITS as $T - 3);
373 assert_eq!((0b0100001 as $T).count_zeros(), BITS as $T - 2);
374 assert_eq!((0b1111001 as $T).count_zeros(), BITS as $T - 5);
379 assert_eq!(from_str::<$T>("0"), Some(0 as $T));
380 assert_eq!(from_str::<$T>("3"), Some(3 as $T));
381 assert_eq!(from_str::<$T>("10"), Some(10 as $T));
382 assert_eq!(from_str::<i32>("123456789"), Some(123456789 as i32));
383 assert_eq!(from_str::<$T>("00100"), Some(100 as $T));
385 assert_eq!(from_str::<$T>("-1"), Some(-1 as $T));
386 assert_eq!(from_str::<$T>("-3"), Some(-3 as $T));
387 assert_eq!(from_str::<$T>("-10"), Some(-10 as $T));
388 assert_eq!(from_str::<i32>("-123456789"), Some(-123456789 as i32));
389 assert_eq!(from_str::<$T>("-00100"), Some(-100 as $T));
391 assert!(from_str::<$T>(" ").is_none());
392 assert!(from_str::<$T>("x").is_none());
396 fn test_parse_bytes() {
398 assert_eq!(parse_bytes("123".as_bytes(), 10u), Some(123 as $T));
399 assert_eq!(parse_bytes("1001".as_bytes(), 2u), Some(9 as $T));
400 assert_eq!(parse_bytes("123".as_bytes(), 8u), Some(83 as $T));
401 assert_eq!(i32::parse_bytes("123".as_bytes(), 16u), Some(291 as i32));
402 assert_eq!(i32::parse_bytes("ffff".as_bytes(), 16u), Some(65535 as i32));
403 assert_eq!(i32::parse_bytes("FFFF".as_bytes(), 16u), Some(65535 as i32));
404 assert_eq!(parse_bytes("z".as_bytes(), 36u), Some(35 as $T));
405 assert_eq!(parse_bytes("Z".as_bytes(), 36u), Some(35 as $T));
407 assert_eq!(parse_bytes("-123".as_bytes(), 10u), Some(-123 as $T));
408 assert_eq!(parse_bytes("-1001".as_bytes(), 2u), Some(-9 as $T));
409 assert_eq!(parse_bytes("-123".as_bytes(), 8u), Some(-83 as $T));
410 assert_eq!(i32::parse_bytes("-123".as_bytes(), 16u), Some(-291 as i32));
411 assert_eq!(i32::parse_bytes("-ffff".as_bytes(), 16u), Some(-65535 as i32));
412 assert_eq!(i32::parse_bytes("-FFFF".as_bytes(), 16u), Some(-65535 as i32));
413 assert_eq!(parse_bytes("-z".as_bytes(), 36u), Some(-35 as $T));
414 assert_eq!(parse_bytes("-Z".as_bytes(), 36u), Some(-35 as $T));
416 assert!(parse_bytes("Z".as_bytes(), 35u).is_none());
417 assert!(parse_bytes("-9".as_bytes(), 2u).is_none());
422 assert_eq!((0 as $T).to_str_radix(10u), ~"0");
423 assert_eq!((1 as $T).to_str_radix(10u), ~"1");
424 assert_eq!((-1 as $T).to_str_radix(10u), ~"-1");
425 assert_eq!((127 as $T).to_str_radix(16u), ~"7f");
426 assert_eq!((100 as $T).to_str_radix(10u), ~"100");
431 fn test_int_to_str_overflow() {
432 let mut i8_val: i8 = 127_i8;
433 assert_eq!(i8_val.to_str(), ~"127");
436 assert_eq!(i8_val.to_str(), ~"-128");
438 let mut i16_val: i16 = 32_767_i16;
439 assert_eq!(i16_val.to_str(), ~"32767");
442 assert_eq!(i16_val.to_str(), ~"-32768");
444 let mut i32_val: i32 = 2_147_483_647_i32;
445 assert_eq!(i32_val.to_str(), ~"2147483647");
448 assert_eq!(i32_val.to_str(), ~"-2147483648");
450 let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
451 assert_eq!(i64_val.to_str(), ~"9223372036854775807");
454 assert_eq!(i64_val.to_str(), ~"-9223372036854775808");
458 fn test_int_from_str_overflow() {
459 let mut i8_val: i8 = 127_i8;
460 assert_eq!(from_str::<i8>("127"), Some(i8_val));
461 assert!(from_str::<i8>("128").is_none());
464 assert_eq!(from_str::<i8>("-128"), Some(i8_val));
465 assert!(from_str::<i8>("-129").is_none());
467 let mut i16_val: i16 = 32_767_i16;
468 assert_eq!(from_str::<i16>("32767"), Some(i16_val));
469 assert!(from_str::<i16>("32768").is_none());
472 assert_eq!(from_str::<i16>("-32768"), Some(i16_val));
473 assert!(from_str::<i16>("-32769").is_none());
475 let mut i32_val: i32 = 2_147_483_647_i32;
476 assert_eq!(from_str::<i32>("2147483647"), Some(i32_val));
477 assert!(from_str::<i32>("2147483648").is_none());
480 assert_eq!(from_str::<i32>("-2147483648"), Some(i32_val));
481 assert!(from_str::<i32>("-2147483649").is_none());
483 let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
484 assert_eq!(from_str::<i64>("9223372036854775807"), Some(i64_val));
485 assert!(from_str::<i64>("9223372036854775808").is_none());
488 assert_eq!(from_str::<i64>("-9223372036854775808"), Some(i64_val));
489 assert!(from_str::<i64>("-9223372036854775809").is_none());
493 fn test_signed_checked_div() {
494 assert_eq!(10i.checked_div(&2), Some(5));
495 assert_eq!(5i.checked_div(&0), None);
496 assert_eq!(int::MIN.checked_div(&-1), None);