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.
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.
11 use T = self::inst::T;
12 use T_SIGNED = self::inst::T_SIGNED;
14 use num::{ToStrRadix, FromStrRadix};
15 use num::{Zero, One, strconv};
18 pub use cmp::{min, max};
20 pub static bits : uint = inst::bits;
21 pub static bytes : uint = (inst::bits / 8);
23 pub static min_value: T = 0 as T;
24 pub static max_value: T = 0 as T - 1 as T;
27 pub fn add(x: T, y: T) -> T { x + y }
29 pub fn sub(x: T, y: T) -> T { x - y }
31 pub fn mul(x: T, y: T) -> T { x * y }
33 pub fn div(x: T, y: T) -> T { x / y }
35 pub fn rem(x: T, y: T) -> T { x % y }
38 pub fn lt(x: T, y: T) -> bool { x < y }
40 pub fn le(x: T, y: T) -> bool { x <= y }
42 pub fn eq(x: T, y: T) -> bool { x == y }
44 pub fn ne(x: T, y: T) -> bool { x != y }
46 pub fn ge(x: T, y: T) -> bool { x >= y }
48 pub fn gt(x: T, y: T) -> bool { x > y }
52 /// Iterate over the range [`start`,`start`+`step`..`stop`)
54 pub fn range_step(start: T,
60 fail!(~"range_step called with step == 0");
65 // avoiding overflow. break if i + step > max_value
66 if i > max_value - (step as T) { break; }
72 // avoiding underflow. break if i + step < min_value
73 if i < min_value + ((-step) as T) { break; }
80 /// Iterate over the range [`lo`..`hi`)
81 pub fn range(lo: T, hi: T, it: &fn(T) -> bool) {
82 range_step(lo, hi, 1 as T_SIGNED, it);
86 /// Iterate over the range [`hi`..`lo`)
87 pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) {
88 range_step(hi, lo, -1 as T_SIGNED, it);
91 /// Computes the bitwise complement
93 pub fn compl(i: T) -> T {
102 fn lt(&self, other: &T) -> bool { (*self) < (*other) }
104 fn le(&self, other: &T) -> bool { (*self) <= (*other) }
106 fn ge(&self, other: &T) -> bool { (*self) >= (*other) }
108 fn gt(&self, other: &T) -> bool { (*self) > (*other) }
114 fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
116 fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
119 impl Orderable for T {
121 fn min(&self, other: &T) -> T {
122 if *self < *other { *self } else { *other }
126 fn max(&self, other: &T) -> T {
127 if *self > *other { *self } else { *other }
131 fn clamp(&self, mn: &T, mx: &T) -> T {
132 if *self > *mx { *mx } else
133 if *self < *mn { *mn } else { *self }
142 fn is_zero(&self) -> bool { *self == 0 }
151 impl Add<T,T> for T {
153 fn add(&self, other: &T) -> T { *self + *other }
157 impl Sub<T,T> for T {
159 fn sub(&self, other: &T) -> T { *self - *other }
163 impl Mul<T,T> for T {
165 fn mul(&self, other: &T) -> T { *self * *other }
169 impl Div<T,T> for T {
171 fn div(&self, other: &T) -> T { *self / *other }
174 #[cfg(stage0,notest)]
175 impl Modulo<T,T> for T {
177 fn modulo(&self, other: &T) -> T { *self % *other }
179 #[cfg(not(stage0),notest)]
180 impl Rem<T,T> for T {
182 fn rem(&self, other: &T) -> T { *self % *other }
188 fn neg(&self) -> T { -*self }
191 impl Unsigned for T {}
194 /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
196 fn div_rem(&self, other: &T) -> (T,T) {
197 (*self / *other, *self % *other)
200 /// Unsigned integer division. Returns the same result as `div` (`/`).
202 fn div_floor(&self, other: &T) -> T { *self / *other }
204 /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
206 fn mod_floor(&self, other: &T) -> T { *self / *other }
208 /// Calculates `div_floor` and `modulo_floor` simultaneously
210 fn div_mod_floor(&self, other: &T) -> (T,T) {
211 (*self / *other, *self % *other)
214 /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
216 fn gcd(&self, other: &T) -> T {
217 // Use Euclid's algorithm
218 let mut m = *self, n = *other;
227 /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
229 fn lcm(&self, other: &T) -> T {
230 (*self * *other) / self.gcd(other)
233 /// Returns `true` if the number can be divided by `other` without leaving a remainder
235 fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 }
237 /// Returns `true` if the number is divisible by `2`
239 fn is_even(&self) -> bool { self.is_multiple_of(&2) }
241 /// Returns `true` if the number is not divisible by `2`
243 fn is_odd(&self) -> bool { !self.is_even() }
246 impl Bitwise for T {}
249 impl BitOr<T,T> for T {
251 fn bitor(&self, other: &T) -> T { *self | *other }
255 impl BitAnd<T,T> for T {
257 fn bitand(&self, other: &T) -> T { *self & *other }
261 impl BitXor<T,T> for T {
263 fn bitxor(&self, other: &T) -> T { *self ^ *other }
267 impl Shl<T,T> for T {
269 fn shl(&self, other: &T) -> T { *self << *other }
273 impl Shr<T,T> for T {
275 fn shr(&self, other: &T) -> T { *self >> *other }
281 fn not(&self) -> T { !*self }
286 fn min_value() -> T { min_value }
289 fn max_value() -> T { max_value }
294 // String conversion functions and impl str -> num
296 /// Parse a string as a number in base 10.
298 pub fn from_str(s: &str) -> Option<T> {
299 strconv::from_str_common(s, 10u, false, false, false,
300 strconv::ExpNone, false, false)
303 /// Parse a string as a number in the given base.
305 pub fn from_str_radix(s: &str, radix: uint) -> Option<T> {
306 strconv::from_str_common(s, radix, false, false, false,
307 strconv::ExpNone, false, false)
310 /// Parse a byte slice as a number in the given base.
312 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
313 strconv::from_str_bytes_common(buf, radix, false, false, false,
314 strconv::ExpNone, false, false)
319 fn from_str(s: &str) -> Option<T> {
324 impl FromStrRadix for T {
326 fn from_str_radix(s: &str, radix: uint) -> Option<T> {
327 from_str_radix(s, radix)
331 // String conversion functions and impl num -> str
333 /// Convert to a string as a byte slice in a given base.
335 pub fn to_str_bytes<U>(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
336 let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
337 strconv::SignNeg, strconv::DigAll);
341 /// Convert to a string in base 10.
343 pub fn to_str(num: T) -> ~str {
344 let (buf, _) = strconv::to_str_common(&num, 10u, false,
345 strconv::SignNeg, strconv::DigAll);
349 /// Convert to a string in a given base.
351 pub fn to_str_radix(num: T, radix: uint) -> ~str {
352 let (buf, _) = strconv::to_str_common(&num, radix, false,
353 strconv::SignNeg, strconv::DigAll);
359 fn to_str(&self) -> ~str {
364 impl ToStrRadix for T {
366 fn to_str_radix(&self, radix: uint) -> ~str {
367 to_str_radix(*self, radix)
379 num::test_num(10 as T, 2 as T);
383 fn test_orderable() {
384 assert_eq!((1 as T).min(&(2 as T)), 1 as T);
385 assert_eq!((2 as T).min(&(1 as T)), 1 as T);
386 assert_eq!((1 as T).max(&(2 as T)), 2 as T);
387 assert_eq!((2 as T).max(&(1 as T)), 2 as T);
388 assert_eq!((1 as T).clamp(&(2 as T), &(4 as T)), 2 as T);
389 assert_eq!((8 as T).clamp(&(2 as T), &(4 as T)), 4 as T);
390 assert_eq!((3 as T).clamp(&(2 as T), &(4 as T)), 3 as T);
395 assert_eq!((10 as T).gcd(&2), 2 as T);
396 assert_eq!((10 as T).gcd(&3), 1 as T);
397 assert_eq!((0 as T).gcd(&3), 3 as T);
398 assert_eq!((3 as T).gcd(&3), 3 as T);
399 assert_eq!((56 as T).gcd(&42), 14 as T);
404 assert_eq!((1 as T).lcm(&0), 0 as T);
405 assert_eq!((0 as T).lcm(&1), 0 as T);
406 assert_eq!((1 as T).lcm(&1), 1 as T);
407 assert_eq!((8 as T).lcm(&9), 72 as T);
408 assert_eq!((11 as T).lcm(&5), 55 as T);
409 assert_eq!((99 as T).lcm(&17), 1683 as T);
413 fn test_multiple_of() {
414 assert!((6 as T).is_multiple_of(&(6 as T)));
415 assert!((6 as T).is_multiple_of(&(3 as T)));
416 assert!((6 as T).is_multiple_of(&(1 as T)));
421 assert_eq!((0 as T).is_even(), true);
422 assert_eq!((1 as T).is_even(), false);
423 assert_eq!((2 as T).is_even(), true);
424 assert_eq!((3 as T).is_even(), false);
425 assert_eq!((4 as T).is_even(), true);
430 assert_eq!((0 as T).is_odd(), false);
431 assert_eq!((1 as T).is_odd(), true);
432 assert_eq!((2 as T).is_odd(), false);
433 assert_eq!((3 as T).is_odd(), true);
434 assert_eq!((4 as T).is_odd(), false);
439 assert_eq!(0b1110 as T, (0b1100 as T).bitor(&(0b1010 as T)));
440 assert_eq!(0b1000 as T, (0b1100 as T).bitand(&(0b1010 as T)));
441 assert_eq!(0b0110 as T, (0b1100 as T).bitxor(&(0b1010 as T)));
442 assert_eq!(0b1110 as T, (0b0111 as T).shl(&(1 as T)));
443 assert_eq!(0b0111 as T, (0b1110 as T).shr(&(1 as T)));
444 assert_eq!(max_value - (0b1011 as T), (0b1011 as T).not());
449 assert_eq!((0b010101 as T).population_count(), 3);
453 fn test_primitive() {
454 assert_eq!(Primitive::bits::<T>(), sys::size_of::<T>() * 8);
455 assert_eq!(Primitive::bytes::<T>(), sys::size_of::<T>());
459 pub fn test_to_str() {
460 assert_eq!(to_str_radix(0 as T, 10u), ~"0");
461 assert_eq!(to_str_radix(1 as T, 10u), ~"1");
462 assert_eq!(to_str_radix(2 as T, 10u), ~"2");
463 assert_eq!(to_str_radix(11 as T, 10u), ~"11");
464 assert_eq!(to_str_radix(11 as T, 16u), ~"b");
465 assert_eq!(to_str_radix(255 as T, 16u), ~"ff");
466 assert_eq!(to_str_radix(0xff as T, 10u), ~"255");
470 pub fn test_from_str() {
471 assert_eq!(from_str(~"0"), Some(0u as T));
472 assert_eq!(from_str(~"3"), Some(3u as T));
473 assert_eq!(from_str(~"10"), Some(10u as T));
474 assert_eq!(u32::from_str(~"123456789"), Some(123456789 as u32));
475 assert_eq!(from_str(~"00100"), Some(100u as T));
477 assert!(from_str(~"").is_none());
478 assert!(from_str(~" ").is_none());
479 assert!(from_str(~"x").is_none());
483 pub fn test_parse_bytes() {
485 assert_eq!(parse_bytes(to_bytes(~"123"), 10u), Some(123u as T));
486 assert_eq!(parse_bytes(to_bytes(~"1001"), 2u), Some(9u as T));
487 assert_eq!(parse_bytes(to_bytes(~"123"), 8u), Some(83u as T));
488 assert_eq!(u16::parse_bytes(to_bytes(~"123"), 16u), Some(291u as u16));
489 assert_eq!(u16::parse_bytes(to_bytes(~"ffff"), 16u), Some(65535u as u16));
490 assert_eq!(parse_bytes(to_bytes(~"z"), 36u), Some(35u as T));
492 assert!(parse_bytes(to_bytes(~"Z"), 10u).is_none());
493 assert!(parse_bytes(to_bytes(~"_"), 2u).is_none());
497 fn test_uint_to_str_overflow() {
498 let mut u8_val: u8 = 255_u8;
499 assert_eq!(u8::to_str(u8_val), ~"255");
502 assert_eq!(u8::to_str(u8_val), ~"0");
504 let mut u16_val: u16 = 65_535_u16;
505 assert_eq!(u16::to_str(u16_val), ~"65535");
508 assert_eq!(u16::to_str(u16_val), ~"0");
510 let mut u32_val: u32 = 4_294_967_295_u32;
511 assert_eq!(u32::to_str(u32_val), ~"4294967295");
514 assert_eq!(u32::to_str(u32_val), ~"0");
516 let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
517 assert_eq!(u64::to_str(u64_val), ~"18446744073709551615");
520 assert_eq!(u64::to_str(u64_val), ~"0");
524 fn test_uint_from_str_overflow() {
525 let mut u8_val: u8 = 255_u8;
526 assert_eq!(u8::from_str(~"255"), Some(u8_val));
527 assert!(u8::from_str(~"256").is_none());
530 assert_eq!(u8::from_str(~"0"), Some(u8_val));
531 assert!(u8::from_str(~"-1").is_none());
533 let mut u16_val: u16 = 65_535_u16;
534 assert_eq!(u16::from_str(~"65535"), Some(u16_val));
535 assert!(u16::from_str(~"65536").is_none());
538 assert_eq!(u16::from_str(~"0"), Some(u16_val));
539 assert!(u16::from_str(~"-1").is_none());
541 let mut u32_val: u32 = 4_294_967_295_u32;
542 assert_eq!(u32::from_str(~"4294967295"), Some(u32_val));
543 assert!(u32::from_str(~"4294967296").is_none());
546 assert_eq!(u32::from_str(~"0"), Some(u32_val));
547 assert!(u32::from_str(~"-1").is_none());
549 let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
550 assert_eq!(u64::from_str(~"18446744073709551615"), Some(u64_val));
551 assert!(u64::from_str(~"18446744073709551616").is_none());
554 assert_eq!(u64::from_str(~"0"), Some(u64_val));
555 assert!(u64::from_str(~"-1").is_none());
560 #[ignore(cfg(windows))]
561 pub fn to_str_radix1() {
562 uint::to_str_radix(100u, 1u);
567 #[ignore(cfg(windows))]
568 pub fn to_str_radix37() {
569 uint::to_str_radix(100u, 37u);
573 pub fn test_ranges() {
579 for range_rev(13,10) |i| {
582 for range_step(20,26,2) |i| {
585 for range_step(36,30,-2) |i| {
588 for range_step(max_value - 2, max_value, 2) |i| {
591 for range_step(max_value - 3, max_value, 2) |i| {
594 for range_step(min_value + 2, min_value, -2) |i| {
597 for range_step(min_value + 3, min_value, -2) |i| {
601 assert_eq!(l, ~[0,1,2,
606 max_value-3,max_value-1,
608 min_value+3,min_value+1]);
610 // None of the `fail`s should execute.
611 for range(0,0) |_i| {
612 fail!(~"unreachable");
614 for range_rev(0,0) |_i| {
615 fail!(~"unreachable");
617 for range_step(10,0,1) |_i| {
618 fail!(~"unreachable");
620 for range_step(0,1,-10) |_i| {
621 fail!(~"unreachable");
627 #[ignore(cfg(windows))]
628 fn test_range_step_zero_step_up() {
629 for range_step(0,10,0) |_i| {}
633 #[ignore(cfg(windows))]
634 fn test_range_step_zero_step_down() {
635 for range_step(0,-10,0) |_i| {}