From d162fa26ba014dcb20e41e31e9c7f969301f532c Mon Sep 17 00:00:00 2001 From: Ben Striegel Date: Thu, 5 Jul 2012 22:12:26 -0400 Subject: A new `times` method on numeric types This method is intended to elegantly subsume two common iteration functions. The first is `iter::range`, which is used identically to the method introduced in this commit, but currently works only on uints. The second is a common case of `{int, i8, uint, etc.}::range`, in the case where the inductive variable is ignored. Compare the usage of the three: ``` for iter::range(100u) { // do whatever } for int::range(0, 100) |_i| { // do whatever } for 100.times { // do whatever } ``` I feel that the latter reads much more nicely than the first two approaches, and unlike the first two the new method allows the user to ignore the specific type of the number (ineed, if we're throwing away the inductive variable, who cares what type it is?). A minor benefit is that this new method will be somewhat familiar to users of Ruby, from which we borrow the name "times". --- src/libcore/uint-template.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'src/libcore/uint-template.rs') 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 { }; } +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 { 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); +} -- cgit 1.4.1-3-g733a5