Skip to content

Commit c095a5c

Browse files
author
blake2-ppc
committed
dlist: Use a DoubleEndedIterator for .mut_iter() and .mut_rev_iter()
Unify the mutable iterators too. Switch the ListInsertion trait to use method .insert_next() and .peek_next() for list mutation. .insert_next() inserts an element into the list that will not appear in iteration, of course; so the length of the iteration can not change during iteration.
1 parent e1d5d1c commit c095a5c

File tree

1 file changed

+109
-79
lines changed

1 file changed

+109
-79
lines changed

src/libextra/dlist.rs

Lines changed: 109 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -53,17 +53,11 @@ pub struct DListIterator<'self, T> {
5353
priv nelem: uint,
5454
}
5555

56-
/// DList mutable iterator
57-
pub struct MutForwardIterator<'self, T> {
56+
/// Double-ended mutable DList iterator
57+
pub struct MutDListIterator<'self, T> {
5858
priv list: &'self mut DList<T>,
59-
priv curs: Rawlink<Node<T>>,
60-
priv nelem: uint,
61-
}
62-
63-
/// DList mutable reverse iterator
64-
pub struct MutReverseIterator<'self, T> {
65-
priv list: &'self mut DList<T>,
66-
priv next: Rawlink<Node<T>>,
59+
priv head: Rawlink<Node<T>>,
60+
priv tail: Rawlink<Node<T>>,
6761
priv nelem: uint,
6862
}
6963

@@ -279,13 +273,14 @@ impl<T> DList<T> {
279273
{
280274
let mut it = self.mut_iter();
281275
loop {
282-
match it.next() {
276+
match it.peek_next() {
283277
None => break,
284-
Some(x) => if f(x, &elt) { it.insert_before(elt); return }
278+
Some(x) => if f(x, &elt) { break }
285279
}
280+
it.next();
286281
}
282+
it.insert_next(elt);
287283
}
288-
self.push_back(elt);
289284
}
290285

291286
/// Merge DList `other` into this DList, using the function `f`.
@@ -296,17 +291,16 @@ impl<T> DList<T> {
296291
pub fn merge(&mut self, mut other: DList<T>, f: &fn(&T, &T) -> bool) {
297292
{
298293
let mut it = self.mut_iter();
299-
let mut elt = it.next();
300294
loop {
301-
let take_a = match (&mut elt, other.front()) {
302-
(_ , None) => return,
303-
(&None, _ ) => break,
304-
(&Some(ref mut x), Some(y)) => f(*x, y),
295+
let take_a = match (it.peek_next(), other.front()) {
296+
(_ , None) => return,
297+
(None, _ ) => break,
298+
(Some(ref mut x), Some(y)) => f(*x, y),
305299
};
306300
if take_a {
307-
elt = it.next()
301+
it.next();
308302
} else {
309-
it.insert_before(other.pop_front().unwrap());
303+
it.insert_next(other.pop_front().unwrap());
310304
}
311305
}
312306
}
@@ -325,13 +319,22 @@ impl<T> DList<T> {
325319
}
326320

327321
/// Provide a forward iterator with mutable references
328-
pub fn mut_iter<'a>(&'a mut self) -> MutForwardIterator<'a, T> {
329-
MutForwardIterator{nelem: self.len(), list: self, curs: Rawlink::none()}
322+
pub fn mut_iter<'a>(&'a mut self) -> MutDListIterator<'a, T> {
323+
let head_raw = match self.list_head {
324+
Some(ref mut h) => Rawlink::some(*h),
325+
None => Rawlink::none(),
326+
};
327+
MutDListIterator{
328+
nelem: self.len(),
329+
head: head_raw,
330+
tail: self.list_tail,
331+
list: self
332+
}
330333
}
331-
332334
/// Provide a reverse iterator with mutable references
333-
pub fn mut_rev_iter<'a>(&'a mut self) -> MutReverseIterator<'a, T> {
334-
MutReverseIterator{nelem: self.len(), list: self, next: self.list_tail}
335+
pub fn mut_rev_iter<'a>(&'a mut self) -> InvertIterator<&'a mut T,
336+
MutDListIterator<'a, T>> {
337+
self.mut_iter().invert()
335338
}
336339

337340

@@ -392,31 +395,21 @@ impl<'self, A> DoubleEndedIterator<&'self A> for DListIterator<'self, A> {
392395
}
393396
}
394397

395-
// MutForwardIterator is different because it implements ListInsertion,
396-
// and can modify the list during traversal, used in insert_when and merge.
397-
impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
398+
impl<'self, A> Iterator<&'self mut A> for MutDListIterator<'self, A> {
398399
#[inline]
399400
fn next(&mut self) -> Option<&'self mut A> {
400-
match self.curs.resolve() {
401-
None => {
402-
match self.list.list_head {
403-
None => None,
404-
Some(ref mut head) => {
405-
self.nelem -= 1;
406-
self.curs = Rawlink::some(*head);
407-
Some(&mut head.value)
408-
}
409-
}
410-
}
411-
Some(curs) => {
412-
match curs.next {
413-
None => None,
414-
Some(ref mut head) => {
415-
self.nelem -= 1;
416-
self.curs = Rawlink::some(*head);
417-
Some(&mut head.value)
418-
}
419-
}
401+
if self.nelem == 0 {
402+
return None;
403+
}
404+
match self.head.resolve() {
405+
None => None,
406+
Some(next) => {
407+
self.nelem -= 1;
408+
self.head = match next.next {
409+
Some(ref mut node) => Rawlink::some(&mut **node),
410+
None => Rawlink::none(),
411+
};
412+
Some(&mut next.value)
420413
}
421414
}
422415
}
@@ -426,37 +419,39 @@ impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
426419
}
427420
}
428421

429-
impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
422+
impl<'self, A> DoubleEndedIterator<&'self mut A> for MutDListIterator<'self, A> {
430423
#[inline]
431-
fn next(&mut self) -> Option<&'self mut A> {
432-
match self.next.resolve() {
424+
fn next_back(&mut self) -> Option<&'self mut A> {
425+
if self.nelem == 0 {
426+
return None;
427+
}
428+
match self.tail.resolve() {
433429
None => None,
434430
Some(prev) => {
435431
self.nelem -= 1;
436-
self.next = prev.prev;
432+
self.tail = prev.prev;
437433
Some(&mut prev.value)
438434
}
439435
}
440436
}
441-
442-
fn size_hint(&self) -> (uint, Option<uint>) {
443-
(self.nelem, Some(self.nelem))
444-
}
445437
}
446438

439+
447440
/// Allow mutating the DList while iterating
448441
pub trait ListInsertion<A> {
449-
/// Insert `elt` just previous to the most recently yielded element
450-
fn insert_before(&mut self, elt: A);
442+
/// Insert `elt` just after to the most recently yielded element
443+
fn insert_next(&mut self, elt: A);
451444

452445
/// Provide a reference to the next element, without changing the iterator
453446
fn peek_next<'a>(&'a mut self) -> Option<&'a mut A>;
454447
}
455448

456-
impl<'self, A> ListInsertion<A> for MutForwardIterator<'self, A> {
457-
fn insert_before(&mut self, elt: A) {
458-
match self.curs.resolve() {
459-
None => { self.list.push_front(elt); self.next(); }
449+
impl<'self, A> ListInsertion<A> for MutDListIterator<'self, A> {
450+
fn insert_next(&mut self, elt: A) {
451+
// Insert an element before `self.head` so that it is between the
452+
// previously yielded element and self.head.
453+
match self.head.resolve() {
454+
None => { self.list.push_back(elt); }
460455
Some(node) => {
461456
let prev_node = match node.prev.resolve() {
462457
None => return self.list.push_front(elt),
@@ -472,12 +467,9 @@ impl<'self, A> ListInsertion<A> for MutForwardIterator<'self, A> {
472467
}
473468

474469
fn peek_next<'a>(&'a mut self) -> Option<&'a mut A> {
475-
match self.curs.resolve() {
476-
None => self.list.front_mut(),
477-
Some(curs) => match curs.next {
478-
None => None,
479-
Some(ref mut node) => Some(&mut node.value),
480-
}
470+
match self.head.resolve() {
471+
None => None,
472+
Some(head) => Some(&mut head.value),
481473
}
482474
}
483475
}
@@ -680,6 +672,24 @@ mod tests {
680672
assert_eq!(it.next(), None);
681673
}
682674

675+
#[test]
676+
fn test_iterator_double_end() {
677+
let mut n = DList::new();
678+
assert_eq!(n.iter().next(), None);
679+
n.push_front(4);
680+
n.push_front(5);
681+
n.push_front(6);
682+
let mut it = n.iter();
683+
assert_eq!(it.size_hint(), (3, Some(3)));
684+
assert_eq!(it.next().unwrap(), &6);
685+
assert_eq!(it.size_hint(), (2, Some(2)));
686+
assert_eq!(it.next_back().unwrap(), &4);
687+
assert_eq!(it.size_hint(), (1, Some(1)));
688+
assert_eq!(it.next_back().unwrap(), &5);
689+
assert_eq!(it.next_back(), None);
690+
assert_eq!(it.next(), None);
691+
}
692+
683693
#[test]
684694
fn test_rev_iter() {
685695
let m = generate_test();
@@ -708,38 +718,58 @@ mod tests {
708718
let mut n = DList::new();
709719
assert!(n.mut_iter().next().is_none());
710720
n.push_front(4);
721+
n.push_back(5);
711722
let mut it = n.mut_iter();
712-
assert_eq!(it.size_hint(), (1, Some(1)));
723+
assert_eq!(it.size_hint(), (2, Some(2)));
724+
assert!(it.next().is_some());
713725
assert!(it.next().is_some());
714726
assert_eq!(it.size_hint(), (0, Some(0)));
715727
assert!(it.next().is_none());
716728
}
717729

730+
#[test]
731+
fn test_iterator_mut_double_end() {
732+
let mut n = DList::new();
733+
assert!(n.mut_iter().next_back().is_none());
734+
n.push_front(4);
735+
n.push_front(5);
736+
n.push_front(6);
737+
let mut it = n.mut_iter();
738+
assert_eq!(it.size_hint(), (3, Some(3)));
739+
assert_eq!(*it.next().unwrap(), 6);
740+
assert_eq!(it.size_hint(), (2, Some(2)));
741+
assert_eq!(*it.next_back().unwrap(), 4);
742+
assert_eq!(it.size_hint(), (1, Some(1)));
743+
assert_eq!(*it.next_back().unwrap(), 5);
744+
assert!(it.next_back().is_none());
745+
assert!(it.next().is_none());
746+
}
747+
718748
#[test]
719749
fn test_insert_prev() {
720750
let mut m = list_from(&[0,2,4,6,8]);
721751
let len = m.len();
722752
{
723753
let mut it = m.mut_iter();
724-
it.insert_before(-2);
754+
it.insert_next(-2);
725755
loop {
726756
match it.next() {
727757
None => break,
728758
Some(elt) => {
729-
it.insert_before(*elt + 1);
759+
it.insert_next(*elt + 1);
730760
match it.peek_next() {
731761
Some(x) => assert_eq!(*x, *elt + 2),
732762
None => assert_eq!(8, *elt),
733763
}
734764
}
735765
}
736766
}
737-
it.insert_before(0);
738-
it.insert_before(1);
767+
it.insert_next(0);
768+
it.insert_next(1);
739769
}
740770
check_links(&m);
741771
assert_eq!(m.len(), 3 + len * 2);
742-
assert_eq!(m.consume_iter().collect::<~[int]>(), ~[-2,1,0,3,2,5,4,7,6,9,0,1,8]);
772+
assert_eq!(m.consume_iter().collect::<~[int]>(), ~[-2,0,1,2,3,4,5,6,7,8,9,0,1]);
743773
}
744774

745775
#[test]
@@ -853,7 +883,7 @@ mod tests {
853883
fn bench_collect_into(b: &mut test::BenchHarness) {
854884
let v = &[0, ..64];
855885
do b.iter {
856-
let _: DList<int> = v.iter().transform(|&x|x).collect();
886+
let _: DList<int> = v.iter().transform(|x| *x).collect();
857887
}
858888
}
859889
#[bench]
@@ -917,31 +947,31 @@ mod tests {
917947
let v = &[0, ..128];
918948
let m: DList<int> = v.iter().transform(|&x|x).collect();
919949
do b.iter {
920-
for m.iter().advance |_| {}
950+
assert!(m.iter().len_() == 128);
921951
}
922952
}
923953
#[bench]
924954
fn bench_iter_mut(b: &mut test::BenchHarness) {
925955
let v = &[0, ..128];
926956
let mut m: DList<int> = v.iter().transform(|&x|x).collect();
927957
do b.iter {
928-
for m.mut_iter().advance |_| {}
958+
assert!(m.mut_iter().len_() == 128);
929959
}
930960
}
931961
#[bench]
932962
fn bench_iter_rev(b: &mut test::BenchHarness) {
933963
let v = &[0, ..128];
934964
let m: DList<int> = v.iter().transform(|&x|x).collect();
935965
do b.iter {
936-
for m.rev_iter().advance |_| {}
966+
assert!(m.rev_iter().len_() == 128);
937967
}
938968
}
939969
#[bench]
940970
fn bench_iter_mut_rev(b: &mut test::BenchHarness) {
941971
let v = &[0, ..128];
942972
let mut m: DList<int> = v.iter().transform(|&x|x).collect();
943973
do b.iter {
944-
for m.mut_rev_iter().advance |_| {}
974+
assert!(m.mut_rev_iter().len_() == 128);
945975
}
946976
}
947977
#[bench]

0 commit comments

Comments
 (0)