@@ -69,34 +69,53 @@ pub pure fn is_nonpositive(x: T) -> bool { x <= 0 as T }
69
69
pub pure fn is_nonnegative ( x : T ) -> bool { x >= 0 as T }
70
70
71
71
#[ inline( always) ]
72
- /// Iterate over the range [`start`,`start`+`step`..`stop`)
73
- pub pure fn range_step ( start : T , stop : T , step : T , it : fn ( T ) -> bool ) {
72
+ /**
73
+ * Iterate over the range [`start`,`start`+`step`..`stop`)
74
+ *
75
+ * Note that `uint` requires separate `range_step` functions for each
76
+ * direction.
77
+ *
78
+ */
79
+ pub pure fn range_step_up ( start : T , stop : T , step : T , it : fn ( T ) -> bool ) {
74
80
let mut i = start;
75
81
if step == 0 {
76
- fail ~"range_step called with step == 0 ";
77
- } else if step > 0 { // ascending
78
- while i < stop {
79
- if !it ( i) { break }
80
- i += step;
81
- }
82
- } else { // descending
83
- while i > stop {
84
- if !it ( i) { break }
85
- i += step;
86
- }
82
+ fail ~"range_step_up called with step == 0 ";
83
+ }
84
+ while i < stop {
85
+ if !it ( i) { break }
86
+ i += step;
87
+ }
88
+ }
89
+
90
+ #[ inline( always) ]
91
+ /**
92
+ * Iterate over the range [`start`,`start`-`step`..`stop`)
93
+ *
94
+ * Note that `uint` requires separate `range_step` functions for each
95
+ * direction.
96
+ *
97
+ */
98
+ pub pure fn range_step_down ( start : T , stop : T , step : T , it : fn ( T ) -> bool ) {
99
+ let mut i = start;
100
+ if step == 0 {
101
+ fail ~"range_step_down called with step == 0 ";
102
+ }
103
+ while i > stop {
104
+ if !it ( i) { break }
105
+ i -= step;
87
106
}
88
107
}
89
108
90
109
#[ inline( always) ]
91
110
/// Iterate over the range [`lo`..`hi`)
92
111
pub pure fn range ( lo : T , hi : T , it : fn ( T ) -> bool ) {
93
- range_step ( lo, hi, 1 as T , it) ;
112
+ range_step_up ( lo, hi, 1 as T , it) ;
94
113
}
95
114
96
115
#[ inline( always) ]
97
116
/// Iterate over the range [`hi`..`lo`)
98
117
pub pure fn range_rev ( hi : T , lo : T , it : fn ( T ) -> bool ) {
99
- range_step ( hi, lo, - 1 as T , it) ;
118
+ range_step_down ( hi, lo, 1 as T , it) ;
100
119
}
101
120
102
121
/// Computes the bitwise complement
@@ -351,3 +370,51 @@ pub fn test_times() {
351
370
for ten. times { accum += 1 ; }
352
371
assert ( accum == 10 ) ;
353
372
}
373
+ use io;
374
+ #[ test]
375
+ pub fn test_ranges ( ) {
376
+ let mut l = ~[ ] ;
377
+
378
+ for range( 0 , 3 ) |i| {
379
+ l. push ( i) ;
380
+ }
381
+ for range_rev( 13 , 10 ) |i| {
382
+ l. push ( i) ;
383
+ }
384
+ for range_step_up( 20 , 26 , 2 ) |i| {
385
+ l. push ( i) ;
386
+ }
387
+ for range_step_down( 36 , 30 , 2 ) |i| {
388
+ l. push ( i) ;
389
+ }
390
+
391
+ assert l == ~[ 0 , 1 , 2 ,
392
+ 13 , 12 , 11 ,
393
+ 20 , 22 , 24 ,
394
+ 36 , 34 , 32 ] ;
395
+
396
+ // None of the `fail`s should execute.
397
+ for range( 0 , 0 ) |_i| {
398
+ fail ~"unreachable";
399
+ }
400
+ for range_rev( 0 , 0 ) |_i| {
401
+ fail ~"unreachable";
402
+ }
403
+ for range_step_up( 10 , 0 , 1 ) |_i| {
404
+ fail ~"unreachable";
405
+ }
406
+ for range_step_down( 0 , 10 , 1 ) |_i| {
407
+ fail ~"unreachable";
408
+ }
409
+ }
410
+
411
+ #[ test]
412
+ #[ should_fail]
413
+ fn test_range_step_up_zero_step( ) {
414
+ for range_step_up( 0 , 10 , 0 ) |_i| { }
415
+ }
416
+ #[ test]
417
+ #[ should_fail]
418
+ fn test_range_step_down_zero_step( ) {
419
+ for range_step_down( 0 , 10 , 0 ) |_i| { }
420
+ }
0 commit comments