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;
13 use from_str::FromStr;
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 = (-1 as T) << (bits - 1);
24 pub static max_value: T = min_value - 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 }
36 /// Returns the remainder of y / x.
40 /// assert!(int::rem(5 / 2) == 1);
43 /// When faced with negative numbers, the result copies the sign of the
47 /// assert!(int::rem(2 / -3) == 2);
51 /// assert!(int::rem(-2 / 3) == -2);
56 pub fn rem(x: T, y: T) -> T { x % y }
59 pub fn lt(x: T, y: T) -> bool { x < y }
61 pub fn le(x: T, y: T) -> bool { x <= y }
63 pub fn eq(x: T, y: T) -> bool { x == y }
65 pub fn ne(x: T, y: T) -> bool { x != y }
67 pub fn ge(x: T, y: T) -> bool { x >= y }
69 pub fn gt(x: T, y: T) -> bool { x > y }
72 /// Iterate over the range [`lo`..`hi`)
76 /// * `lo` - lower bound, inclusive
77 /// * `hi` - higher bound, exclusive
82 /// for int::range(1, 5) |i| {
85 /// assert!(sum == 10);
89 /// Iterate over the range [`start`,`start`+`step`..`stop`)
90 pub fn range_step(start: T, stop: T, step: T, it: &fn(T) -> bool) {
93 fail!(~"range_step called with step == 0");
94 } else if step > 0 { // ascending
97 // avoiding overflow. break if i + step > max_value
98 if i > max_value - step { break; }
101 } else { // descending
104 // avoiding underflow. break if i + step < min_value
105 if i < min_value - step { break; }
112 /// Iterate over the range [`lo`..`hi`)
113 pub fn range(lo: T, hi: T, it: &fn(T) -> bool) {
114 range_step(lo, hi, 1 as T, it);
118 /// Iterate over the range [`hi`..`lo`)
119 pub fn range_rev(hi: T, lo: T, it: &fn(T) -> bool) {
120 range_step(hi, lo, -1 as T, it);
123 /// Computes the bitwise complement
125 pub fn compl(i: T) -> T {
129 /// Computes the absolute value
131 pub fn abs(i: T) -> T { i.abs() }
138 fn lt(&self, other: &T) -> bool { return (*self) < (*other); }
140 fn le(&self, other: &T) -> bool { return (*self) <= (*other); }
142 fn ge(&self, other: &T) -> bool { return (*self) >= (*other); }
144 fn gt(&self, other: &T) -> bool { return (*self) > (*other); }
150 fn eq(&self, other: &T) -> bool { return (*self) == (*other); }
152 fn ne(&self, other: &T) -> bool { return (*self) != (*other); }
155 impl Orderable for T {
157 fn min(&self, other: &T) -> T {
158 if *self < *other { *self } else { *other }
162 fn max(&self, other: &T) -> T {
163 if *self > *other { *self } else { *other }
167 fn clamp(&self, mn: &T, mx: &T) -> T {
168 if *self > *mx { *mx } else
169 if *self < *mn { *mn } else { *self }
178 fn is_zero(&self) -> bool { *self == 0 }
187 impl Add<T,T> for T {
189 fn add(&self, other: &T) -> T { *self + *other }
193 impl Sub<T,T> for T {
195 fn sub(&self, other: &T) -> T { *self - *other }
199 impl Mul<T,T> for T {
201 fn mul(&self, other: &T) -> T { *self * *other }
205 impl Div<T,T> for T {
207 /// Integer division, truncated towards 0. As this behaviour reflects the underlying
208 /// machine implementation it is more efficient than `Integer::div_floor`.
213 /// assert!( 8 / 3 == 2);
214 /// assert!( 8 / -3 == -2);
215 /// assert!(-8 / 3 == -2);
216 /// assert!(-8 / -3 == 2);
218 /// assert!( 1 / 2 == 0);
219 /// assert!( 1 / -2 == 0);
220 /// assert!(-1 / 2 == 0);
221 /// assert!(-1 / -2 == 0);
225 fn div(&self, other: &T) -> T { *self / *other }
228 #[cfg(stage0,notest)]
229 impl Modulo<T,T> for T {
231 fn modulo(&self, other: &T) -> T { *self % *other }
233 #[cfg(not(stage0),notest)]
234 impl Rem<T,T> for T {
236 /// Returns the integer remainder after division, satisfying:
239 /// assert!((n / d) * d + (n % d) == n)
245 /// assert!( 8 % 3 == 2);
246 /// assert!( 8 % -3 == 2);
247 /// assert!(-8 % 3 == -2);
248 /// assert!(-8 % -3 == -2);
250 /// assert!( 1 % 2 == 1);
251 /// assert!( 1 % -2 == 1);
252 /// assert!(-1 % 2 == -1);
253 /// assert!(-1 % -2 == -1);
257 fn rem(&self, other: &T) -> T { *self % *other }
263 fn neg(&self) -> T { -*self }
267 /// Computes the absolute value
270 if self.is_negative() { -*self } else { *self }
276 /// - `0` if the number is zero
277 /// - `1` if the number is positive
278 /// - `-1` if the number is negative
281 fn signum(&self) -> T {
289 /// Returns true if the number is positive
291 fn is_positive(&self) -> bool { *self > 0 }
293 /// Returns true if the number is negative
295 fn is_negative(&self) -> bool { *self < 0 }
300 /// Floored integer division
305 /// assert!(( 8).div_floor( 3) == 2);
306 /// assert!(( 8).div_floor(-3) == -3);
307 /// assert!((-8).div_floor( 3) == -3);
308 /// assert!((-8).div_floor(-3) == 2);
310 /// assert!(( 1).div_floor( 2) == 0);
311 /// assert!(( 1).div_floor(-2) == -1);
312 /// assert!((-1).div_floor( 2) == -1);
313 /// assert!((-1).div_floor(-2) == 0);
317 fn div_floor(&self, other: &T) -> T {
318 // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
319 // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
320 match self.div_rem(other) {
321 (d, r) if (r > 0 && *other < 0)
322 || (r < 0 && *other > 0) => d - 1,
328 /// Integer modulo, satisfying:
331 /// assert!(n.div_floor(d) * d + n.mod_floor(d) == n)
337 /// assert!(( 8).mod_floor( 3) == 2);
338 /// assert!(( 8).mod_floor(-3) == -1);
339 /// assert!((-8).mod_floor( 3) == 1);
340 /// assert!((-8).mod_floor(-3) == -2);
342 /// assert!(( 1).mod_floor( 2) == 1);
343 /// assert!(( 1).mod_floor(-2) == -1);
344 /// assert!((-1).mod_floor( 2) == 1);
345 /// assert!((-1).mod_floor(-2) == -1);
349 fn mod_floor(&self, other: &T) -> T {
350 // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
351 // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
352 match *self % *other {
353 r if (r > 0 && *other < 0)
354 || (r < 0 && *other > 0) => r + *other,
359 /// Calculates `div_floor` and `mod_floor` simultaneously
361 fn div_mod_floor(&self, other: &T) -> (T,T) {
362 // Algorithm from [Daan Leijen. _Division and Modulus for Computer Scientists_,
363 // December 2001](http://research.microsoft.com/pubs/151917/divmodnote-letter.pdf)
364 match self.div_rem(other) {
365 (d, r) if (r > 0 && *other < 0)
366 || (r < 0 && *other > 0) => (d - 1, r + *other),
371 /// Calculates `div` (`\`) and `rem` (`%`) simultaneously
373 fn div_rem(&self, other: &T) -> (T,T) {
374 (*self / *other, *self % *other)
378 /// Calculates the Greatest Common Divisor (GCD) of the number and `other`
380 /// The result is always positive
383 fn gcd(&self, other: &T) -> T {
384 // Use Euclid's algorithm
385 let mut m = *self, n = *other;
395 /// Calculates the Lowest Common Multiple (LCM) of the number and `other`
398 fn lcm(&self, other: &T) -> T {
399 ((*self * *other) / self.gcd(other)).abs() // should not have to recaluculate abs
402 /// Returns `true` if the number can be divided by `other` without leaving a remainder
404 fn is_multiple_of(&self, other: &T) -> bool { *self % *other == 0 }
406 /// Returns `true` if the number is divisible by `2`
408 fn is_even(&self) -> bool { self.is_multiple_of(&2) }
410 /// Returns `true` if the number is not divisible by `2`
412 fn is_odd(&self) -> bool { !self.is_even() }
415 impl Bitwise for T {}
418 impl BitOr<T,T> for T {
420 fn bitor(&self, other: &T) -> T { *self | *other }
424 impl BitAnd<T,T> for T {
426 fn bitand(&self, other: &T) -> T { *self & *other }
430 impl BitXor<T,T> for T {
432 fn bitxor(&self, other: &T) -> T { *self ^ *other }
436 impl Shl<T,T> for T {
438 fn shl(&self, other: &T) -> T { *self << *other }
442 impl Shr<T,T> for T {
444 fn shr(&self, other: &T) -> T { *self >> *other }
450 fn not(&self) -> T { !*self }
455 fn min_value() -> T { min_value }
458 fn max_value() -> T { max_value }
463 // String conversion functions and impl str -> num
465 /// Parse a string as a number in base 10.
467 pub fn from_str(s: &str) -> Option<T> {
468 strconv::from_str_common(s, 10u, true, false, false,
469 strconv::ExpNone, false, false)
472 /// Parse a string as a number in the given base.
474 pub fn from_str_radix(s: &str, radix: uint) -> Option<T> {
475 strconv::from_str_common(s, radix, true, false, false,
476 strconv::ExpNone, false, false)
479 /// Parse a byte slice as a number in the given base.
481 pub fn parse_bytes(buf: &[u8], radix: uint) -> Option<T> {
482 strconv::from_str_bytes_common(buf, radix, true, false, false,
483 strconv::ExpNone, false, false)
488 fn from_str(s: &str) -> Option<T> {
493 impl FromStrRadix for T {
495 fn from_str_radix(s: &str, radix: uint) -> Option<T> {
496 from_str_radix(s, radix)
500 // String conversion functions and impl num -> str
502 /// Convert to a string as a byte slice in a given base.
504 pub fn to_str_bytes<U>(n: T, radix: uint, f: &fn(v: &[u8]) -> U) -> U {
505 let (buf, _) = strconv::to_str_bytes_common(&n, radix, false,
506 strconv::SignNeg, strconv::DigAll);
510 /// Convert to a string in base 10.
512 pub fn to_str(num: T) -> ~str {
513 let (buf, _) = strconv::to_str_common(&num, 10u, false,
514 strconv::SignNeg, strconv::DigAll);
518 /// Convert to a string in a given base.
520 pub fn to_str_radix(num: T, radix: uint) -> ~str {
521 let (buf, _) = strconv::to_str_common(&num, radix, false,
522 strconv::SignNeg, strconv::DigAll);
528 fn to_str(&self) -> ~str {
533 impl ToStrRadix for T {
535 fn to_str_radix(&self, radix: uint) -> ~str {
536 to_str_radix(*self, radix)
548 num::test_num(10 as T, 2 as T);
552 fn test_orderable() {
553 assert_eq!((1 as T).min(&(2 as T)), 1 as T);
554 assert_eq!((2 as T).min(&(1 as T)), 1 as T);
555 assert_eq!((1 as T).max(&(2 as T)), 2 as T);
556 assert_eq!((2 as T).max(&(1 as T)), 2 as T);
557 assert_eq!((1 as T).clamp(&(2 as T), &(4 as T)), 2 as T);
558 assert_eq!((8 as T).clamp(&(2 as T), &(4 as T)), 4 as T);
559 assert_eq!((3 as T).clamp(&(2 as T), &(4 as T)), 3 as T);
563 pub fn test_signed() {
564 assert_eq!((1 as T).abs(), 1 as T);
565 assert_eq!((0 as T).abs(), 0 as T);
566 assert_eq!((-1 as T).abs(), 1 as T);
568 assert_eq!((1 as T).signum(), 1 as T);
569 assert_eq!((0 as T).signum(), 0 as T);
570 assert_eq!((-0 as T).signum(), 0 as T);
571 assert_eq!((-1 as T).signum(), -1 as T);
573 assert!((1 as T).is_positive());
574 assert!(!(0 as T).is_positive());
575 assert!(!(-0 as T).is_positive());
576 assert!(!(-1 as T).is_positive());
578 assert!(!(1 as T).is_negative());
579 assert!(!(0 as T).is_negative());
580 assert!(!(-0 as T).is_negative());
581 assert!((-1 as T).is_negative());
585 /// Checks that the division rule holds for:
587 /// - `n`: numerator (dividend)
588 /// - `d`: denominator (divisor)
589 /// - `qr`: quotient and remainder
592 fn test_division_rule((n,d): (T,T), (q,r): (T,T)) {
593 assert_eq!(d * q + r, n);
598 fn test_nd_dr(nd: (T,T), qr: (T,T)) {
600 let separate_div_rem = (n / d, n % d);
601 let combined_div_rem = n.div_rem(&d);
603 assert_eq!(separate_div_rem, qr);
604 assert_eq!(combined_div_rem, qr);
606 test_division_rule(nd, separate_div_rem);
607 test_division_rule(nd, combined_div_rem);
610 test_nd_dr(( 8, 3), ( 2, 2));
611 test_nd_dr(( 8, -3), (-2, 2));
612 test_nd_dr((-8, 3), (-2, -2));
613 test_nd_dr((-8, -3), ( 2, -2));
615 test_nd_dr(( 1, 2), ( 0, 1));
616 test_nd_dr(( 1, -2), ( 0, 1));
617 test_nd_dr((-1, 2), ( 0, -1));
618 test_nd_dr((-1, -2), ( 0, -1));
622 fn test_div_mod_floor() {
623 fn test_nd_dm(nd: (T,T), dm: (T,T)) {
625 let separate_div_mod_floor = (n.div_floor(&d), n.mod_floor(&d));
626 let combined_div_mod_floor = n.div_mod_floor(&d);
628 assert_eq!(separate_div_mod_floor, dm);
629 assert_eq!(combined_div_mod_floor, dm);
631 test_division_rule(nd, separate_div_mod_floor);
632 test_division_rule(nd, combined_div_mod_floor);
635 test_nd_dm(( 8, 3), ( 2, 2));
636 test_nd_dm(( 8, -3), (-3, -1));
637 test_nd_dm((-8, 3), (-3, 1));
638 test_nd_dm((-8, -3), ( 2, -2));
640 test_nd_dm(( 1, 2), ( 0, 1));
641 test_nd_dm(( 1, -2), (-1, -1));
642 test_nd_dm((-1, 2), (-1, 1));
643 test_nd_dm((-1, -2), ( 0, -1));
648 assert_eq!((10 as T).gcd(&2), 2 as T);
649 assert_eq!((10 as T).gcd(&3), 1 as T);
650 assert_eq!((0 as T).gcd(&3), 3 as T);
651 assert_eq!((3 as T).gcd(&3), 3 as T);
652 assert_eq!((56 as T).gcd(&42), 14 as T);
653 assert_eq!((3 as T).gcd(&-3), 3 as T);
654 assert_eq!((-6 as T).gcd(&3), 3 as T);
655 assert_eq!((-4 as T).gcd(&-2), 2 as T);
660 assert_eq!((1 as T).lcm(&0), 0 as T);
661 assert_eq!((0 as T).lcm(&1), 0 as T);
662 assert_eq!((1 as T).lcm(&1), 1 as T);
663 assert_eq!((-1 as T).lcm(&1), 1 as T);
664 assert_eq!((1 as T).lcm(&-1), 1 as T);
665 assert_eq!((-1 as T).lcm(&-1), 1 as T);
666 assert_eq!((8 as T).lcm(&9), 72 as T);
667 assert_eq!((11 as T).lcm(&5), 55 as T);
672 assert_eq!(0b1110 as T, (0b1100 as T).bitor(&(0b1010 as T)));
673 assert_eq!(0b1000 as T, (0b1100 as T).bitand(&(0b1010 as T)));
674 assert_eq!(0b0110 as T, (0b1100 as T).bitxor(&(0b1010 as T)));
675 assert_eq!(0b1110 as T, (0b0111 as T).shl(&(1 as T)));
676 assert_eq!(0b0111 as T, (0b1110 as T).shr(&(1 as T)));
677 assert_eq!(-(0b11 as T) - (1 as T), (0b11 as T).not());
681 fn test_multiple_of() {
682 assert!((6 as T).is_multiple_of(&(6 as T)));
683 assert!((6 as T).is_multiple_of(&(3 as T)));
684 assert!((6 as T).is_multiple_of(&(1 as T)));
685 assert!((-8 as T).is_multiple_of(&(4 as T)));
686 assert!((8 as T).is_multiple_of(&(-1 as T)));
687 assert!((-8 as T).is_multiple_of(&(-2 as T)));
692 assert_eq!((-4 as T).is_even(), true);
693 assert_eq!((-3 as T).is_even(), false);
694 assert_eq!((-2 as T).is_even(), true);
695 assert_eq!((-1 as T).is_even(), false);
696 assert_eq!((0 as T).is_even(), true);
697 assert_eq!((1 as T).is_even(), false);
698 assert_eq!((2 as T).is_even(), true);
699 assert_eq!((3 as T).is_even(), false);
700 assert_eq!((4 as T).is_even(), true);
705 assert_eq!((-4 as T).is_odd(), false);
706 assert_eq!((-3 as T).is_odd(), true);
707 assert_eq!((-2 as T).is_odd(), false);
708 assert_eq!((-1 as T).is_odd(), true);
709 assert_eq!((0 as T).is_odd(), false);
710 assert_eq!((1 as T).is_odd(), true);
711 assert_eq!((2 as T).is_odd(), false);
712 assert_eq!((3 as T).is_odd(), true);
713 assert_eq!((4 as T).is_odd(), false);
718 assert_eq!((0b010101 as T).population_count(), 3);
722 fn test_primitive() {
723 assert_eq!(Primitive::bits::<T>(), sys::size_of::<T>() * 8);
724 assert_eq!(Primitive::bytes::<T>(), sys::size_of::<T>());
729 assert_eq!(from_str(~"0"), Some(0 as T));
730 assert_eq!(from_str(~"3"), Some(3 as T));
731 assert_eq!(from_str(~"10"), Some(10 as T));
732 assert_eq!(i32::from_str(~"123456789"), Some(123456789 as i32));
733 assert_eq!(from_str(~"00100"), Some(100 as T));
735 assert_eq!(from_str(~"-1"), Some(-1 as T));
736 assert_eq!(from_str(~"-3"), Some(-3 as T));
737 assert_eq!(from_str(~"-10"), Some(-10 as T));
738 assert_eq!(i32::from_str(~"-123456789"), Some(-123456789 as i32));
739 assert_eq!(from_str(~"-00100"), Some(-100 as T));
741 assert!(from_str(~" ").is_none());
742 assert!(from_str(~"x").is_none());
746 fn test_parse_bytes() {
748 assert_eq!(parse_bytes(to_bytes(~"123"), 10u), Some(123 as T));
749 assert_eq!(parse_bytes(to_bytes(~"1001"), 2u), Some(9 as T));
750 assert_eq!(parse_bytes(to_bytes(~"123"), 8u), Some(83 as T));
751 assert_eq!(i32::parse_bytes(to_bytes(~"123"), 16u), Some(291 as i32));
752 assert_eq!(i32::parse_bytes(to_bytes(~"ffff"), 16u), Some(65535 as i32));
753 assert_eq!(i32::parse_bytes(to_bytes(~"FFFF"), 16u), Some(65535 as i32));
754 assert_eq!(parse_bytes(to_bytes(~"z"), 36u), Some(35 as T));
755 assert_eq!(parse_bytes(to_bytes(~"Z"), 36u), Some(35 as T));
757 assert_eq!(parse_bytes(to_bytes(~"-123"), 10u), Some(-123 as T));
758 assert_eq!(parse_bytes(to_bytes(~"-1001"), 2u), Some(-9 as T));
759 assert_eq!(parse_bytes(to_bytes(~"-123"), 8u), Some(-83 as T));
760 assert_eq!(i32::parse_bytes(to_bytes(~"-123"), 16u), Some(-291 as i32));
761 assert_eq!(i32::parse_bytes(to_bytes(~"-ffff"), 16u), Some(-65535 as i32));
762 assert_eq!(i32::parse_bytes(to_bytes(~"-FFFF"), 16u), Some(-65535 as i32));
763 assert_eq!(parse_bytes(to_bytes(~"-z"), 36u), Some(-35 as T));
764 assert_eq!(parse_bytes(to_bytes(~"-Z"), 36u), Some(-35 as T));
766 assert!(parse_bytes(to_bytes(~"Z"), 35u).is_none());
767 assert!(parse_bytes(to_bytes(~"-9"), 2u).is_none());
772 assert_eq!(to_str_radix(0 as T, 10u), ~"0");
773 assert_eq!(to_str_radix(1 as T, 10u), ~"1");
774 assert_eq!(to_str_radix(-1 as T, 10u), ~"-1");
775 assert_eq!(to_str_radix(127 as T, 16u), ~"7f");
776 assert_eq!(to_str_radix(100 as T, 10u), ~"100");
781 fn test_int_to_str_overflow() {
782 let mut i8_val: i8 = 127_i8;
783 assert_eq!(i8::to_str(i8_val), ~"127");
786 assert_eq!(i8::to_str(i8_val), ~"-128");
788 let mut i16_val: i16 = 32_767_i16;
789 assert_eq!(i16::to_str(i16_val), ~"32767");
792 assert_eq!(i16::to_str(i16_val), ~"-32768");
794 let mut i32_val: i32 = 2_147_483_647_i32;
795 assert_eq!(i32::to_str(i32_val), ~"2147483647");
798 assert_eq!(i32::to_str(i32_val), ~"-2147483648");
800 let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
801 assert_eq!(i64::to_str(i64_val), ~"9223372036854775807");
804 assert_eq!(i64::to_str(i64_val), ~"-9223372036854775808");
808 fn test_int_from_str_overflow() {
809 let mut i8_val: i8 = 127_i8;
810 assert_eq!(i8::from_str(~"127"), Some(i8_val));
811 assert!(i8::from_str(~"128").is_none());
814 assert_eq!(i8::from_str(~"-128"), Some(i8_val));
815 assert!(i8::from_str(~"-129").is_none());
817 let mut i16_val: i16 = 32_767_i16;
818 assert_eq!(i16::from_str(~"32767"), Some(i16_val));
819 assert!(i16::from_str(~"32768").is_none());
822 assert_eq!(i16::from_str(~"-32768"), Some(i16_val));
823 assert!(i16::from_str(~"-32769").is_none());
825 let mut i32_val: i32 = 2_147_483_647_i32;
826 assert_eq!(i32::from_str(~"2147483647"), Some(i32_val));
827 assert!(i32::from_str(~"2147483648").is_none());
830 assert_eq!(i32::from_str(~"-2147483648"), Some(i32_val));
831 assert!(i32::from_str(~"-2147483649").is_none());
833 let mut i64_val: i64 = 9_223_372_036_854_775_807_i64;
834 assert_eq!(i64::from_str(~"9223372036854775807"), Some(i64_val));
835 assert!(i64::from_str(~"9223372036854775808").is_none());
838 assert_eq!(i64::from_str(~"-9223372036854775808"), Some(i64_val));
839 assert!(i64::from_str(~"-9223372036854775809").is_none());
849 for range_rev(13,10) |i| {
852 for range_step(20,26,2) |i| {
855 for range_step(36,30,-2) |i| {
858 for range_step(max_value - 2, max_value, 2) |i| {
861 for range_step(max_value - 3, max_value, 2) |i| {
864 for range_step(min_value + 2, min_value, -2) |i| {
867 for range_step(min_value + 3, min_value, -2) |i| {
870 assert_eq!(l, ~[0,1,2,
875 max_value-3,max_value-1,
877 min_value+3,min_value+1]);
879 // None of the `fail`s should execute.
880 for range(10,0) |_i| {
881 fail!(~"unreachable");
883 for range_rev(0,10) |_i| {
884 fail!(~"unreachable");
886 for range_step(10,0,1) |_i| {
887 fail!(~"unreachable");
889 for range_step(0,10,-1) |_i| {
890 fail!(~"unreachable");
896 #[ignore(cfg(windows))]
897 fn test_range_step_zero_step() {
898 for range_step(0,10,0) |_i| {}