get rid of implicit vec copies in treemap iterator
Each call to next() was doing a copy rather than a move. There's currently no way for this to be a method that uses &mut self, so it has to be a free function. Closes #4763.
This commit is contained in:
parent
5b6c26b4e4
commit
37e998696f
@ -49,8 +49,8 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: Eq {
|
||||
let mut y = other.iter();
|
||||
for self.len().times {
|
||||
unsafe { // unsafe as a purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
map_next(&mut x);
|
||||
map_next(&mut y);
|
||||
// FIXME: #4492 (ICE), x.get() == y.get()
|
||||
let (x1, x2) = x.get().unwrap();
|
||||
let (y1, y2) = y.get().unwrap();
|
||||
@ -74,8 +74,8 @@ impl <K: Eq Ord, V: Eq> TreeMap<K, V>: Eq {
|
||||
let (a_len, b_len) = (a.len(), b.len());
|
||||
for uint::min(a_len, b_len).times {
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
map_next(&mut x);
|
||||
map_next(&mut y);
|
||||
let (key_a,_) = x.get().unwrap();
|
||||
let (key_b,_) = y.get().unwrap();
|
||||
if *key_a < *key_b { return true; }
|
||||
@ -214,28 +214,26 @@ fn get(&const self) -> Option<(&self/K, &self/V)> {
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Advance the iterator to the next node (in order). If this iterator
|
||||
/// is finished, does nothing.
|
||||
fn next(self) -> TreeMapIterator/&self<K, V> {
|
||||
let mut this = self;
|
||||
while !this.stack.is_empty() || this.node.is_some() {
|
||||
match *this.node {
|
||||
/// Advance the iterator to the next node (in order). If this iterator
|
||||
/// is finished, does nothing.
|
||||
fn map_next<K: Ord, V>(iter: &mut TreeMapIterator/&a<K, V>) {
|
||||
while !iter.stack.is_empty() || iter.node.is_some() {
|
||||
match *iter.node {
|
||||
Some(ref x) => {
|
||||
this.stack.push(x);
|
||||
this.node = &x.left;
|
||||
iter.stack.push(x);
|
||||
iter.node = &x.left;
|
||||
}
|
||||
None => {
|
||||
let res = this.stack.pop();
|
||||
this.node = &res.right;
|
||||
this.current = Some(res);
|
||||
return this;
|
||||
let res = iter.stack.pop();
|
||||
iter.node = &res.right;
|
||||
iter.current = Some(res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.current = None;
|
||||
return this;
|
||||
}
|
||||
iter.current = None;
|
||||
}
|
||||
|
||||
pub struct TreeSet<T> {
|
||||
@ -297,18 +295,18 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let mut x = self.iter();
|
||||
let mut y = other.iter();
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
set_next(&mut x);
|
||||
set_next(&mut y);
|
||||
let mut a = x.get();
|
||||
let mut b = y.get();
|
||||
while a.is_some() && b.is_some() {
|
||||
let a1 = a.unwrap();
|
||||
let b1 = b.unwrap();
|
||||
if a1 < b1 {
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
} else if b1 < a1 {
|
||||
y = y.next();
|
||||
set_next(&mut y);
|
||||
b = y.get();
|
||||
} else {
|
||||
return false;
|
||||
@ -328,8 +326,8 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let mut x = self.iter();
|
||||
let mut y = other.iter();
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
set_next(&mut x);
|
||||
set_next(&mut y);
|
||||
let mut a = x.get();
|
||||
let mut b = y.get();
|
||||
while b.is_some() {
|
||||
@ -345,10 +343,10 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
}
|
||||
|
||||
if !(a1 < b1) {
|
||||
y = y.next();
|
||||
set_next(&mut y);
|
||||
b = y.get();
|
||||
}
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
}
|
||||
}
|
||||
@ -361,15 +359,15 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let mut y = other.iter();
|
||||
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
set_next(&mut x);
|
||||
set_next(&mut y);
|
||||
let mut a = x.get();
|
||||
let mut b = y.get();
|
||||
|
||||
while a.is_some() {
|
||||
if b.is_none() {
|
||||
return do a.while_some() |a1| {
|
||||
if f(a1) { x = x.next(); x.get() } else { None }
|
||||
if f(a1) { set_next(&mut x); x.get() } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,11 +376,11 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
|
||||
if a1 < b1 {
|
||||
if !f(a1) { return }
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
} else {
|
||||
if !(b1 < a1) { x = x.next(); a = x.get() }
|
||||
y = y.next();
|
||||
if !(b1 < a1) { set_next(&mut x); a = x.get() }
|
||||
set_next(&mut y);
|
||||
b = y.get();
|
||||
}
|
||||
}
|
||||
@ -396,15 +394,15 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let mut y = other.iter();
|
||||
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
set_next(&mut x);
|
||||
set_next(&mut y);
|
||||
let mut a = x.get();
|
||||
let mut b = y.get();
|
||||
|
||||
while a.is_some() {
|
||||
if b.is_none() {
|
||||
return do a.while_some() |a1| {
|
||||
if f(a1) { x.next(); x.get() } else { None }
|
||||
if f(a1) { set_next(&mut x); x.get() } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,21 +411,21 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
|
||||
if a1 < b1 {
|
||||
if !f(a1) { return }
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
} else {
|
||||
if b1 < a1 {
|
||||
if !f(b1) { return }
|
||||
} else {
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
}
|
||||
y = y.next();
|
||||
set_next(&mut y);
|
||||
b = y.get();
|
||||
}
|
||||
}
|
||||
do b.while_some |b1| {
|
||||
if f(b1) { y = y.next(); y.get() } else { None }
|
||||
if f(b1) { set_next(&mut y); y.get() } else { None }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -438,8 +436,8 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let mut y = other.iter();
|
||||
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
set_next(&mut x);
|
||||
set_next(&mut y);
|
||||
let mut a = x.get();
|
||||
let mut b = y.get();
|
||||
|
||||
@ -447,13 +445,13 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let a1 = a.unwrap();
|
||||
let b1 = b.unwrap();
|
||||
if a1 < b1 {
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
} else {
|
||||
if !(b1 < a1) {
|
||||
if !f(a1) { return }
|
||||
}
|
||||
y = y.next();
|
||||
set_next(&mut y);
|
||||
b = y.get();
|
||||
}
|
||||
}
|
||||
@ -466,15 +464,15 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
let mut y = other.iter();
|
||||
|
||||
unsafe { // purity workaround
|
||||
x = x.next();
|
||||
y = y.next();
|
||||
set_next(&mut x);
|
||||
set_next(&mut y);
|
||||
let mut a = x.get();
|
||||
let mut b = y.get();
|
||||
|
||||
while a.is_some() {
|
||||
if b.is_none() {
|
||||
return do a.while_some() |a1| {
|
||||
if f(a1) { x = x.next(); x.get() } else { None }
|
||||
if f(a1) { set_next(&mut x); x.get() } else { None }
|
||||
}
|
||||
}
|
||||
|
||||
@ -483,15 +481,15 @@ fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
|
||||
|
||||
if b1 < a1 {
|
||||
if !f(b1) { return }
|
||||
y = y.next();
|
||||
set_next(&mut y);
|
||||
b = y.get();
|
||||
} else {
|
||||
if !f(a1) { return }
|
||||
if !(a1 < b1) {
|
||||
y = y.next();
|
||||
set_next(&mut y);
|
||||
b = y.get()
|
||||
}
|
||||
x = x.next();
|
||||
set_next(&mut x);
|
||||
a = x.get();
|
||||
}
|
||||
}
|
||||
@ -528,12 +526,12 @@ fn get(&const self) -> Option<&self/T> {
|
||||
Some((k, _)) => Some(k)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Advance the iterator to the next node (in order). If this iterator is
|
||||
/// finished, does nothing.
|
||||
fn next(self) -> TreeSetIterator/&self<T> {
|
||||
TreeSetIterator { iter: self.iter.next() }
|
||||
}
|
||||
/// Advance the iterator to the next node (in order). If this iterator is
|
||||
/// finished, does nothing.
|
||||
fn set_next<T: Ord>(iter: &mut TreeSetIterator/&a<T>) {
|
||||
map_next(&mut iter.iter);
|
||||
}
|
||||
|
||||
// Nodes keep track of their level in the tree, starting at 1 in the
|
||||
@ -967,18 +965,18 @@ fn test_lazy_iterator() {
|
||||
|
||||
// FIXME: #4492 (ICE): iter.next() == Some((&x1, &y1))
|
||||
|
||||
iter = iter.next();
|
||||
map_next(&mut iter);
|
||||
assert iter.get().unwrap() == (&x1, &y1);
|
||||
iter = iter.next();
|
||||
map_next(&mut iter);
|
||||
assert iter.get().unwrap() == (&x2, &y2);
|
||||
iter = iter.next();
|
||||
map_next(&mut iter);
|
||||
assert iter.get().unwrap() == (&x3, &y3);
|
||||
iter = iter.next();
|
||||
map_next(&mut iter);
|
||||
assert iter.get().unwrap() == (&x4, &y4);
|
||||
iter = iter.next();
|
||||
map_next(&mut iter);
|
||||
assert iter.get().unwrap() == (&x5, &y5);
|
||||
|
||||
iter = iter.next();
|
||||
map_next(&mut iter);
|
||||
assert iter.get().is_none();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user