1
Fork 0

Add a T_SIGNED type to uint template and eliminate step_down variant

Handle negative steps properly in range_step, fix order of arguments
in tests, and such.
This commit is contained in:
Tim Chevalier 2013-01-23 15:08:47 -08:00
parent 1a6e1e2801
commit 982cf90dc6
6 changed files with 33 additions and 36 deletions

View file

@ -13,6 +13,7 @@
#[forbid(deprecated_pattern)]; #[forbid(deprecated_pattern)];
use T = self::inst::T; use T = self::inst::T;
use T_SIGNED = self::inst::T_SIGNED;
use char; use char;
use cmp::{Eq, Ord}; use cmp::{Eq, Ord};
@ -72,50 +73,36 @@ pub pure fn is_nonnegative(x: T) -> bool { x >= 0 as T }
/** /**
* Iterate over the range [`start`,`start`+`step`..`stop`) * Iterate over the range [`start`,`start`+`step`..`stop`)
* *
* Note that `uint` requires separate `range_step` functions for each
* direction.
*
*/ */
pub pure fn range_step_up(start: T, stop: T, step: T, it: fn(T) -> bool) { pub pure fn range_step(start: T, stop: T, step: T_SIGNED, it: fn(T) -> bool) {
let mut i = start; let mut i = start;
if step == 0 { if step == 0 {
fail ~"range_step_up called with step == 0"; fail ~"range_step called with step == 0";
} }
while i < stop { if step >= 0 {
if !it(i) { break } while i < stop {
i += step; if !it(i) { break }
i += step as T;
}
} }
} else {
while i > stop {
#[inline(always)] if !it(i) { break }
/** i -= -step as T;
* Iterate over the range [`start`,`start`-`step`..`stop`) }
*
* Note that `uint` requires separate `range_step` functions for each
* direction.
*
*/
pub pure fn range_step_down(start: T, stop: T, step: T, it: fn(T) -> bool) {
let mut i = start;
if step == 0 {
fail ~"range_step_down called with step == 0";
}
while i > stop {
if !it(i) { break }
i -= step;
} }
} }
#[inline(always)] #[inline(always)]
/// Iterate over the range [`lo`..`hi`) /// Iterate over the range [`lo`..`hi`)
pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) { pub pure fn range(lo: T, hi: T, it: fn(T) -> bool) {
range_step_up(lo, hi, 1 as T, it); range_step(lo, hi, 1 as T_SIGNED, it);
} }
#[inline(always)] #[inline(always)]
/// Iterate over the range [`hi`..`lo`) /// Iterate over the range [`hi`..`lo`)
pub pure fn range_rev(hi: T, lo: T, it: fn(T) -> bool) { pub pure fn range_rev(hi: T, lo: T, it: fn(T) -> bool) {
range_step_down(hi, lo, 1 as T, it); range_step(hi, lo, -1 as T_SIGNED, it);
} }
/// Computes the bitwise complement /// Computes the bitwise complement
@ -381,10 +368,10 @@ pub fn test_ranges() {
for range_rev(13,10) |i| { for range_rev(13,10) |i| {
l.push(i); l.push(i);
} }
for range_step_up(20,26,2) |i| { for range_step(20,26,2) |i| {
l.push(i); l.push(i);
} }
for range_step_down(36,30,2) |i| { for range_step(36,30,-2) |i| {
l.push(i); l.push(i);
} }
@ -400,21 +387,21 @@ pub fn test_ranges() {
for range_rev(0,0) |_i| { for range_rev(0,0) |_i| {
fail ~"unreachable"; fail ~"unreachable";
} }
for range_step_up(10,0,1) |_i| { for range_step(10,0,1) |_i| {
fail ~"unreachable"; fail ~"unreachable";
} }
for range_step_down(0,10,1) |_i| { for range_step(0,1,-10) |_i| {
fail ~"unreachable"; fail ~"unreachable";
} }
} }
#[test] #[test]
#[should_fail] #[should_fail]
fn test_range_step_up_zero_step() { fn test_range_step_zero_step_up() {
for range_step_up(0,10,0) |_i| {} for range_step(0,10,0) |_i| {}
} }
#[test] #[test]
#[should_fail] #[should_fail]
fn test_range_step_down_zero_step() { fn test_range_step_zero_step_down() {
for range_step_down(0,10,0) |_i| {} for range_step(0,-10,0) |_i| {}
} }

View file

@ -12,5 +12,7 @@
mod inst { mod inst {
pub type T = u16; pub type T = u16;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i16;
pub const bits: uint = 16; pub const bits: uint = 16;
} }

View file

@ -12,5 +12,7 @@
mod inst { mod inst {
pub type T = u32; pub type T = u32;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i32;
pub const bits: uint = 32; pub const bits: uint = 32;
} }

View file

@ -12,5 +12,7 @@
mod inst { mod inst {
pub type T = u64; pub type T = u64;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i64;
pub const bits: uint = 64; pub const bits: uint = 64;
} }

View file

@ -14,6 +14,8 @@ pub use self::inst::is_ascii;
mod inst { mod inst {
pub type T = u8; pub type T = u8;
#[allow(non_camel_case_types)]
pub type T_SIGNED = i8;
pub const bits: uint = 8; pub const bits: uint = 8;
// Type-specific functions here. These must be reexported by the // Type-specific functions here. These must be reexported by the

View file

@ -20,6 +20,8 @@ mod inst {
use uint; use uint;
pub type T = uint; pub type T = uint;
#[allow(non_camel_case_types)]
pub type T_SIGNED = int;
#[cfg(target_arch = "x86")] #[cfg(target_arch = "x86")]
#[cfg(target_arch = "arm")] #[cfg(target_arch = "arm")]