@@ -18,6 +18,8 @@ Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
1818
1919*/
2020
21+ use iter;
22+ use iter:: BaseIter ;
2123use kinds:: Copy ;
2224use managed;
2325use option:: { None , Option , Some } ;
@@ -489,14 +491,54 @@ pub impl<T:Copy> DList<T> {
489491 let mut v = vec::with_capacity(self.size);
490492 unsafe {
491493 // 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| {
493495 v[index] = *data;
494496 }
495497 }
496498 v
497499 }
498500}
499501
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+
500542#[ cfg( test) ]
501543mod tests {
502544 use dlist:: { DList, concat, from_vec, new_dlist_node} ;
0 commit comments