@@ -18,6 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
18
18
19
19
*/
20
20
21
+ use iter;
22
+ use iter:: BaseIter ;
21
23
use kinds:: Copy ;
22
24
use managed;
23
25
use option:: { None , Option , Some } ;
@@ -489,14 +491,54 @@ pub impl<T:Copy> DList<T> {
489
491
let mut v = vec::with_capacity(self.size);
490
492
unsafe {
491
493
// Take this out of the unchecked when iter's functions are pure
492
- for self . eachi |index, data| {
494
+ for iter:: eachi(&self) |index,data| {
493
495
v[index] = *data;
494
496
}
495
497
}
496
498
v
497
499
}
498
500
}
499
501
502
+ impl<T> BaseIter<T> for @mut DList<T> {
503
+ /**
504
+ * Iterates through the current contents.
505
+ *
506
+ * Attempts to access this dlist during iteration are allowed (to
507
+ * allow for e.g. breadth-first search with in-place enqueues), but
508
+ * removing the current node is forbidden.
509
+ */
510
+ pure fn each(&self, f: fn(v: &T) -> bool) {
511
+ let mut link = self.peek_n();
512
+ while option::is_some(&link) {
513
+ let nobe = option::get(link);
514
+ fail_unless!(nobe.linked);
515
+
516
+ {
517
+ let frozen_nobe = &*nobe;
518
+ if !f(&frozen_nobe.data) { break; }
519
+ }
520
+
521
+ // Check (weakly) that the user didn't do a remove.
522
+ if self.size == 0 {
523
+ fail!(~" The dlist became empty during iteration??")
524
+ }
525
+ if !nobe.linked ||
526
+ (!((nobe.prev.is_some()
527
+ || managed::mut_ptr_eq(self.hd.expect(~" headless dlist?"),
528
+ nobe))
529
+ && (nobe.next.is_some()
530
+ || managed::mut_ptr_eq(self.tl.expect(~" tailless dlist?"),
531
+ nobe)))) {
532
+ fail!(~" Removing a dlist node during iteration is forbidden!" )
533
+ }
534
+ link = nobe. next_link( ) ;
535
+ }
536
+ }
537
+
538
+ #[ inline( always) ]
539
+ pure fn size_hint( & self ) -> Option < uint > { Some ( self . len( ) ) }
540
+ }
541
+
500
542
#[ cfg( test) ]
501
543
mod tests {
502
544
use dlist:: { DList, concat, from_vec, new_dlist_node} ;
0 commit comments