Skip to content

Commit 3e8a762

Browse files
committed
Don’t reset RangeInclusive to 1...0 after last iteration.
Instead try to set start to end+1, and if that overflows set end to start-1.
1 parent d103522 commit 3e8a762

File tree

2 files changed

+59
-75
lines changed

2 files changed

+59
-75
lines changed

src/libcore/iter/range.rs

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,34 +30,13 @@ pub trait Step: Clone + PartialOrd + Sized {
3030
/// without overflow.
3131
fn steps_between(start: &Self, end: &Self) -> Option<usize>;
3232

33-
/// Replaces this step with `1`, returning itself
34-
fn replace_one(&mut self) -> Self;
35-
36-
/// Replaces this step with `0`, returning itself
37-
fn replace_zero(&mut self) -> Self;
38-
3933
/// Add an usize, returning None on overflow
4034
fn add_usize(&self, n: usize) -> Option<Self>;
4135

4236
/// Subtracts an usize, returning None on overflow
4337
fn sub_usize(&self, n: usize) -> Option<Self>;
4438
}
4539

46-
// These are still macro-generated because the integer literals resolve to different types.
47-
macro_rules! step_identical_methods {
48-
() => {
49-
#[inline]
50-
fn replace_one(&mut self) -> Self {
51-
mem::replace(self, 1)
52-
}
53-
54-
#[inline]
55-
fn replace_zero(&mut self) -> Self {
56-
mem::replace(self, 0)
57-
}
58-
}
59-
}
60-
6140
macro_rules! step_impl_unsigned {
6241
($($t:ty)*) => ($(
6342
#[unstable(feature = "step_trait",
@@ -90,8 +69,6 @@ macro_rules! step_impl_unsigned {
9069
Err(_) => None,
9170
}
9271
}
93-
94-
step_identical_methods!();
9572
}
9673
)*)
9774
}
@@ -148,8 +125,6 @@ macro_rules! step_impl_signed {
148125
Err(_) => None,
149126
}
150127
}
151-
152-
step_identical_methods!();
153128
}
154129
)*)
155130
}
@@ -174,8 +149,6 @@ macro_rules! step_impl_no_between {
174149
fn sub_usize(&self, n: usize) -> Option<Self> {
175150
self.checked_sub(n as $t)
176151
}
177-
178-
step_identical_methods!();
179152
}
180153
)*)
181154
}
@@ -338,8 +311,15 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
338311
Some(mem::replace(&mut self.start, n))
339312
},
340313
Some(Equal) => {
341-
let last = self.start.replace_one();
342-
self.end.replace_zero();
314+
let last;
315+
if let Some(end_plus_one) = self.end.add_usize(1) {
316+
last = mem::replace(&mut self.start, end_plus_one);
317+
} else {
318+
last = self.start.clone();
319+
// `start == end`, and `end + 1` underflowed.
320+
// `start - 1` overflowing would imply a type with only one valid value?
321+
self.end = self.start.sub_usize(1).expect("overflow in RangeInclusive::next");
322+
}
343323
Some(last)
344324
},
345325
_ => None,
@@ -370,16 +350,26 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
370350
return Some(plus_n)
371351
}
372352
Some(Equal) => {
373-
self.start.replace_one();
374-
self.end.replace_zero();
353+
if let Some(end_plus_one) = self.end.add_usize(1) {
354+
self.start = end_plus_one
355+
} else {
356+
// `start == end`, and `end + 1` underflowed.
357+
// `start - 1` overflowing would imply a type with only one valid value?
358+
self.end = self.start.sub_usize(1).expect("overflow in RangeInclusive::nth")
359+
}
375360
return Some(plus_n)
376361
}
377362
_ => {}
378363
}
379364
}
380365

381-
self.start.replace_one();
382-
self.end.replace_zero();
366+
if let Some(end_plus_one) = self.end.add_usize(1) {
367+
self.start = end_plus_one
368+
} else {
369+
// `start == end`, and `end + 1` underflowed.
370+
// `start - 1` overflowing would imply a type with only one valid value?
371+
self.end = self.start.sub_usize(1).expect("overflow in RangeInclusive::nth")
372+
}
383373
None
384374
}
385375
}
@@ -397,8 +387,15 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
397387
Some(mem::replace(&mut self.end, n))
398388
},
399389
Some(Equal) => {
400-
let last = self.end.replace_zero();
401-
self.start.replace_one();
390+
let last;
391+
if let Some(start_minus_one) = self.start.sub_usize(1) {
392+
last = mem::replace(&mut self.end, start_minus_one);
393+
} else {
394+
last = self.end.clone();
395+
// `start == end`, and `start - 1` underflowed.
396+
// `end + 1` overflowing would imply a type with only one valid value?
397+
self.start = self.start.add_usize(1).expect("overflow in RangeInclusive::next_back");
398+
}
402399
Some(last)
403400
},
404401
_ => None,

src/libcore/tests/iter.rs

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,20 +1080,41 @@ fn test_range() {
10801080
fn test_range_inclusive_exhaustion() {
10811081
let mut r = 10...10;
10821082
assert_eq!(r.next(), Some(10));
1083-
assert_eq!(r, 1...0);
1083+
assert_eq!(r, 11...10);
1084+
assert_eq!(r.next(), None);
1085+
assert_eq!(r, 11...10);
10841086

10851087
let mut r = 10...10;
10861088
assert_eq!(r.next_back(), Some(10));
1089+
assert_eq!(r, 10...9);
1090+
assert_eq!(r.next_back(), None);
1091+
assert_eq!(r, 10...9);
1092+
1093+
let mut r = 0_u32...0;
1094+
assert_eq!(r.next_back(), Some(0));
1095+
assert_eq!(r, 1...0);
1096+
assert_eq!(r.next_back(), None);
10871097
assert_eq!(r, 1...0);
10881098

10891099
let mut r = 10...12;
10901100
assert_eq!(r.nth(2), Some(12));
1091-
assert_eq!(r, 1...0);
1101+
assert_eq!(r, 13...12);
10921102

10931103
let mut r = 10...12;
10941104
assert_eq!(r.nth(5), None);
1095-
assert_eq!(r, 1...0);
1105+
assert_eq!(r, 13...12);
1106+
1107+
let mut r = 127_i8...127;
1108+
assert_eq!(r.next(), Some(127));
1109+
assert_eq!(r, 127...126);
1110+
assert_eq!(r.next(), None);
1111+
assert_eq!(r, 127...126);
10961112

1113+
let mut r = 255_u8...255;
1114+
assert_eq!(r.next(), Some(255));
1115+
assert_eq!(r, 255...254);
1116+
assert_eq!(r.next(), None);
1117+
assert_eq!(r, 255...254);
10971118
}
10981119

10991120
#[test]
@@ -1142,7 +1163,7 @@ fn test_range_inclusive_nth() {
11421163
assert_eq!(r.is_empty(), false);
11431164
assert_eq!(r.nth(10), None);
11441165
assert_eq!(r.is_empty(), true);
1145-
assert_eq!(r, 1...0); // We may not want to document/promise this detail
1166+
assert_eq!(r, 21...20);
11461167
}
11471168

11481169
#[test]
@@ -1263,40 +1284,6 @@ fn test_chain_fold() {
12631284
}
12641285

12651286
#[test]
1266-
fn test_step_replace_unsigned() {
1267-
let mut x = 4u32;
1268-
let y = x.replace_zero();
1269-
assert_eq!(x, 0);
1270-
assert_eq!(y, 4);
1271-
1272-
x = 5;
1273-
let y = x.replace_one();
1274-
assert_eq!(x, 1);
1275-
assert_eq!(y, 5);
1276-
}
1277-
1278-
#[test]
1279-
fn test_step_replace_signed() {
1280-
let mut x = 4i32;
1281-
let y = x.replace_zero();
1282-
assert_eq!(x, 0);
1283-
assert_eq!(y, 4);
1284-
1285-
x = 5;
1286-
let y = x.replace_one();
1287-
assert_eq!(x, 1);
1288-
assert_eq!(y, 5);
1289-
}
1290-
1291-
#[test]
1292-
fn test_step_replace_no_between() {
1293-
let mut x = 4u128;
1294-
let y = x.replace_zero();
1295-
assert_eq!(x, 0);
1296-
assert_eq!(y, 4);
1297-
1298-
x = 5;
1299-
let y = x.replace_one();
1300-
assert_eq!(x, 1);
1301-
assert_eq!(y, 5);
1287+
fn test_step_add_usize() {
1288+
assert_eq!((-120_i8).add_usize(200), Some(80));
13021289
}

0 commit comments

Comments
 (0)