diff options
Diffstat (limited to 'src/libcore')
| -rw-r--r-- | src/libcore/core.rs | 22 | ||||
| -rw-r--r-- | src/libcore/int-template.rs | 35 | ||||
| -rw-r--r-- | src/libcore/iter.rs | 4 | ||||
| -rw-r--r-- | src/libcore/uint-template.rs | 26 |
4 files changed, 74 insertions, 13 deletions
diff --git a/src/libcore/core.rs b/src/libcore/core.rs index f97d2727194..e70a092d876 100644 --- a/src/libcore/core.rs +++ b/src/libcore/core.rs @@ -12,16 +12,16 @@ import option_iter::extensions; import ptr::extensions; import rand::extensions; import result::extensions; -import int::num; -import i8::num; -import i16::num; -import i32::num; -import i64::num; -import uint::num; -import u8::num; -import u16::num; -import u32::num; -import u64::num; +import int::{num, times}; +import i8::{num, times}; +import i16::{num, times}; +import i32::{num, times}; +import i64::{num, times}; +import uint::{num, times}; +import u8::{num, times}; +import u16::{num, times}; +import u32::{num, times}; +import u64::{num, times}; import float::num; import f32::num; import f64::num; @@ -29,7 +29,7 @@ import f64::num; export path, option, some, none, unreachable; export extensions; // The following exports are the extension impls for numeric types -export num; +export num, times; // Export the log levels as global constants. Higher levels mean // more-verbosity. Error is the bottom level, default logging level is diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs index 407b810e95d..5c5cffb2ac1 100644 --- a/src/libcore/int-template.rs +++ b/src/libcore/int-template.rs @@ -11,7 +11,7 @@ export range; export compl; export abs; export parse_buf, from_str, to_str, to_str_bytes, str; -export num, ord, eq; +export num, ord, eq, times; const min_value: T = -1 as T << (inst::bits - 1 as T); const max_value: T = min_value - 1 as T; @@ -135,6 +135,25 @@ impl num of num::num for T { fn from_int(n: int) -> T { ret n as T; } } +impl times of iter::times for T { + #[inline(always)] + #[doc = "A convenience form for basic iteration. Given a variable `x` \ + of any numeric type, the expression `for x.times { /* anything */ }` \ + will execute the given function exactly x times. If we assume that \ + `x` is an int, this is functionally equivalent to \ + `for int::range(0, x) |_i| { /* anything */ }`."] + fn times(it: fn() -> bool) { + if self < 0 { + fail #fmt("The .times method expects a nonnegative number, \ + but found %?", self); + } + let mut i = self; + while i > 0 { + if !it() { break } + i -= 1; + } + } +} // FIXME: Has alignment issues on windows and 32-bit linux (#2609) #[test] @@ -206,8 +225,22 @@ fn test_ifaces() { assert (ten.mul(two) == ten.from_int(20)); assert (ten.div(two) == ten.from_int(5)); assert (ten.modulo(two) == ten.from_int(0)); + assert (ten.neg() == ten.from_int(-10)); } test(10 as T); } +#[test] +fn test_times() { + let ten = 10 as T; + let mut accum = 0; + for ten.times { accum += 1; } + assert (accum == 10); +} + +#[test] +#[should_fail] +fn test_times_negative() { + for (-10).times { log(error, "nope!"); } +} diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 0280221ebfc..55d47cfe75d 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -3,6 +3,10 @@ iface base_iter<A> { fn size_hint() -> option<uint>; } +iface times { + fn times(it: fn() -> bool); +} + fn eachi<A,IA:base_iter<A>>(self: IA, blk: fn(uint, A) -> bool) { let mut i = 0u; for self.each |a| { diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs index 91b9eb856e4..0433cd7ce30 100644 --- a/src/libcore/uint-template.rs +++ b/src/libcore/uint-template.rs @@ -11,7 +11,7 @@ export range; export compl; export to_str, to_str_bytes; export from_str, from_str_radix, str, parse_buf; -export num, ord, eq; +export num, ord, eq, times; const min_value: T = 0 as T; const max_value: T = 0 as T - 1 as T; @@ -104,6 +104,22 @@ fn parse_buf(buf: ~[u8], radix: uint) -> option<T> { }; } +impl times of iter::times for T { + #[inline(always)] + #[doc = "A convenience form for basic iteration. Given a variable `x` \ + of any numeric type, the expression `for x.times { /* anything */ }` \ + will execute the given function exactly x times. If we assume that \ + `x` is an int, this is functionally equivalent to \ + `for int::range(0, x) |_i| { /* anything */ }`."] + fn times(it: fn() -> bool) { + let mut i = self; + while i > 0 { + if !it() { break } + i -= 1; + } + } +} + /// Parse a string to an int fn from_str(s: str) -> option<T> { parse_buf(str::bytes(s), 10u) } @@ -259,3 +275,11 @@ fn to_str_radix1() { fn to_str_radix17() { uint::to_str(100u, 17u); } + +#[test] +fn test_times() { + let ten = 10 as T; + let mut accum = 0; + for ten.times { accum += 1; } + assert (accum == 10); +} |
