]> git.lizzy.rs Git - rust.git/blob - src/libcore/num/uint-template.rs
libcore: Export core::from_str::FromStr from core::prelude
[rust.git] / src / libcore / num / uint-template.rs
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 use T = self::inst::T;
12 use T_SIGNED = self::inst::T_SIGNED;
13
14 use num::{ToStrRadix, FromStrRadix};
15 use num::{Zero, One, strconv};
16 use prelude::*;
17
18 pub use cmp::{min, max};
19
20 pub static bits : uint = inst::bits;
21 pub static bytes : uint = (inst::bits / 8);
22
23 pub static min_value: T = 0 as T;
24 pub static max_value: T = 0 as T - 1 as T;
25
26 #[inline(always)]
27 pub fn add(x: T, y: T) -> T { x + y }
28 #[inline(always)]
29 pub fn sub(x: T, y: T) -> T { x - y }
30 #[inline(always)]
31 pub fn mul(x: T, y: T) -> T { x * y }
32 #[inline(always)]
33 pub fn div(x: T, y: T) -> T { x / y }
34 #[inline(always)]
35 pub fn rem(x: T, y: T) -> T { x % y }
36
37 #[inline(always)]
38 pub fn lt(x: T, y: T) -> bool { x < y }
39 #[inline(always)]
40 pub fn le(x: T, y: T) -> bool { x <= y }
41 #[inline(always)]
42 pub fn eq(x: T, y: T) -> bool { x == y }
43 #[inline(always)]
44 pub fn ne(x: T, y: T) -> bool { x != y }
45 #[inline(always)]
46 pub fn ge(x: T, y: T) -> bool { x >= y }
47 #[inline(always)]
48 pub fn gt(x: T, y: T) -> bool { x > y }
49
50 #[inline(always)]
51 ///
52 /// Iterate over the range [`start`,`start`+`step`..`stop`)
53 ///
54 pub fn range_step(start: T,
55                        stop: T,
56                        step: T_SIGNED,
57                        it: &fn(T) -> bool) {
58     let mut i = start;
59     if step == 0 {
60         fail!(~"range_step called with step == 0");
61     }
62     if step >= 0 {
63         while i < stop {
64             if !it(i) { break }
65             // avoiding overflow. break if i + step > max_value
66             if i > max_value - (step as T) { break; }
67             i += step as T;
68         }
69     } else {
70         while i > stop {
71             if !it(i) { break }
72             // avoiding underflow. break if i + step < min_value
73             if i < min_value + ((-step) as T) { break; }
74             i -= -step as T;
75         }
76     }
77 }
78
79 #[inline(always)]
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);
83 }
84
85 #[inline(always)]
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);
89 }
90
91 /// Computes the bitwise complement
92 #[inline(always)]
93 pub fn compl(i: T) -> T {
94     max_value ^ i
95 }
96
97 impl Num for T {}
98
99 #[cfg(notest)]
100 impl Ord for T {
101     #[inline(always)]
102     fn lt(&self, other: &T) -> bool { (*self) < (*other) }
103     #[inline(always)]
104     fn le(&self, other: &T) -> bool { (*self) <= (*other) }
105     #[inline(always)]
106     fn ge(&self, other: &T) -> bool { (*self) >= (*other) }
107     #[inline(always)]
108     fn gt(&self, other: &T) -> bool { (*self) > (*other) }
109 }
110
111 #[cfg(notest)]
112 impl Eq for T {
113     #[inline(always)]
114     fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
115     #[inline(always)]
116     fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
117 }
118
119 impl Orderable for T {
120     #[inline(always)]
121     fn min(&self, other: &T) -> T {
122         if *self < *other { *self } else { *other }
123     }
124
125     #[inline(always)]
126     fn max(&self, other: &T) -> T {
127         if *self > *other { *self } else { *other }
128     }
129
130     #[inline(always)]
131     fn clamp(&self, mn: &T, mx: &T) -> T {
132         if *self > *mx { *mx } else
133         if *self < *mn { *mn } else { *self }
134     }
135 }
136
137 impl Zero for T {
138     #[inline(always)]
139     fn zero() -> T { 0 }
140
141     #[inline(always)]
142     fn is_zero(&self) -> bool { *self == 0 }
143 }
144
145 impl One for T {
146     #[inline(always)]
147     fn one() -> T { 1 }
148 }
149
150 #[cfg(notest)]
151 impl Add<T,T> for T {
152     #[inline(always)]
153     fn add(&self, other: &T) -> T { *self + *other }
154 }
155
156 #[cfg(notest)]
157 impl Sub<T,T> for T {
158     #[inline(always)]
159     fn sub(&self, other: &T) -> T { *self - *other }
160 }
161
162 #[cfg(notest)]
163 impl Mul<T,T> for T {
164     #[inline(always)]
165     fn mul(&self, other: &T) -> T { *self * *other }
166 }
167
168 #[cfg(notest)]
169 impl Div<T,T> for T {
170     #[inline(always)]
171     fn div(&self, other: &T) -> T { *self / *other }
172 }
173
174 #[cfg(stage0,notest)]
175 impl Modulo<T,T> for T {
176     #[inline(always)]
177     fn modulo(&self, other: &T) -> T { *self % *other }
178 }
179 #[cfg(not(stage0),notest)]
180 impl Rem<T,T> for T {
181     #[inline(always)]
182     fn rem(&self, other: &T) -> T { *self % *other }
183 }
184
185 #[cfg(notest)]
186 impl Neg<T> for T {
187     #[inline(always)]
188     fn neg(&self) -> T { -*self }
189 }
190
191 impl Unsigned for T {}
192
193 impl Integer for T {
194     /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
195     #[inline(always)]
196     fn div_rem(&self, other: &T) -> (T,T) {
197         (*self / *other, *self % *other)
198     }
199
200     /// Unsigned integer division. Returns the same result as `div` (`/`).
201     #[inline(always)]
202     fn div_floor(&self, other: &T) -> T { *self / *other }
203
204     /// Unsigned integer modulo operation. Returns the same result as `rem` (`%`).
205     #[inline(always)]
206     fn mod_floor(&self, other: &T) -> T { *self / *other }
207
208     /// Calculates `div_floor` and `modulo_floor` simultaneously
209     #[inline(always)]
210     fn div_mod_floor(&self, other: &T) -> (T,T) {
211         (*self / *other, *self % *other)
212     }
213
214     /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
215     #[inline(always)]
216     fn gcd(&self, other: &T) -> T {
217         // Use Euclid's algorithm
218         let mut m = *self, n = *other;
219         while m != 0 {
220             let temp = m;
221             m = n % temp;
222             n = temp;
223         }
224         n
225     }
226
227     /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
228     #[inline(always)]
229     fn lcm(&self, other: &T) -> T {
230         (*self * *other) / self.gcd(other)
231     }
232
233     /// Returns `true` if the number can be divided by `other` without leaving a remainder
234     #[inline(always)]
235     fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 }
236
237     /// Returns `true` if the number is divisible by `2`
238     #[inline(always)]
239     fn is_even(&self) -> bool { self.is_multiple_of(&2) }
240
241     /// Returns `true` if the number is not divisible by `2`
242     #[inline(always)]
243     fn is_odd(&self) -> bool { !self.is_even() }
244 }
245
246 impl Bitwise for T {}
247
248 #[cfg(notest)]
249 impl BitOr<T,T> for T {
250     #[inline(always)]
251     fn bitor(&self, other: &T) -> T { *self | *other }
252 }
253
254 #[cfg(notest)]
255 impl BitAnd<T,T> for T {
256     #[inline(always)]
257     fn bitand(&self, other: &T) -> T { *self & *other }
258 }
259
260 #[cfg(notest)]
261 impl BitXor<T,T> for T {
262     #[inline(always)]
263     fn bitxor(&self, other: &T) -> T { *self ^ *other }
264 }
265
266 #[cfg(notest)]
267 impl Shl<T,T> for T {
268     #[inline(always)]
269     fn shl(&self, other: &T) -> T { *self << *other }
270 }
271
272 #[cfg(notest)]
273 impl Shr<T,T> for T {
274     #[inline(always)]
275     fn shr(&self, other: &T) -> T { *self >> *other }
276 }
277
278 #[cfg(notest)]
279 impl Not<T> for T {
280     #[inline(always)]
281     fn not(&self) -> T { !*self }
282 }
283
284 impl Bounded for T {
285     #[inline(always)]
286     fn min_value() -> T { min_value }
287
288     #[inline(always)]
289     fn max_value() -> T { max_value }
290 }
291
292 impl Int for T {}
293
294 // String conversion functions and impl str -> num
295
296 /// Parse a string as a number in base 10.
297 #[inline(always)]
298 pub fn from_str(s: &str) -> Option<T> {
299     strconv::from_str_common(s, 10u, false, false, false,
300                              strconv::ExpNone, false, false)
301 }
302
303 /// Parse a string as a number in the given base.
304 #[inline(always)]
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)
308 }
309
310 /// Parse a byte slice as a number in the given base.
311 #[inline(always)]
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)
315 }
316
317 impl FromStr for T {
318     #[inline(always)]
319     fn from_str(s: &str) -> Option<T> {
320         from_str(s)
321     }
322 }
323
324 impl FromStrRadix for T {
325     #[inline(always)]
326     fn from_str_radix(s: &str, radix: uint) -> Option<T> {
327         from_str_radix(s, radix)
328     }
329 }
330
331 // String conversion functions and impl num -> str
332
333 /// Convert to a string as a byte slice in a given base.
334 #[inline(always)]
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);
338     f(buf)
339 }
340
341 /// Convert to a string in base 10.
342 #[inline(always)]
343 pub fn to_str(num: T) -> ~str {
344     let (buf, _) = strconv::to_str_common(&num, 10u, false,
345                             strconv::SignNeg, strconv::DigAll);
346     buf
347 }
348
349 /// Convert to a string in a given base.
350 #[inline(always)]
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);
354     buf
355 }
356
357 impl ToStr for T {
358     #[inline(always)]
359     fn to_str(&self) -> ~str {
360         to_str(*self)
361     }
362 }
363
364 impl ToStrRadix for T {
365     #[inline(always)]
366     fn to_str_radix(&self, radix: uint) -> ~str {
367         to_str_radix(*self, radix)
368     }
369 }
370
371 #[cfg(test)]
372 mod tests {
373     use super::*;
374     use super::inst::T;
375     use prelude::*;
376
377     #[test]
378     fn test_num() {
379         num::test_num(10 as T, 2 as T);
380     }
381
382     #[test]
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);
391     }
392
393     #[test]
394     fn test_gcd() {
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);
400     }
401
402     #[test]
403     fn test_lcm() {
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);
410     }
411
412     #[test]
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)));
417     }
418
419     #[test]
420     fn test_even() {
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);
426     }
427
428     #[test]
429     fn test_odd() {
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);
435     }
436
437     #[test]
438     fn test_bitwise() {
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());
445     }
446
447     #[test]
448     fn test_bitcount() {
449         assert_eq!((0b010101 as T).population_count(), 3);
450     }
451
452     #[test]
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>());
456     }
457
458     #[test]
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");
467     }
468
469     #[test]
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));
476
477         assert!(from_str(~"").is_none());
478         assert!(from_str(~" ").is_none());
479         assert!(from_str(~"x").is_none());
480     }
481
482     #[test]
483     pub fn test_parse_bytes() {
484         use str::to_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));
491
492         assert!(parse_bytes(to_bytes(~"Z"), 10u).is_none());
493         assert!(parse_bytes(to_bytes(~"_"), 2u).is_none());
494     }
495
496     #[test]
497     fn test_uint_to_str_overflow() {
498         let mut u8_val: u8 = 255_u8;
499         assert_eq!(u8::to_str(u8_val), ~"255");
500
501         u8_val += 1 as u8;
502         assert_eq!(u8::to_str(u8_val), ~"0");
503
504         let mut u16_val: u16 = 65_535_u16;
505         assert_eq!(u16::to_str(u16_val), ~"65535");
506
507         u16_val += 1 as u16;
508         assert_eq!(u16::to_str(u16_val), ~"0");
509
510         let mut u32_val: u32 = 4_294_967_295_u32;
511         assert_eq!(u32::to_str(u32_val), ~"4294967295");
512
513         u32_val += 1 as u32;
514         assert_eq!(u32::to_str(u32_val), ~"0");
515
516         let mut u64_val: u64 = 18_446_744_073_709_551_615_u64;
517         assert_eq!(u64::to_str(u64_val), ~"18446744073709551615");
518
519         u64_val += 1 as u64;
520         assert_eq!(u64::to_str(u64_val), ~"0");
521     }
522
523     #[test]
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());
528
529         u8_val += 1 as u8;
530         assert_eq!(u8::from_str(~"0"), Some(u8_val));
531         assert!(u8::from_str(~"-1").is_none());
532
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());
536
537         u16_val += 1 as u16;
538         assert_eq!(u16::from_str(~"0"), Some(u16_val));
539         assert!(u16::from_str(~"-1").is_none());
540
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());
544
545         u32_val += 1 as u32;
546         assert_eq!(u32::from_str(~"0"), Some(u32_val));
547         assert!(u32::from_str(~"-1").is_none());
548
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());
552
553         u64_val += 1 as u64;
554         assert_eq!(u64::from_str(~"0"), Some(u64_val));
555         assert!(u64::from_str(~"-1").is_none());
556     }
557
558     #[test]
559     #[should_fail]
560     #[ignore(cfg(windows))]
561     pub fn to_str_radix1() {
562         uint::to_str_radix(100u, 1u);
563     }
564
565     #[test]
566     #[should_fail]
567     #[ignore(cfg(windows))]
568     pub fn to_str_radix37() {
569         uint::to_str_radix(100u, 37u);
570     }
571
572     #[test]
573     pub fn test_ranges() {
574         let mut l = ~[];
575
576         for range(0,3) |i| {
577             l.push(i);
578         }
579         for range_rev(13,10) |i| {
580             l.push(i);
581         }
582         for range_step(20,26,2) |i| {
583             l.push(i);
584         }
585         for range_step(36,30,-2) |i| {
586             l.push(i);
587         }
588         for range_step(max_value - 2, max_value, 2) |i| {
589             l.push(i);
590         }
591         for range_step(max_value - 3, max_value, 2) |i| {
592             l.push(i);
593         }
594         for range_step(min_value + 2, min_value, -2) |i| {
595             l.push(i);
596         }
597         for range_step(min_value + 3, min_value, -2) |i| {
598             l.push(i);
599         }
600
601         assert_eq!(l, ~[0,1,2,
602                         13,12,11,
603                         20,22,24,
604                         36,34,32,
605                         max_value-2,
606                         max_value-3,max_value-1,
607                         min_value+2,
608                         min_value+3,min_value+1]);
609
610         // None of the `fail`s should execute.
611         for range(0,0) |_i| {
612             fail!(~"unreachable");
613         }
614         for range_rev(0,0) |_i| {
615             fail!(~"unreachable");
616         }
617         for range_step(10,0,1) |_i| {
618             fail!(~"unreachable");
619         }
620         for range_step(0,1,-10) |_i| {
621             fail!(~"unreachable");
622         }
623     }
624
625     #[test]
626     #[should_fail]
627     #[ignore(cfg(windows))]
628     fn test_range_step_zero_step_up() {
629         for range_step(0,10,0) |_i| {}
630     }
631     #[test]
632     #[should_fail]
633     #[ignore(cfg(windows))]
634     fn test_range_step_zero_step_down() {
635         for range_step(0,-10,0) |_i| {}
636     }
637 }