From 824bb44f929a564dc4dd0590578de3ea04789402 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Tue, 9 Jul 2013 16:55:04 +0200
Subject: [PATCH 01/12] dlist: A new implementation of an owned doubly-linked
 list

This is an owned sendable linked list which allows insertion and
deletion at both ends, with fast traversal through iteration, and fast
append/prepend.

It is indended to replace the previous managed DList with exposed list
nodes. It does not match it feature by feature, but DList could grow
more methods if needed.
---
 src/libextra/dlist.rs     | 1750 ++++++++++++++++++-------------------
 src/libextra/serialize.rs |   16 +-
 2 files changed, 851 insertions(+), 915 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index e7dcb0fd7ce..d3132b37345 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -1,966 +1,902 @@
-// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
+
+//! A doubly-linked list with owned nodes.
+//!
+//! The List allows pushing and popping elements at either end.
+
+
+// List is constructed like a singly-linked list over the field `next`.
+// including the last link being None; each Node owns its `next` field.
 //
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-/*!
-
-A doubly-linked list. Supports O(1) head, tail, count, push, pop, etc.
-
-# Safety note
-
-Do not use ==, !=, <, etc on doubly-linked lists -- it may not terminate.
-
-*/
+// Backlinks over List::prev are raw pointers that form a full chain in
+// the reverse direction.
 
 
-use std::managed;
+use std::cast;
+use std::cmp;
+use std::util;
+use std::iterator::FromIterator;
 
-pub type DListLink<T> = Option<@mut DListNode<T>>;
-
-#[allow(missing_doc)]
-pub struct DListNode<T> {
-    data: T,
-    linked: bool, // for assertions
-    prev: DListLink<T>,
-    next: DListLink<T>,
+/// A doubly-linked list
+pub struct List<T> {
+    priv length: uint,
+    priv list_head: Link<T>,
+    priv list_tail: Rawlink<T>,
 }
 
-#[allow(missing_doc)]
-pub struct DList<T> {
-    size: uint,
-    hd: DListLink<T>,
-    tl: DListLink<T>,
+type Link<T> = Option<~Node<T>>;
+type Rawlink<T> = Option<&'static Node<T>>;
+// Rawlink uses &'static to have a small Option<&'> represenation.
+// FIXME: Use a raw pointer like *mut Node if possible.
+// FIXME: Causes infinite recursion in %? repr
+
+struct Node<T> {
+    priv next: Link<T>,
+    priv prev: Rawlink<T>,
+    priv value: T,
 }
 
-impl<T> DListNode<T> {
-    fn assert_links(@mut self) {
-        match self.next {
-            Some(neighbour) => match neighbour.prev {
-              Some(me) => if !managed::mut_ptr_eq(self, me) {
-                  fail!("Asymmetric next-link in dlist node.")
-              },
-              None => fail!("One-way next-link in dlist node.")
-            },
-            None => ()
-        }
-        match self.prev {
-            Some(neighbour) => match neighbour.next {
-              Some(me) => if !managed::mut_ptr_eq(me, self) {
-                  fail!("Asymmetric prev-link in dlist node.")
-              },
-              None => fail!("One-way prev-link in dlist node.")
-            },
-            None => ()
-        }
+/// List iterator
+pub struct ForwardIterator<'self, T> {
+    priv list: &'self List<T>,
+    priv next: &'self Link<T>,
+}
+
+/// List reverse iterator
+pub struct ReverseIterator<'self, T> {
+    priv list: &'self List<T>,
+    priv next: Rawlink<T>,
+}
+
+/// List mutable iterator
+pub struct MutForwardIterator<'self, T> {
+    priv list: &'self mut List<T>,
+    priv curs: Rawlink<T>,
+}
+
+/// List mutable reverse iterator
+pub struct MutReverseIterator<'self, T> {
+    priv list: &'self mut List<T>,
+    priv next: Rawlink<T>,
+}
+
+/// List consuming iterator
+pub struct ConsumeIterator<T> {
+    priv list: List<T>
+}
+
+/// List reverse consuming iterator
+pub struct ConsumeRevIterator<T> {
+    priv list: List<T>
+}
+
+impl<T> Container for List<T> {
+    /// O(1)
+    fn is_empty(&self) -> bool {
+        self.list_head.is_none()
+    }
+    /// O(1)
+    fn len(&self) -> uint {
+        self.length
     }
 }
 
-impl<T> DListNode<T> {
-    /// Get the next node in the list, if there is one.
-    pub fn next_link(@mut self) -> DListLink<T> {
-        self.assert_links();
-        self.next
-    }
-    /// Get the next node in the list, failing if there isn't one.
-    pub fn next_node(@mut self) -> @mut DListNode<T> {
-        match self.next_link() {
-            Some(nobe) => nobe,
-            None       => fail!("This dlist node has no next neighbour.")
-        }
-    }
-    /// Get the previous node in the list, if there is one.
-    pub fn prev_link(@mut self) -> DListLink<T> {
-        self.assert_links();
-        self.prev
-    }
-    /// Get the previous node in the list, failing if there isn't one.
-    pub fn prev_node(@mut self) -> @mut DListNode<T> {
-        match self.prev_link() {
-            Some(nobe) => nobe,
-            None       => fail!("This dlist node has no previous neighbour.")
-        }
+impl<T> Mutable for List<T> {
+    /// Remove all elements from the List
+    ///
+    /// O(N)
+    fn clear(&mut self) {
+        *self = List::new()
     }
 }
 
-/// Creates a new dlist node with the given data.
-pub fn new_dlist_node<T>(data: T) -> @mut DListNode<T> {
-    @mut DListNode { data: data, linked: false, prev: None, next: None }
+/// Cast the raw link into a borrowed ref
+fn resolve_rawlink<T>(lnk: &'static Node<T>) -> &mut Node<T> {
+    unsafe { cast::transmute_mut(lnk) }
+}
+fn rawlink<T>(n: &mut Node<T>) -> Rawlink<T> {
+    Some(unsafe { cast::transmute(n) })
 }
 
-/// Creates a new, empty dlist.
-pub fn DList<T>() -> @mut DList<T> {
-    @mut DList { size: 0, hd: None, tl: None }
-}
-
-/// Creates a new dlist with a single element
-pub fn from_elem<T>(data: T) -> @mut DList<T> {
-    let list = DList();
-    list.push(data);
-    list
-}
-
-/// Creates a new dlist from a vector of elements, maintaining the same order
-pub fn from_vec<T:Copy>(vec: &[T]) -> @mut DList<T> {
-    do vec.iter().fold(DList()) |list,data| {
-        // Iterating left-to-right -- add newly to the tail.
-        list.push(copy *data);
-        list
-    }
-}
-
-/// Produce a list from a list of lists, leaving no elements behind in the
-/// input. O(number of sub-lists).
-pub fn concat<T>(lists: @mut DList<@mut DList<T>>) -> @mut DList<T> {
-    let result = DList();
-    while !lists.is_empty() {
-        result.append(lists.pop().get());
-    }
-    result
-}
-
-impl<T> DList<T> {
-    fn new_link(data: T) -> DListLink<T> {
-        Some(@mut DListNode {
-            data: data,
-            linked: true,
-            prev: None,
-            next: None
-        })
-    }
-    fn assert_mine(@mut self, nobe: @mut DListNode<T>) {
-        // These asserts could be stronger if we had node-root back-pointers,
-        // but those wouldn't allow for O(1) append.
-        if self.size == 0 {
-            fail!("This dlist is empty; that node can't be on it.")
-        }
-        if !nobe.linked { fail!("That node isn't linked to any dlist.") }
-        if !((nobe.prev.is_some()
-              || managed::mut_ptr_eq(self.hd.expect("headless dlist?"),
-                                 nobe)) &&
-             (nobe.next.is_some()
-              || managed::mut_ptr_eq(self.tl.expect("tailless dlist?"),
-                                 nobe))) {
-            fail!("That node isn't on this dlist.")
-        }
-    }
-    fn make_mine(&self, nobe: @mut DListNode<T>) {
-        if nobe.prev.is_some() || nobe.next.is_some() || nobe.linked {
-            fail!("Cannot insert node that's already on a dlist!")
-        }
-        nobe.linked = true;
-    }
-    // Link two nodes together. If either of them are 'none', also sets
-    // the head and/or tail pointers appropriately.
+impl<T> List<T> {
+    /// Create an empty List
     #[inline]
-    fn link(&mut self, before: DListLink<T>, after: DListLink<T>) {
-        match before {
-            Some(neighbour) => neighbour.next = after,
-            None            => self.hd        = after
-        }
-        match after {
-            Some(neighbour) => neighbour.prev = before,
-            None            => self.tl        = before
-        }
-    }
-    // Remove a node from the list.
-    fn unlink(@mut self, nobe: @mut DListNode<T>) {
-        self.assert_mine(nobe);
-        assert!(self.size > 0);
-        self.link(nobe.prev, nobe.next);
-        nobe.prev = None; // Release extraneous references.
-        nobe.next = None;
-        nobe.linked = false;
-        self.size -= 1;
+    pub fn new() -> List<T> {
+        List{list_head: None, list_tail: None, length: 0}
     }
 
-    fn add_head(@mut self, nobe: DListLink<T>) {
-        self.link(nobe, self.hd); // Might set tail too.
-        self.hd = nobe;
-        self.size += 1;
+    /// Provide a reference to the front element, or None if the list is empty
+    pub fn peek_front<'a>(&'a self) -> Option<&'a T> {
+        self.list_head.chain_ref(|x| Some(&x.value))
     }
-    fn add_tail(@mut self, nobe: DListLink<T>) {
-        self.link(self.tl, nobe); // Might set head too.
-        self.tl = nobe;
-        self.size += 1;
+
+    /// Provide a mutable reference to the front element, or None if the list is empty
+    pub fn peek_front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+        match self.list_head {
+            None => None,
+            Some(ref mut head) => Some(&mut head.value),
+        }
     }
-    fn insert_left(@mut self,
-                   nobe: DListLink<T>,
-                   neighbour: @mut DListNode<T>) {
-        self.assert_mine(neighbour);
-        assert!(self.size > 0);
-        self.link(neighbour.prev, nobe);
-        self.link(nobe, Some(neighbour));
-        self.size += 1;
+
+    /// Provide a reference to the back element, or None if the list is empty
+    pub fn peek_back<'a>(&'a self) -> Option<&'a T> {
+        match self.list_tail {
+            None => None,
+            Some(tail) => Some(&resolve_rawlink(tail).value),
+        }
     }
-    fn insert_right(@mut self,
-                    neighbour: @mut DListNode<T>,
-                    nobe: DListLink<T>) {
-        self.assert_mine(neighbour);
-        assert!(self.size > 0);
-        self.link(nobe, neighbour.next);
-        self.link(Some(neighbour), nobe);
-        self.size += 1;
+
+    /// Provide a mutable reference to the back element, or None if the list is empty
+    pub fn peek_back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+        match self.list_tail {
+            None => None,
+            Some(tail) => Some(&mut resolve_rawlink(tail).value),
+        }
+    }
+
+    /// Add an element last in the list
+    ///
+    /// O(1)
+    pub fn push_back(&mut self, elt: T) {
+        match self.list_tail {
+            None => return self.push_front(elt),
+            Some(rtail) => {
+                let mut new_tail = ~Node{value: elt, next: None, prev: self.list_tail};
+                self.list_tail = rawlink(new_tail);
+                let tail = resolve_rawlink(rtail);
+                tail.next = Some(new_tail);
+            }
+        }
+        self.length += 1;
+    }
+
+    /// Remove the last element and return it, or None if the list is empty
+    ///
+    /// O(1)
+    #[inline]
+    pub fn pop_back(&mut self) -> Option<T> {
+        match self.list_tail {
+            None => None,
+            Some(rtail) => {
+                self.length -= 1;
+                let tail = resolve_rawlink(rtail);
+                let tail_own = match tail.prev {
+                    None => {
+                        self.list_tail = None;
+                        self.list_head.swap_unwrap()
+                    },
+                    Some(rtail_prev) => {
+                        self.list_tail = tail.prev;
+                        resolve_rawlink(rtail_prev).next.swap_unwrap()
+                    }
+                };
+                Some(tail_own.value)
+            }
+        }
+    }
+
+    /// Add an element first in the list
+    ///
+    /// O(1)
+    pub fn push_front(&mut self, elt: T) {
+        let mut new_head = ~Node{value: elt, next: None, prev: None};
+        match self.list_head {
+            None => {
+                self.list_tail = rawlink(new_head);
+                self.list_head = Some(new_head);
+            }
+            Some(ref mut head) => {
+                head.prev = rawlink(new_head);
+                util::swap(head, &mut new_head);
+                head.next = Some(new_head);
+            }
+        }
+        self.length += 1;
+    }
+
+    /// Remove the first element and return it, or None if the list is empty
+    ///
+    /// O(1)
+    pub fn pop_front(&mut self) -> Option<T> {
+        match self.list_head {
+            None => None,
+            ref mut head @ Some(*) => {
+                self.length -= 1;
+                match *head.swap_unwrap() {
+                    Node{value: value, next: Some(next), prev: _} => {
+                        let mut mnext = next;
+                        mnext.prev = None;
+                        *head = Some(mnext);
+                        Some(value)
+                    }
+                    Node{value: value, next: None, prev: _} => {
+                        self.list_tail = None;
+                        *head = None;
+                        Some(value)
+                    }
+                }
+            }
+        }
+    }
+
+    /// Add all elements from `other` to the end of the list
+    ///
+    /// O(1)
+    pub fn append(&mut self, other: List<T>) {
+        match self.list_tail {
+            None => *self = other,
+            Some(rtail) => {
+                match other {
+                    List{list_head: None, list_tail: _, length: _} => return,
+                    List{list_head: Some(node), list_tail: o_tail, length: o_length} => {
+                        let mut lnk_node = node;
+                        let tail = resolve_rawlink(rtail);
+                        lnk_node.prev = self.list_tail;
+                        tail.next = Some(lnk_node);
+                        self.list_tail = o_tail;
+                        self.length += o_length;
+                    }
+                }
+            }
+        }
+    }
+
+    /// Add all elements from `other` to the beginning of the list
+    ///
+    /// O(1)
+    pub fn prepend(&mut self, mut other: List<T>) {
+        util::swap(self, &mut other);
+        self.append(other);
+    }
+
+    /// Insert `elt` before the first `x` in the list where `f(x, elt)` is true,
+    /// or at the end.
+    ///
+    /// O(N)
+    #[inline]
+    pub fn insert_before(&mut self, elt: T, f: &fn(&T, &T) -> bool) {
+        {
+            let mut it = self.mut_iter();
+            loop {
+                match it.next() {
+                    None => break,
+                    Some(x) => if f(x, &elt) { it.insert_before(elt); return }
+                }
+            }
+        }
+        self.push_back(elt);
+    }
+
+    /// Merge, using the function `f`; take `a` if `f(a, b)` is true, else `b`.
+    ///
+    /// O(max(N, M))
+    pub fn merge(&mut self, mut other: List<T>, f: &fn(&T, &T) -> bool) {
+        {
+            let mut it = self.mut_iter();
+            loop {
+                match (it.next(), other.peek_front()) {
+                    (None   , _      ) => break,
+                    (_      , None   ) => return,
+                    (Some(x), Some(y)) => if f(x, y) { loop }
+                }
+                it.insert_before(other.pop_front().unwrap());
+            }
+        }
+        self.append(other);
+    }
+
+
+    /// Provide a forward iterator
+    pub fn iter<'a>(&'a self) -> ForwardIterator<'a, T> {
+        ForwardIterator{list: self, next: &self.list_head}
+    }
+
+    /// Provide a reverse iterator
+    pub fn rev_iter<'a>(&'a self) -> ReverseIterator<'a, T> {
+        ReverseIterator{list: self, next: self.list_tail}
+    }
+
+    /// Provide a forward iterator with mutable references
+    pub fn mut_iter<'a>(&'a mut self) -> MutForwardIterator<'a, T> {
+        MutForwardIterator{list: self, curs: None}
+    }
+
+    /// Provide a reverse iterator with mutable references
+    pub fn mut_rev_iter<'a>(&'a mut self) -> MutReverseIterator<'a, T> {
+        MutReverseIterator{list: self, next: self.list_tail}
+    }
+
+
+    /// Consume the list into an iterator yielding elements by value
+    pub fn consume_iter(self) -> ConsumeIterator<T> {
+        ConsumeIterator{list: self}
+    }
+
+    /// Consume the list into an iterator yielding elements by value, in reverse
+    pub fn consume_rev_iter(self) -> ConsumeRevIterator<T> {
+        ConsumeRevIterator{list: self}
     }
 }
 
-impl<T> DList<T> {
-    /**
-     * Iterates through the current contents.
-     *
-     * Attempts to access this dlist during iteration are allowed (to
-     * allow for e.g. breadth-first search with in-place enqueues), but
-     * removing the current node is forbidden.
-     */
-    pub fn each(@mut self, f: &fn(v: &T) -> bool) -> bool {
-        let mut link = self.peek_n();
-        while link.is_some() {
-            let nobe = link.get();
-            assert!(nobe.linked);
-
-            {
-                let frozen_nobe = &*nobe;
-                if !f(&frozen_nobe.data) { return false; }
-            }
-
-            // Check (weakly) that the user didn't do a remove.
-            if self.size == 0 {
-                fail!("The dlist became empty during iteration??")
-            }
-            if !nobe.linked ||
-                (!((nobe.prev.is_some()
-                    || managed::mut_ptr_eq(self.hd.expect("headless dlist?"),
-                                           nobe))
-                   && (nobe.next.is_some()
-                    || managed::mut_ptr_eq(self.tl.expect("tailless dlist?"),
-                                           nobe)))) {
-                fail!("Removing a dlist node during iteration is forbidden!")
-            }
-            link = nobe.next_link();
-        }
-        return true;
-    }
-
-    /// Get the size of the list. O(1).
-    pub fn len(@mut self) -> uint { self.size }
-    /// Returns true if the list is empty. O(1).
-    pub fn is_empty(@mut self) -> bool { self.len() == 0 }
-
-    /// Add data to the head of the list. O(1).
-    pub fn push_head(@mut self, data: T) {
-        self.add_head(DList::new_link(data));
-    }
-    /**
-     * Add data to the head of the list, and get the new containing
-     * node. O(1).
-     */
-    pub fn push_head_n(@mut self, data: T) -> @mut DListNode<T> {
-        let nobe = DList::new_link(data);
-        self.add_head(nobe);
-        nobe.get()
-    }
-    /// Add data to the tail of the list. O(1).
-    pub fn push(@mut self, data: T) {
-        self.add_tail(DList::new_link(data));
-    }
-    /**
-     * Add data to the tail of the list, and get the new containing
-     * node. O(1).
-     */
-    pub fn push_n(@mut self, data: T) -> @mut DListNode<T> {
-        let nobe = DList::new_link(data);
-        self.add_tail(nobe);
-        nobe.get()
-    }
-    /**
-     * Insert data into the middle of the list, left of the given node.
-     * O(1).
-     */
-    pub fn insert_before(@mut self, data: T, neighbour: @mut DListNode<T>) {
-        self.insert_left(DList::new_link(data), neighbour);
-    }
-    /**
-     * Insert an existing node in the middle of the list, left of the
-     * given node. O(1).
-     */
-    pub fn insert_n_before(@mut self,
-                           nobe: @mut DListNode<T>,
-                           neighbour: @mut DListNode<T>) {
-        self.make_mine(nobe);
-        self.insert_left(Some(nobe), neighbour);
-    }
-    /**
-     * Insert data in the middle of the list, left of the given node,
-     * and get its containing node. O(1).
-     */
-    pub fn insert_before_n(@mut self,
-                           data: T,
-                           neighbour: @mut DListNode<T>)
-                           -> @mut DListNode<T> {
-        let nobe = DList::new_link(data);
-        self.insert_left(nobe, neighbour);
-        nobe.get()
-    }
-    /**
-     * Insert data into the middle of the list, right of the given node.
-     * O(1).
-     */
-    pub fn insert_after(@mut self, data: T, neighbour: @mut DListNode<T>) {
-        self.insert_right(neighbour, DList::new_link(data));
-    }
-    /**
-     * Insert an existing node in the middle of the list, right of the
-     * given node. O(1).
-     */
-    pub fn insert_n_after(@mut self,
-                          nobe: @mut DListNode<T>,
-                          neighbour: @mut DListNode<T>) {
-        self.make_mine(nobe);
-        self.insert_right(neighbour, Some(nobe));
-    }
-    /**
-     * Insert data in the middle of the list, right of the given node,
-     * and get its containing node. O(1).
-     */
-    pub fn insert_after_n(@mut self,
-                          data: T,
-                          neighbour: @mut DListNode<T>)
-                          -> @mut DListNode<T> {
-        let nobe = DList::new_link(data);
-        self.insert_right(neighbour, nobe);
-        nobe.get()
-    }
-
-    /// Remove a node from the head of the list. O(1).
-    pub fn pop_n(@mut self) -> DListLink<T> {
-        let hd = self.peek_n();
-        hd.map(|nobe| self.unlink(*nobe));
-        hd
-    }
-    /// Remove a node from the tail of the list. O(1).
-    pub fn pop_tail_n(@mut self) -> DListLink<T> {
-        let tl = self.peek_tail_n();
-        tl.map(|nobe| self.unlink(*nobe));
-        tl
-    }
-    /// Get the node at the list's head. O(1).
-    pub fn peek_n(@mut self) -> DListLink<T> { self.hd }
-    /// Get the node at the list's tail. O(1).
-    pub fn peek_tail_n(@mut self) -> DListLink<T> { self.tl }
-
-    /// Get the node at the list's head, failing if empty. O(1).
-    pub fn head_n(@mut self) -> @mut DListNode<T> {
-        match self.hd {
-            Some(nobe) => nobe,
-            None       => fail!("Attempted to get the head of an empty dlist.")
-        }
-    }
-    /// Get the node at the list's tail, failing if empty. O(1).
-    pub fn tail_n(@mut self) -> @mut DListNode<T> {
-        match self.tl {
-            Some(nobe) => nobe,
-            None       => fail!("Attempted to get the tail of an empty dlist.")
-        }
-    }
-
-    /// Remove a node from anywhere in the list. O(1).
-    pub fn remove(@mut self, nobe: @mut DListNode<T>) { self.unlink(nobe); }
-
-    /**
-     * Empty another list onto the end of this list, joining this list's tail
-     * to the other list's head. O(1).
-     */
-    pub fn append(@mut self, them: @mut DList<T>) {
-        if managed::mut_ptr_eq(self, them) {
-            fail!("Cannot append a dlist to itself!")
-        }
-        if them.len() > 0 {
-            self.link(self.tl, them.hd);
-            self.tl    = them.tl;
-            self.size += them.size;
-            them.size  = 0;
-            them.hd    = None;
-            them.tl    = None;
-        }
-    }
-    /**
-     * Empty another list onto the start of this list, joining the other
-     * list's tail to this list's head. O(1).
-     */
-    pub fn prepend(@mut self, them: @mut DList<T>) {
-        if managed::mut_ptr_eq(self, them) {
-            fail!("Cannot prepend a dlist to itself!")
-        }
-        if them.len() > 0 {
-            self.link(them.tl, self.hd);
-            self.hd    = them.hd;
-            self.size += them.size;
-            them.size  = 0;
-            them.hd    = None;
-            them.tl    = None;
-        }
-    }
-
-    /// Reverse the list's elements in place. O(n).
-    pub fn reverse(@mut self) {
-        do self.hd.while_some |nobe| {
-            let next_nobe = nobe.next;
-            self.remove(nobe);
-            self.make_mine(nobe);
-            self.add_head(Some(nobe));
-            next_nobe
-        }
-    }
-
-    /**
-     * Remove everything from the list. This is important because the cyclic
-     * links won't otherwise be automatically refcounted-collected. O(n).
-     */
-    pub fn clear(@mut self) {
-        // Cute as it would be to simply detach the list and proclaim "O(1)!",
-        // the GC would still be a hidden O(n). Better to be honest about it.
-        while !self.is_empty() {
-            let _ = self.pop_n();
-        }
-    }
-
-    /// Iterate over nodes.
-    pub fn each_node(@mut self, f: &fn(@mut DListNode<T>) -> bool) -> bool {
-        let mut link = self.peek_n();
-        while link.is_some() {
-            let nobe = link.get();
-            if !f(nobe) { return false; }
-            link = nobe.next_link();
-        }
-        return true;
-    }
-
-    /// Check data structure integrity. O(n).
-    pub fn assert_consistent(@mut self) {
-        if self.hd.is_none() || self.tl.is_none() {
-            assert!(self.hd.is_none() && self.tl.is_none());
-        }
-        // iterate forwards
-        let mut count = 0;
-        let mut link = self.peek_n();
-        let mut rabbit = link;
-        while link.is_some() {
-            let nobe = link.get();
-            assert!(nobe.linked);
-            // check cycle
-            if rabbit.is_some() {
-                rabbit = rabbit.get().next;
-            }
-            if rabbit.is_some() {
-                rabbit = rabbit.get().next;
-            }
-            if rabbit.is_some() {
-                assert!(!managed::mut_ptr_eq(rabbit.get(), nobe));
-            }
-            // advance
-            link = nobe.next_link();
-            count += 1;
-        }
-        assert_eq!(count, self.len());
-        // iterate backwards - some of this is probably redundant.
-        link = self.peek_tail_n();
-        rabbit = link;
-        while link.is_some() {
-            let nobe = link.get();
-            assert!(nobe.linked);
-            // check cycle
-            if rabbit.is_some() {
-                rabbit = rabbit.get().prev;
-            }
-            if rabbit.is_some() {
-                rabbit = rabbit.get().prev;
-            }
-            if rabbit.is_some() {
-                assert!(!managed::mut_ptr_eq(rabbit.get(), nobe));
-            }
-            // advance
-            link = nobe.prev_link();
-            count -= 1;
-        }
-        assert_eq!(count, 0);
+/// Insert sorted in ascending order
+///
+/// O(N)
+impl<T: cmp::TotalOrd> List<T> {
+    fn insert_ordered(&mut self, elt: T) {
+        self.insert_before(elt, |a, b| a.cmp(b) != cmp::Less);
     }
 }
 
-impl<T:Copy> DList<T> {
-    /// Remove data from the head of the list. O(1).
-    pub fn pop(@mut self) -> Option<T> {
-        self.pop_n().map(|nobe| copy nobe.data)
+impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
+    #[inline]
+    fn next(&mut self) -> Option<&'self A> {
+        match *self.next {
+            None => None,
+            Some(ref next) => {
+                self.next = &next.next;
+                Some(&next.value)
+            }
+        }
     }
 
-    /// Remove data from the tail of the list. O(1).
-    pub fn pop_tail(@mut self) -> Option<T> {
-        self.pop_tail_n().map(|nobe| copy nobe.data)
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (0, Some(self.list.length))
+    }
+}
+
+// MutForwardIterator is different because it implements ListInsertCursor,
+// and can modify the list during traversal, used in insert_when and merge.
+impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
+    #[inline]
+    fn next(&mut self) -> Option<&'self mut A> {
+        match self.curs {
+            None => {
+                match self.list.list_head {
+                    None => None,
+                    Some(ref mut head) => {
+                        self.curs = rawlink(&mut **head);
+                        Some(&mut head.value)
+                    }
+                }
+            }
+            Some(rcurs) => {
+                match resolve_rawlink(rcurs).next {
+                    None => None,
+                    Some(ref mut head) => {
+                        self.curs = rawlink(&mut **head);
+                        Some(&mut head.value)
+                    }
+                }
+            }
+        }
     }
 
-    /// Get data at the list's head. O(1).
-    pub fn peek(@mut self) -> Option<T> {
-        self.peek_n().map(|nobe| copy nobe.data)
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (0, Some(self.list.length))
+    }
+}
+
+impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
+    #[inline]
+    fn next(&mut self) -> Option<&'self A> {
+        match self.next {
+            None => None,
+            Some(rnext) => {
+                let prev = resolve_rawlink(rnext);
+                self.next = prev.prev;
+                Some(&prev.value)
+            }
+        }
     }
 
-    /// Get data at the list's tail. O(1).
-    pub fn peek_tail(@mut self) -> Option<T> {
-        self.peek_tail_n().map (|nobe| copy nobe.data)
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (0, Some(self.list.length))
+    }
+}
+
+impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
+    #[inline]
+    fn next(&mut self) -> Option<&'self mut A> {
+        match self.next {
+            None => None,
+            Some(rnext) => {
+                let prev = resolve_rawlink(rnext);
+                self.next = prev.prev;
+                Some(&mut prev.value)
+            }
+        }
     }
 
-    /// Get data at the list's head, failing if empty. O(1).
-    pub fn head(@mut self) -> T { copy self.head_n().data }
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (0, Some(self.list.length))
+    }
+}
 
-    /// Get data at the list's tail, failing if empty. O(1).
-    pub fn tail(@mut self) -> T { copy self.tail_n().data }
+// XXX: Should this be `pub`?
+trait ListInsertCursor<A> {
+    /// Insert `elt` just previous to the most recently yielded element
+    fn insert_before(&mut self, elt: A);
+}
+
+impl<'self, A> ListInsertCursor<A> for MutForwardIterator<'self, A> {
+    fn insert_before(&mut self, elt: A) {
+        match self.curs {
+            None => self.list.push_front(elt),
+            Some(rcurs) => {
+                let node = resolve_rawlink(rcurs);
+                let prev_node = match node.prev {
+                    None => return self.list.push_front(elt),  // at head
+                    Some(rprev) => resolve_rawlink(rprev),
+                };
+                let mut node_own = prev_node.next.swap_unwrap();
+                let mut ins_node = ~Node{value: elt,
+                                         next: None,
+                                         prev: rawlink(prev_node)};
+                node_own.prev = rawlink(ins_node);
+                ins_node.next = Some(node_own);
+                prev_node.next = Some(ins_node);
+                self.list.length += 1;
+            }
+        }
+    }
+}
+
+impl<A> Iterator<A> for ConsumeIterator<A> {
+    fn next(&mut self) -> Option<A> { self.list.pop_front() }
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (self.list.length, Some(self.list.length))
+    }
+}
+
+impl<A> Iterator<A> for ConsumeRevIterator<A> {
+    fn next(&mut self) -> Option<A> { self.list.pop_back() }
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        (self.list.length, Some(self.list.length))
+    }
+}
+
+impl<A, T: Iterator<A>> FromIterator<A, T> for List<A> {
+    fn from_iterator(iterator: &mut T) -> List<A> {
+        let mut ret = List::new();
+        for iterator.advance |elt| { ret.push_back(elt); }
+        ret
+    }
+}
+
+impl<A: Eq> Eq for List<A> {
+    fn eq(&self, other: &List<A>) -> bool {
+        self.len() == other.len() &&
+            self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
+    }
+    fn ne(&self, other: &List<A>) -> bool {
+        !self.eq(other)
+    }
+}
+
+impl<A: Clone> Clone for List<A> {
+    fn clone(&self) -> List<A> {
+        self.iter().transform(|x| x.clone()).collect()
+    }
 }
 
 #[cfg(test)]
-mod tests {
+fn check_links<T>(list: &List<T>) {
+    let mut len = 0u;
+    let mut last_ptr: Option<&Node<T>> = None;
+    let mut node_ptr: &Node<T>;
+    match list.list_head {
+        None => { assert_eq!(0u, list.length); return }
+        Some(ref node) => node_ptr = &**node,
+    }
+    loop {
+        match (last_ptr, node_ptr.prev) {
+            (None   , None      ) => {}
+            (None   , _         ) => fail!("prev link for list_head"),
+            (Some(p), Some(pptr)) => {
+                assert_eq!((p as *Node<T>) as uint, pptr as *Node<T> as uint);
+            }
+            _ => fail!("prev link is none, not good"),
+        }
+        match node_ptr.next {
+            Some(ref next) => {
+                last_ptr = Some(node_ptr);
+                node_ptr = &**next;
+                len += 1;
+            }
+            None => {
+                len += 1;
+                break;
+            }
+        }
+    }
+    assert_eq!(len, list.length);
+}
+
+#[test]
+fn test_basic() {
+    let mut m = List::new::<~int>();
+    assert_eq!(m.pop_front(), None);
+    assert_eq!(m.pop_back(), None);
+    assert_eq!(m.pop_front(), None);
+    m.push_front(~1);
+    assert_eq!(m.pop_front(), Some(~1));
+    m.push_back(~2);
+    m.push_back(~3);
+    assert_eq!(m.len(), 2);
+    assert_eq!(m.pop_front(), Some(~2));
+    assert_eq!(m.pop_front(), Some(~3));
+    assert_eq!(m.len(), 0);
+    assert_eq!(m.pop_front(), None);
+    m.push_back(~1);
+    m.push_back(~3);
+    m.push_back(~5);
+    m.push_back(~7);
+    assert_eq!(m.pop_front(), Some(~1));
+
+    let mut n = List::new();
+    n.push_front(2);
+    n.push_front(3);
+    {
+        assert_eq!(n.peek_front().unwrap(), &3);
+        let x = n.peek_front_mut().unwrap();
+        assert_eq!(*x, 3);
+        *x = 0;
+    }
+    {
+        assert_eq!(n.peek_back().unwrap(), &2);
+        let y = n.peek_back_mut().unwrap();
+        assert_eq!(*y, 2);
+        *y = 1;
+    }
+    assert_eq!(n.pop_front(), Some(0));
+    assert_eq!(n.pop_front(), Some(1));
+}
+
+#[cfg(test)]
+fn generate_test() -> List<int> {
+    list_from(&[0,1,2,3,4,5,6])
+}
+
+#[cfg(test)]
+fn list_from<T: Copy>(v: &[T]) -> List<T> {
+    v.iter().transform(|x| copy *x).collect()
+}
+
+#[test]
+fn test_append() {
+    {
+        let mut m = List::new();
+        let mut n = List::new();
+        n.push_back(2);
+        m.append(n);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        check_links(&m);
+    }
+    {
+        let mut m = List::new();
+        let n = List::new();
+        m.push_back(2);
+        m.append(n);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        check_links(&m);
+    }
+
+    let v = ~[1,2,3,4,5];
+    let u = ~[9,8,1,2,3,4,5];
+    let mut m = list_from(v);
+    m.append(list_from(u));
+    check_links(&m);
+    let sum = v + u;
+    assert_eq!(sum.len(), m.len());
+    for sum.consume_iter().advance |elt| {
+        assert_eq!(m.pop_front(), Some(elt))
+    }
+}
+
+#[test]
+fn test_prepend() {
+    {
+        let mut m = List::new();
+        let mut n = List::new();
+        n.push_back(2);
+        m.prepend(n);
+        assert_eq!(m.len(), 1);
+        assert_eq!(m.pop_back(), Some(2));
+        check_links(&m);
+    }
+
+    let v = ~[1,2,3,4,5];
+    let u = ~[9,8,1,2,3,4,5];
+    let mut m = list_from(v);
+    m.prepend(list_from(u));
+    check_links(&m);
+    let sum = u + v;
+    assert_eq!(sum.len(), m.len());
+    for sum.consume_iter().advance |elt| {
+        assert_eq!(m.pop_front(), Some(elt))
+    }
+}
+
+#[test]
+fn test_iterator() {
+    let m = generate_test();
+    for m.iter().enumerate().advance |(i, elt)| {
+        assert_eq!(i as int, *elt);
+    }
+    let mut n = List::new();
+    assert_eq!(n.iter().next(), None);
+    n.push_front(4);
+    let mut it = n.iter();
+    assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_rev_iter() {
+    let m = generate_test();
+    for m.rev_iter().enumerate().advance |(i, elt)| {
+        assert_eq!((6 - i) as int, *elt);
+    }
+    let mut n = List::new();
+    assert_eq!(n.rev_iter().next(), None);
+    n.push_front(4);
+    let mut it = n.rev_iter();
+    assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.next(), None);
+}
+
+#[test]
+fn test_mut_iter() {
+    let mut m = generate_test();
+    let mut len = m.len();
+    for m.mut_iter().enumerate().advance |(i, elt)| {
+        assert_eq!(i as int, *elt);
+        len -= 1;
+    }
+    assert_eq!(len, 0);
+    let mut n = List::new();
+    assert!(n.mut_iter().next().is_none());
+    n.push_front(4);
+    let mut it = n.mut_iter();
+    assert!(it.next().is_some());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_list_cursor() {
+    let mut m = generate_test();
+    let len = m.len();
+    {
+        let mut it = m.mut_iter();
+        loop {
+            match it.next() {
+                None => break,
+                Some(elt) => it.insert_before(*elt * 2),
+            }
+        }
+    }
+    assert_eq!(m.len(), len * 2);
+    check_links(&m);
+}
+
+#[test]
+fn test_merge() {
+    let mut m = list_from([0, 1, 3, 5, 6, 7, 2]);
+    let n = list_from([-1, 0, 0, 7, 7, 9]);
+    let len = m.len() + n.len();
+    m.merge(n, |a, b| a <= b);
+    assert_eq!(m.len(), len);
+    check_links(&m);
+    let res = m.consume_iter().collect::<~[int]>();
+    assert_eq!(res, ~[-1, 0, 0, 1, 0, 3, 5, 6, 7, 2, 7, 7, 9]);
+}
+
+#[test]
+fn test_insert_ordered() {
+    let mut n = List::new();
+    n.insert_ordered(1);
+    assert_eq!(n.len(), 1);
+    assert_eq!(n.pop_front(), Some(1));
+
+    let mut m = List::new();
+    m.push_back(2);
+    m.push_back(4);
+    m.insert_ordered(3);
+    check_links(&m);
+    assert_eq!(~[2,3,4], m.consume_iter().collect::<~[int]>());
+}
+
+#[test]
+fn test_mut_rev_iter() {
+    let mut m = generate_test();
+    for m.mut_rev_iter().enumerate().advance |(i, elt)| {
+        assert_eq!((6-i) as int, *elt);
+    }
+    let mut n = List::new();
+    assert!(n.mut_rev_iter().next().is_none());
+    n.push_front(4);
+    let mut it = n.mut_rev_iter();
+    assert!(it.next().is_some());
+    assert!(it.next().is_none());
+}
+
+#[test]
+fn test_send() {
+    let n = list_from([1,2,3]);
+    do spawn {
+        check_links(&n);
+        assert_eq!(~[&1,&2,&3], n.iter().collect::<~[&int]>());
+    }
+}
+
+#[test]
+fn test_eq() {
+    let mut n: List<u8> = list_from([]);
+    let mut m = list_from([]);
+    assert_eq!(&n, &m);
+    n.push_front(1);
+    assert!(n != m);
+    m.push_back(1);
+    assert_eq!(&n, &m);
+}
+
+#[test]
+fn test_fuzz() {
+    for 25.times {
+        fuzz_test(3);
+        fuzz_test(16);
+        fuzz_test(189);
+    }
+}
+
+#[cfg(test)]
+fn fuzz_test(sz: int) {
+    use std::rand;
+    use std::int;
+
+    let mut m = List::new::<int>();
+    let mut v = ~[];
+    for int::range(0i, sz) |i| {
+        check_links(&m);
+        let r: u8 = rand::random();
+        match r % 6 {
+            0 => {
+                m.pop_back();
+                if v.len() > 0 { v.pop(); }
+            }
+            1 => {
+                m.pop_front();
+                if v.len() > 0 { v.shift(); }
+            }
+            2 | 4 =>  {
+                m.push_front(-i);
+                v.unshift(-i);
+            }
+            3 | 5 | _ => {
+                m.push_back(i);
+                v.push(i);
+            }
+        }
+    }
+
+    check_links(&m);
+
+    let mut i = 0u;
+    for m.consume_iter().zip(v.iter()).advance |(a, &b)| {
+        i += 1;
+        assert_eq!(a, b);
+    }
+    assert_eq!(i, v.len());
+}
+
+#[cfg(test)]
+mod test_bench {
+    use extra::test;
 
     use super::*;
 
-    #[test]
-    fn test_dlist_concat() {
-        let a = from_vec([1,2]);
-        let b = from_vec([3,4]);
-        let c = from_vec([5,6]);
-        let d = from_vec([7,8]);
-        let ab = from_vec([a,b]);
-        let cd = from_vec([c,d]);
-        let abcd = concat(concat(from_vec([ab,cd])));
-        abcd.assert_consistent(); assert_eq!(abcd.len(), 8);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 1);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 2);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 3);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 4);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 5);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 6);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 7);
-        abcd.assert_consistent(); assert_eq!(abcd.pop().get(), 8);
-        abcd.assert_consistent(); assert!(abcd.is_empty());
-    }
-    #[test]
-    fn test_dlist_append() {
-        let a = from_vec([1,2,3]);
-        let b = from_vec([4,5,6]);
-        a.append(b);
-        assert_eq!(a.len(), 6);
-        assert_eq!(b.len(), 0);
-        b.assert_consistent();
-        a.assert_consistent(); assert_eq!(a.pop().get(), 1);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 2);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 3);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 4);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 5);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 6);
-        a.assert_consistent(); assert!(a.is_empty());
-    }
-    #[test]
-    fn test_dlist_append_empty() {
-        let a = from_vec([1,2,3]);
-        let b = DList::<int>();
-        a.append(b);
-        assert_eq!(a.len(), 3);
-        assert_eq!(b.len(), 0);
-        b.assert_consistent();
-        a.assert_consistent(); assert_eq!(a.pop().get(), 1);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 2);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 3);
-        a.assert_consistent(); assert!(a.is_empty());
-    }
-    #[test]
-    fn test_dlist_append_to_empty() {
-        let a = DList::<int>();
-        let b = from_vec([4,5,6]);
-        a.append(b);
-        assert_eq!(a.len(), 3);
-        assert_eq!(b.len(), 0);
-        b.assert_consistent();
-        a.assert_consistent(); assert_eq!(a.pop().get(), 4);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 5);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 6);
-        a.assert_consistent(); assert!(a.is_empty());
-    }
-    #[test]
-    fn test_dlist_append_two_empty() {
-        let a = DList::<int>();
-        let b = DList::<int>();
-        a.append(b);
-        assert_eq!(a.len(), 0);
-        assert_eq!(b.len(), 0);
-        b.assert_consistent();
-        a.assert_consistent();
-    }
-    #[test]
-    #[ignore(cfg(windows))]
-    #[should_fail]
-    fn test_dlist_append_self() {
-        let a = DList::<int>();
-        a.append(a);
-    }
-    #[test]
-    #[ignore(cfg(windows))]
-    #[should_fail]
-    fn test_dlist_prepend_self() {
-        let a = DList::<int>();
-        a.prepend(a);
-    }
-    #[test]
-    fn test_dlist_prepend() {
-        let a = from_vec([1,2,3]);
-        let b = from_vec([4,5,6]);
-        b.prepend(a);
-        assert_eq!(a.len(), 0);
-        assert_eq!(b.len(), 6);
-        a.assert_consistent();
-        b.assert_consistent(); assert_eq!(b.pop().get(), 1);
-        b.assert_consistent(); assert_eq!(b.pop().get(), 2);
-        b.assert_consistent(); assert_eq!(b.pop().get(), 3);
-        b.assert_consistent(); assert_eq!(b.pop().get(), 4);
-        b.assert_consistent(); assert_eq!(b.pop().get(), 5);
-        b.assert_consistent(); assert_eq!(b.pop().get(), 6);
-        b.assert_consistent(); assert!(b.is_empty());
-    }
-    #[test]
-    fn test_dlist_reverse() {
-        let a = from_vec([5,4,3,2,1]);
-        a.reverse();
-        assert_eq!(a.len(), 5);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 1);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 2);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 3);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 4);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 5);
-        a.assert_consistent(); assert!(a.is_empty());
-    }
-    #[test]
-    fn test_dlist_reverse_empty() {
-        let a = DList::<int>();
-        a.reverse();
-        assert_eq!(a.len(), 0);
-        a.assert_consistent();
-    }
-    #[test]
-    fn test_dlist_each_node() {
-        let a = from_vec([1,2,4,5]);
-        for a.each_node |nobe| {
-            if nobe.data > 3 {
-                a.insert_before(3, nobe);
-            }
+    #[bench]
+    fn bench_collect_into(b: &mut test::BenchHarness) {
+        let v = &[0, ..64];
+        do b.iter {
+            let _: List<int> = v.iter().transform(|&x|x).collect();
         }
-        assert_eq!(a.len(), 6);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 1);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 2);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 3);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 4);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 3);
-        a.assert_consistent(); assert_eq!(a.pop().get(), 5);
-        a.assert_consistent(); assert!(a.is_empty());
     }
-    #[test]
-    fn test_dlist_clear() {
-        let a = from_vec([5,4,3,2,1]);
-        a.clear();
-        assert_eq!(a.len(), 0);
-        a.assert_consistent();
-    }
-    #[test]
-    fn test_dlist_is_empty() {
-        let empty = DList::<int>();
-        let full1 = from_vec([1,2,3]);
-        assert!(empty.is_empty());
-        assert!(!full1.is_empty());
-    }
-    #[test]
-    fn test_dlist_head_tail() {
-        let l = from_vec([1,2,3]);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.tail(), 3);
-        assert_eq!(l.len(), 3);
-    }
-    #[test]
-    fn test_dlist_pop() {
-        let l = from_vec([1,2,3]);
-        assert_eq!(l.pop().get(), 1);
-        assert_eq!(l.tail(), 3);
-        assert_eq!(l.head(), 2);
-        assert_eq!(l.pop().get(), 2);
-        assert_eq!(l.tail(), 3);
-        assert_eq!(l.head(), 3);
-        assert_eq!(l.pop().get(), 3);
-        assert!(l.is_empty());
-        assert!(l.pop().is_none());
-    }
-    #[test]
-    fn test_dlist_pop_tail() {
-        let l = from_vec([1,2,3]);
-        assert_eq!(l.pop_tail().get(), 3);
-        assert_eq!(l.tail(), 2);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.pop_tail().get(), 2);
-        assert_eq!(l.tail(), 1);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.pop_tail().get(), 1);
-        assert!(l.is_empty());
-        assert!(l.pop_tail().is_none());
-    }
-    #[test]
-    fn test_dlist_push() {
-        let l = DList::<int>();
-        l.push(1);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.tail(), 1);
-        l.push(2);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.tail(), 2);
-        l.push(3);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.tail(), 3);
-        assert_eq!(l.len(), 3);
-    }
-    #[test]
-    fn test_dlist_push_head() {
-        let l = DList::<int>();
-        l.push_head(3);
-        assert_eq!(l.head(), 3);
-        assert_eq!(l.tail(), 3);
-        l.push_head(2);
-        assert_eq!(l.head(), 2);
-        assert_eq!(l.tail(), 3);
-        l.push_head(1);
-        assert_eq!(l.head(), 1);
-        assert_eq!(l.tail(), 3);
-        assert_eq!(l.len(), 3);
-    }
-    #[test]
-    fn test_dlist_break_early() {
-        let l = from_vec([1,2,3,4,5]);
-        let mut x = 0;
-        for l.each |i| {
-            x += 1;
-            if (*i == 3) { break; }
+    #[bench]
+    fn bench_collect_into_vec(b: &mut test::BenchHarness) {
+        let v = &[0, ..64];
+        do b.iter {
+            let _: ~[int] = v.iter().transform(|&x|x).collect();
         }
-        assert_eq!(x, 3);
     }
-    #[test]
-    fn test_dlist_remove_head() {
-        let l = DList::<int>();
-        l.assert_consistent(); let one = l.push_n(1);
-        l.assert_consistent(); let _two = l.push_n(2);
-        l.assert_consistent(); let _three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(one);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); assert_eq!(l.head(), 2);
-        l.assert_consistent(); assert_eq!(l.tail(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert!(l.is_empty());
+
+    #[bench]
+    fn bench_push_front(b: &mut test::BenchHarness) {
+        let mut m = List::new::<int>();
+        do b.iter {
+            m.push_front(0);
+        }
     }
-    #[test]
-    fn test_dlist_remove_mid() {
-        let l = DList::<int>();
-        l.assert_consistent(); let _one = l.push_n(1);
-        l.assert_consistent(); let two = l.push_n(2);
-        l.assert_consistent(); let _three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(two);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); assert_eq!(l.head(), 1);
-        l.assert_consistent(); assert_eq!(l.tail(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert!(l.is_empty());
+    #[bench]
+    fn bench_push_front_vec_size10(b: &mut test::BenchHarness) {
+        let mut m = ~[0, ..10];
+        do b.iter {
+            m.unshift(0);
+            m.pop(); // to keep it fair, dont' grow the vec
+        }
     }
-    #[test]
-    fn test_dlist_remove_tail() {
-        let l = DList::<int>();
-        l.assert_consistent(); let _one = l.push_n(1);
-        l.assert_consistent(); let _two = l.push_n(2);
-        l.assert_consistent(); let three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(three);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); assert_eq!(l.head(), 1);
-        l.assert_consistent(); assert_eq!(l.tail(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert!(l.is_empty());
+
+    #[bench]
+    fn bench_push_back(b: &mut test::BenchHarness) {
+        let mut m = List::new::<int>();
+        do b.iter {
+            m.push_back(0);
+        }
     }
-    #[test]
-    fn test_dlist_remove_one_two() {
-        let l = DList::<int>();
-        l.assert_consistent(); let one = l.push_n(1);
-        l.assert_consistent(); let two = l.push_n(2);
-        l.assert_consistent(); let _three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(one);
-        l.assert_consistent(); l.remove(two);
-        // and through and through, the vorpal blade went snicker-snack
-        l.assert_consistent(); assert_eq!(l.len(), 1);
-        l.assert_consistent(); assert_eq!(l.head(), 3);
-        l.assert_consistent(); assert_eq!(l.tail(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert!(l.is_empty());
+    #[bench]
+    fn bench_push_back_vec(b: &mut test::BenchHarness) {
+        let mut m = ~[];
+        do b.iter {
+            m.push(0);
+        }
     }
-    #[test]
-    fn test_dlist_remove_one_three() {
-        let l = DList::<int>();
-        l.assert_consistent(); let one = l.push_n(1);
-        l.assert_consistent(); let _two = l.push_n(2);
-        l.assert_consistent(); let three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(one);
-        l.assert_consistent(); l.remove(three);
-        l.assert_consistent(); assert_eq!(l.len(), 1);
-        l.assert_consistent(); assert_eq!(l.head(), 2);
-        l.assert_consistent(); assert_eq!(l.tail(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert!(l.is_empty());
+
+    #[bench]
+    fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
+        let mut m = List::new::<int>();
+        do b.iter {
+            m.push_back(0);
+            m.pop_back();
+        }
     }
-    #[test]
-    fn test_dlist_remove_two_three() {
-        let l = DList::<int>();
-        l.assert_consistent(); let _one = l.push_n(1);
-        l.assert_consistent(); let two = l.push_n(2);
-        l.assert_consistent(); let three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(two);
-        l.assert_consistent(); l.remove(three);
-        l.assert_consistent(); assert_eq!(l.len(), 1);
-        l.assert_consistent(); assert_eq!(l.head(), 1);
-        l.assert_consistent(); assert_eq!(l.tail(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert!(l.is_empty());
+    #[bench]
+    fn bench_push_back_pop_back_vec(b: &mut test::BenchHarness) {
+        let mut m = ~[];
+        do b.iter {
+            m.push(0);
+            m.pop();
+        }
     }
-    #[test]
-    fn test_dlist_remove_all() {
-        let l = DList::<int>();
-        l.assert_consistent(); let one = l.push_n(1);
-        l.assert_consistent(); let two = l.push_n(2);
-        l.assert_consistent(); let three = l.push_n(3);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); l.remove(two);
-        l.assert_consistent(); l.remove(three);
-        l.assert_consistent(); l.remove(one); // Twenty-three is number one!
-        l.assert_consistent(); assert!(l.peek().is_none());
-        l.assert_consistent(); assert!(l.is_empty());
+
+    #[bench]
+    fn bench_iter(b: &mut test::BenchHarness) {
+        let v = &[0, ..128];
+        let m: List<int> = v.iter().transform(|&x|x).collect();
+        do b.iter {
+            for m.iter().advance |_| {}
+        }
     }
-    #[test]
-    fn test_dlist_insert_n_before() {
-        let l = DList::<int>();
-        l.assert_consistent(); let _one = l.push_n(1);
-        l.assert_consistent(); let two = l.push_n(2);
-        l.assert_consistent(); let three = new_dlist_node(3);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); l.insert_n_before(three, two);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); assert_eq!(l.head(), 1);
-        l.assert_consistent(); assert_eq!(l.tail(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert!(l.is_empty());
+    #[bench]
+    fn bench_iter_mut(b: &mut test::BenchHarness) {
+        let v = &[0, ..128];
+        let mut m: List<int> = v.iter().transform(|&x|x).collect();
+        do b.iter {
+            for m.mut_iter().advance |_| {}
+        }
     }
-    #[test]
-    fn test_dlist_insert_n_after() {
-        let l = DList::<int>();
-        l.assert_consistent(); let one = l.push_n(1);
-        l.assert_consistent(); let _two = l.push_n(2);
-        l.assert_consistent(); let three = new_dlist_node(3);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); l.insert_n_after(three, one);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); assert_eq!(l.head(), 1);
-        l.assert_consistent(); assert_eq!(l.tail(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert!(l.is_empty());
+    #[bench]
+    fn bench_iter_rev(b: &mut test::BenchHarness) {
+        let v = &[0, ..128];
+        let m: List<int> = v.iter().transform(|&x|x).collect();
+        do b.iter {
+            for m.rev_iter().advance |_| {}
+        }
     }
-    #[test]
-    fn test_dlist_insert_before_head() {
-        let l = DList::<int>();
-        l.assert_consistent(); let one = l.push_n(1);
-        l.assert_consistent(); let _two = l.push_n(2);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); l.insert_before(3, one);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); assert_eq!(l.head(), 3);
-        l.assert_consistent(); assert_eq!(l.tail(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert!(l.is_empty());
+    #[bench]
+    fn bench_iter_mut_rev(b: &mut test::BenchHarness) {
+        let v = &[0, ..128];
+        let mut m: List<int> = v.iter().transform(|&x|x).collect();
+        do b.iter {
+            for m.mut_rev_iter().advance |_| {}
+        }
     }
-    #[test]
-    fn test_dlist_insert_after_tail() {
-        let l = DList::<int>();
-        l.assert_consistent(); let _one = l.push_n(1);
-        l.assert_consistent(); let two = l.push_n(2);
-        l.assert_consistent(); assert_eq!(l.len(), 2);
-        l.assert_consistent(); l.insert_after(3, two);
-        l.assert_consistent(); assert_eq!(l.len(), 3);
-        l.assert_consistent(); assert_eq!(l.head(), 1);
-        l.assert_consistent(); assert_eq!(l.tail(), 3);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 1);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 2);
-        l.assert_consistent(); assert_eq!(l.pop().get(), 3);
-        l.assert_consistent(); assert!(l.is_empty());
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_asymmetric_link() {
-        let l = DList::<int>();
-        let _one = l.push_n(1);
-        let two = l.push_n(2);
-        two.prev = None;
-        l.assert_consistent();
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_cyclic_list() {
-        let l = DList::<int>();
-        let one = l.push_n(1);
-        let _two = l.push_n(2);
-        let three = l.push_n(3);
-        three.next = Some(one);
-        one.prev = Some(three);
-        l.assert_consistent();
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_headless() {
-        DList::<int>().head();
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_insert_already_present_before() {
-        let l = DList::<int>();
-        let one = l.push_n(1);
-        let two = l.push_n(2);
-        l.insert_n_before(two, one);
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_insert_already_present_after() {
-        let l = DList::<int>();
-        let one = l.push_n(1);
-        let two = l.push_n(2);
-        l.insert_n_after(one, two);
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_insert_before_orphan() {
-        let l = DList::<int>();
-        let one = new_dlist_node(1);
-        let two = new_dlist_node(2);
-        l.insert_n_before(one, two);
-    }
-    #[test] #[should_fail] #[ignore(cfg(windows))]
-    fn test_dlist_insert_after_orphan() {
-        let l = DList::<int>();
-        let one = new_dlist_node(1);
-        let two = new_dlist_node(2);
-        l.insert_n_after(two, one);
+    #[bench]
+    fn bench_iter_vec(b: &mut test::BenchHarness) {
+        let v = &[0, ..128];
+        do b.iter {
+            for v.iter().advance |_| {}
+        }
     }
 }
+
diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs
index b1383948bf7..5a9072a68d8 100644
--- a/src/libextra/serialize.rs
+++ b/src/libextra/serialize.rs
@@ -24,7 +24,7 @@ use std::trie::{TrieMap, TrieSet};
 use std::uint;
 use std::vec;
 use deque::Deque;
-use dlist::DList;
+use dlist::List;
 use treemap::{TreeMap, TreeSet};
 
 pub trait Encoder {
@@ -652,11 +652,11 @@ impl<
 impl<
     S: Encoder,
     T: Encodable<S> + Copy
-> Encodable<S> for @mut DList<T> {
+> Encodable<S> for List<T> {
     fn encode(&self, s: &mut S) {
-        do s.emit_seq(self.size) |s| {
+        do s.emit_seq(self.len()) |s| {
             let mut i = 0;
-            for self.each |e| {
+            for self.iter().advance |e| {
                 s.emit_seq_elt(i, |s| e.encode(s));
                 i += 1;
             }
@@ -664,12 +664,12 @@ impl<
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for @mut DList<T> {
-    fn decode(d: &mut D) -> @mut DList<T> {
-        let list = DList();
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for List<T> {
+    fn decode(d: &mut D) -> List<T> {
+        let mut list = List::new();
         do d.read_seq |d, len| {
             for uint::range(0, len) |i| {
-                list.push(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
             }
         }
         list

From f97e64083b10e06286eb621f9dff918362e03fc1 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Tue, 9 Jul 2013 16:55:04 +0200
Subject: [PATCH 02/12] dlist: Implement size_hint properly for all iterators

---
 src/libextra/dlist.rs | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index d3132b37345..ed8ba8105b1 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -39,24 +39,28 @@ struct Node<T> {
 pub struct ForwardIterator<'self, T> {
     priv list: &'self List<T>,
     priv next: &'self Link<T>,
+    priv nelem: uint,
 }
 
 /// List reverse iterator
 pub struct ReverseIterator<'self, T> {
     priv list: &'self List<T>,
     priv next: Rawlink<T>,
+    priv nelem: uint,
 }
 
 /// List mutable iterator
 pub struct MutForwardIterator<'self, T> {
     priv list: &'self mut List<T>,
     priv curs: Rawlink<T>,
+    priv nelem: uint,
 }
 
 /// List mutable reverse iterator
 pub struct MutReverseIterator<'self, T> {
     priv list: &'self mut List<T>,
     priv next: Rawlink<T>,
+    priv nelem: uint,
 }
 
 /// List consuming iterator
@@ -287,22 +291,22 @@ impl<T> List<T> {
 
     /// Provide a forward iterator
     pub fn iter<'a>(&'a self) -> ForwardIterator<'a, T> {
-        ForwardIterator{list: self, next: &self.list_head}
+        ForwardIterator{nelem: self.len(), list: self, next: &self.list_head}
     }
 
     /// Provide a reverse iterator
     pub fn rev_iter<'a>(&'a self) -> ReverseIterator<'a, T> {
-        ReverseIterator{list: self, next: self.list_tail}
+        ReverseIterator{nelem: self.len(), list: self, next: self.list_tail}
     }
 
     /// Provide a forward iterator with mutable references
     pub fn mut_iter<'a>(&'a mut self) -> MutForwardIterator<'a, T> {
-        MutForwardIterator{list: self, curs: None}
+        MutForwardIterator{nelem: self.len(), list: self, curs: None}
     }
 
     /// Provide a reverse iterator with mutable references
     pub fn mut_rev_iter<'a>(&'a mut self) -> MutReverseIterator<'a, T> {
-        MutReverseIterator{list: self, next: self.list_tail}
+        MutReverseIterator{nelem: self.len(), list: self, next: self.list_tail}
     }
 
 
@@ -332,6 +336,7 @@ impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
         match *self.next {
             None => None,
             Some(ref next) => {
+                self.nelem -= 1;
                 self.next = &next.next;
                 Some(&next.value)
             }
@@ -339,7 +344,7 @@ impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
     }
 
     fn size_hint(&self) -> (uint, Option<uint>) {
-        (0, Some(self.list.length))
+        (self.nelem, Some(self.nelem))
     }
 }
 
@@ -353,6 +358,7 @@ impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
                 match self.list.list_head {
                     None => None,
                     Some(ref mut head) => {
+                        self.nelem -= 1;
                         self.curs = rawlink(&mut **head);
                         Some(&mut head.value)
                     }
@@ -362,6 +368,7 @@ impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
                 match resolve_rawlink(rcurs).next {
                     None => None,
                     Some(ref mut head) => {
+                        self.nelem -= 1;
                         self.curs = rawlink(&mut **head);
                         Some(&mut head.value)
                     }
@@ -371,7 +378,7 @@ impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
     }
 
     fn size_hint(&self) -> (uint, Option<uint>) {
-        (0, Some(self.list.length))
+        (self.nelem, Some(self.nelem))
     }
 }
 
@@ -381,6 +388,7 @@ impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
         match self.next {
             None => None,
             Some(rnext) => {
+                self.nelem -= 1;
                 let prev = resolve_rawlink(rnext);
                 self.next = prev.prev;
                 Some(&prev.value)
@@ -389,7 +397,7 @@ impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
     }
 
     fn size_hint(&self) -> (uint, Option<uint>) {
-        (0, Some(self.list.length))
+        (self.nelem, Some(self.nelem))
     }
 }
 
@@ -399,6 +407,7 @@ impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
         match self.next {
             None => None,
             Some(rnext) => {
+                self.nelem -= 1;
                 let prev = resolve_rawlink(rnext);
                 self.next = prev.prev;
                 Some(&mut prev.value)
@@ -407,7 +416,7 @@ impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
     }
 
     fn size_hint(&self) -> (uint, Option<uint>) {
-        (0, Some(self.list.length))
+        (self.nelem, Some(self.nelem))
     }
 }
 
@@ -628,7 +637,9 @@ fn test_iterator() {
     assert_eq!(n.iter().next(), None);
     n.push_front(4);
     let mut it = n.iter();
+    assert_eq!(it.size_hint(), (1, Some(1)));
     assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.size_hint(), (0, Some(0)));
     assert_eq!(it.next(), None);
 }
 
@@ -642,7 +653,9 @@ fn test_rev_iter() {
     assert_eq!(n.rev_iter().next(), None);
     n.push_front(4);
     let mut it = n.rev_iter();
+    assert_eq!(it.size_hint(), (1, Some(1)));
     assert_eq!(it.next().unwrap(), &4);
+    assert_eq!(it.size_hint(), (0, Some(0)));
     assert_eq!(it.next(), None);
 }
 
@@ -659,7 +672,9 @@ fn test_mut_iter() {
     assert!(n.mut_iter().next().is_none());
     n.push_front(4);
     let mut it = n.mut_iter();
+    assert_eq!(it.size_hint(), (1, Some(1)));
     assert!(it.next().is_some());
+    assert_eq!(it.size_hint(), (0, Some(0)));
     assert!(it.next().is_none());
 }
 

From 7b1c57713d331266d632c4fa11d4cdfaaa895ac7 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 03:49:32 +0200
Subject: [PATCH 03/12] dlist: Introduce a struct Rawlink mimicing Option<T>
 for a raw pointer

Rawlink<T> holds a *mut T pointer and can convert itself to Option<&mut T>.
The null pointer is of course None.
---
 src/libextra/dlist.rs | 135 +++++++++++++++++++++++-------------------
 1 file changed, 73 insertions(+), 62 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index ed8ba8105b1..b197ea83fdc 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -13,6 +13,7 @@
 
 use std::cast;
 use std::cmp;
+use std::ptr;
 use std::util;
 use std::iterator::FromIterator;
 
@@ -20,18 +21,15 @@ use std::iterator::FromIterator;
 pub struct List<T> {
     priv length: uint,
     priv list_head: Link<T>,
-    priv list_tail: Rawlink<T>,
+    priv list_tail: Rawlink<Node<T>>,
 }
 
 type Link<T> = Option<~Node<T>>;
-type Rawlink<T> = Option<&'static Node<T>>;
-// Rawlink uses &'static to have a small Option<&'> represenation.
-// FIXME: Use a raw pointer like *mut Node if possible.
-// FIXME: Causes infinite recursion in %? repr
+struct Rawlink<T> { priv p: *mut T }
 
 struct Node<T> {
     priv next: Link<T>,
-    priv prev: Rawlink<T>,
+    priv prev: Rawlink<Node<T>>,
     priv value: T,
 }
 
@@ -45,21 +43,21 @@ pub struct ForwardIterator<'self, T> {
 /// List reverse iterator
 pub struct ReverseIterator<'self, T> {
     priv list: &'self List<T>,
-    priv next: Rawlink<T>,
+    priv next: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
 /// List mutable iterator
 pub struct MutForwardIterator<'self, T> {
     priv list: &'self mut List<T>,
-    priv curs: Rawlink<T>,
+    priv curs: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
 /// List mutable reverse iterator
 pub struct MutReverseIterator<'self, T> {
     priv list: &'self mut List<T>,
-    priv next: Rawlink<T>,
+    priv next: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
@@ -73,6 +71,33 @@ pub struct ConsumeRevIterator<T> {
     priv list: List<T>
 }
 
+/// Rawlink is a type like Option<T> but for holding a raw pointer
+impl<T> Rawlink<T> {
+    /// Like Option::None for Rawlink
+    fn none() -> Rawlink<T> {
+        Rawlink{p: ptr::mut_null()}
+    }
+
+    /// Like Option::Some for Rawlink
+    fn some(n: &mut T) -> Rawlink<T> {
+        Rawlink{p: ptr::to_mut_unsafe_ptr(n)}
+    }
+
+    /// Convert the `Rawlink` into an Option value
+    fn resolve_immut(&self) -> Option<&T> {
+        unsafe { self.p.to_option() }
+    }
+
+    /// Convert the `Rawlink` into an Option value
+    fn resolve(&mut self) -> Option<&mut T> {
+        if self.p.is_null() {
+            None
+        } else {
+            Some(unsafe { cast::transmute(self.p) })
+        }
+    }
+}
+
 impl<T> Container for List<T> {
     /// O(1)
     fn is_empty(&self) -> bool {
@@ -93,19 +118,11 @@ impl<T> Mutable for List<T> {
     }
 }
 
-/// Cast the raw link into a borrowed ref
-fn resolve_rawlink<T>(lnk: &'static Node<T>) -> &mut Node<T> {
-    unsafe { cast::transmute_mut(lnk) }
-}
-fn rawlink<T>(n: &mut Node<T>) -> Rawlink<T> {
-    Some(unsafe { cast::transmute(n) })
-}
-
 impl<T> List<T> {
     /// Create an empty List
     #[inline]
     pub fn new() -> List<T> {
-        List{list_head: None, list_tail: None, length: 0}
+        List{list_head: None, list_tail: Rawlink::none(), length: 0}
     }
 
     /// Provide a reference to the front element, or None if the list is empty
@@ -123,17 +140,17 @@ impl<T> List<T> {
 
     /// Provide a reference to the back element, or None if the list is empty
     pub fn peek_back<'a>(&'a self) -> Option<&'a T> {
-        match self.list_tail {
+        match self.list_tail.resolve_immut() {
             None => None,
-            Some(tail) => Some(&resolve_rawlink(tail).value),
+            Some(tail) => Some(&tail.value),
         }
     }
 
     /// Provide a mutable reference to the back element, or None if the list is empty
     pub fn peek_back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
-        match self.list_tail {
+        match self.list_tail.resolve() {
             None => None,
-            Some(tail) => Some(&mut resolve_rawlink(tail).value),
+            Some(tail) => Some(&mut tail.value),
         }
     }
 
@@ -141,12 +158,11 @@ impl<T> List<T> {
     ///
     /// O(1)
     pub fn push_back(&mut self, elt: T) {
-        match self.list_tail {
+        match self.list_tail.resolve() {
             None => return self.push_front(elt),
-            Some(rtail) => {
+            Some(tail) => {
                 let mut new_tail = ~Node{value: elt, next: None, prev: self.list_tail};
-                self.list_tail = rawlink(new_tail);
-                let tail = resolve_rawlink(rtail);
+                self.list_tail = Rawlink::some(new_tail);
                 tail.next = Some(new_tail);
             }
         }
@@ -158,19 +174,18 @@ impl<T> List<T> {
     /// O(1)
     #[inline]
     pub fn pop_back(&mut self) -> Option<T> {
-        match self.list_tail {
+        match self.list_tail.resolve() {
             None => None,
-            Some(rtail) => {
+            Some(tail) => {
                 self.length -= 1;
-                let tail = resolve_rawlink(rtail);
-                let tail_own = match tail.prev {
+                let tail_own = match tail.prev.resolve() {
                     None => {
-                        self.list_tail = None;
+                        self.list_tail = Rawlink::none();
                         self.list_head.swap_unwrap()
                     },
-                    Some(rtail_prev) => {
+                    Some(tail_prev) => {
                         self.list_tail = tail.prev;
-                        resolve_rawlink(rtail_prev).next.swap_unwrap()
+                        tail_prev.next.swap_unwrap()
                     }
                 };
                 Some(tail_own.value)
@@ -182,14 +197,14 @@ impl<T> List<T> {
     ///
     /// O(1)
     pub fn push_front(&mut self, elt: T) {
-        let mut new_head = ~Node{value: elt, next: None, prev: None};
+        let mut new_head = ~Node{value: elt, next: None, prev: Rawlink::none()};
         match self.list_head {
             None => {
-                self.list_tail = rawlink(new_head);
+                self.list_tail = Rawlink::some(new_head);
                 self.list_head = Some(new_head);
             }
             Some(ref mut head) => {
-                head.prev = rawlink(new_head);
+                head.prev = Rawlink::some(new_head);
                 util::swap(head, &mut new_head);
                 head.next = Some(new_head);
             }
@@ -208,12 +223,12 @@ impl<T> List<T> {
                 match *head.swap_unwrap() {
                     Node{value: value, next: Some(next), prev: _} => {
                         let mut mnext = next;
-                        mnext.prev = None;
+                        mnext.prev = Rawlink::none();
                         *head = Some(mnext);
                         Some(value)
                     }
                     Node{value: value, next: None, prev: _} => {
-                        self.list_tail = None;
+                        self.list_tail = Rawlink::none();
                         *head = None;
                         Some(value)
                     }
@@ -226,14 +241,13 @@ impl<T> List<T> {
     ///
     /// O(1)
     pub fn append(&mut self, other: List<T>) {
-        match self.list_tail {
+        match self.list_tail.resolve() {
             None => *self = other,
-            Some(rtail) => {
+            Some(tail) => {
                 match other {
                     List{list_head: None, list_tail: _, length: _} => return,
                     List{list_head: Some(node), list_tail: o_tail, length: o_length} => {
                         let mut lnk_node = node;
-                        let tail = resolve_rawlink(rtail);
                         lnk_node.prev = self.list_tail;
                         tail.next = Some(lnk_node);
                         self.list_tail = o_tail;
@@ -301,7 +315,7 @@ impl<T> List<T> {
 
     /// Provide a forward iterator with mutable references
     pub fn mut_iter<'a>(&'a mut self) -> MutForwardIterator<'a, T> {
-        MutForwardIterator{nelem: self.len(), list: self, curs: None}
+        MutForwardIterator{nelem: self.len(), list: self, curs: Rawlink::none()}
     }
 
     /// Provide a reverse iterator with mutable references
@@ -353,23 +367,23 @@ impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
 impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
     #[inline]
     fn next(&mut self) -> Option<&'self mut A> {
-        match self.curs {
+        match self.curs.resolve() {
             None => {
                 match self.list.list_head {
                     None => None,
                     Some(ref mut head) => {
                         self.nelem -= 1;
-                        self.curs = rawlink(&mut **head);
+                        self.curs = Rawlink::some(*head);
                         Some(&mut head.value)
                     }
                 }
             }
-            Some(rcurs) => {
-                match resolve_rawlink(rcurs).next {
+            Some(curs) => {
+                match curs.next {
                     None => None,
                     Some(ref mut head) => {
                         self.nelem -= 1;
-                        self.curs = rawlink(&mut **head);
+                        self.curs = Rawlink::some(*head);
                         Some(&mut head.value)
                     }
                 }
@@ -385,11 +399,10 @@ impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
 impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
     #[inline]
     fn next(&mut self) -> Option<&'self A> {
-        match self.next {
+        match self.next.resolve() {
             None => None,
-            Some(rnext) => {
+            Some(prev) => {
                 self.nelem -= 1;
-                let prev = resolve_rawlink(rnext);
                 self.next = prev.prev;
                 Some(&prev.value)
             }
@@ -404,11 +417,10 @@ impl<'self, A> Iterator<&'self A> for ReverseIterator<'self, A> {
 impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
     #[inline]
     fn next(&mut self) -> Option<&'self mut A> {
-        match self.next {
+        match self.next.resolve() {
             None => None,
-            Some(rnext) => {
+            Some(prev) => {
                 self.nelem -= 1;
-                let prev = resolve_rawlink(rnext);
                 self.next = prev.prev;
                 Some(&mut prev.value)
             }
@@ -428,19 +440,18 @@ trait ListInsertCursor<A> {
 
 impl<'self, A> ListInsertCursor<A> for MutForwardIterator<'self, A> {
     fn insert_before(&mut self, elt: A) {
-        match self.curs {
+        match self.curs.resolve() {
             None => self.list.push_front(elt),
-            Some(rcurs) => {
-                let node = resolve_rawlink(rcurs);
-                let prev_node = match node.prev {
+            Some(node) => {
+                let prev_node = match node.prev.resolve() {
                     None => return self.list.push_front(elt),  // at head
-                    Some(rprev) => resolve_rawlink(rprev),
+                    Some(prev) => prev,
                 };
                 let mut node_own = prev_node.next.swap_unwrap();
                 let mut ins_node = ~Node{value: elt,
                                          next: None,
-                                         prev: rawlink(prev_node)};
-                node_own.prev = rawlink(ins_node);
+                                         prev: Rawlink::some(prev_node)};
+                node_own.prev = Rawlink::some(ins_node);
                 ins_node.next = Some(node_own);
                 prev_node.next = Some(ins_node);
                 self.list.length += 1;
@@ -497,11 +508,11 @@ fn check_links<T>(list: &List<T>) {
         Some(ref node) => node_ptr = &**node,
     }
     loop {
-        match (last_ptr, node_ptr.prev) {
+        match (last_ptr, node_ptr.prev.resolve_immut()) {
             (None   , None      ) => {}
             (None   , _         ) => fail!("prev link for list_head"),
             (Some(p), Some(pptr)) => {
-                assert_eq!((p as *Node<T>) as uint, pptr as *Node<T> as uint);
+                assert_eq!(p as *Node<T>, pptr as *Node<T>);
             }
             _ => fail!("prev link is none, not good"),
         }

From 8d06efb8ea0857844f856ab5fd87aed89d4bf718 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 03:49:32 +0200
Subject: [PATCH 04/12] dlist: Collect a common pattern into link_with_prev()

---
 src/libextra/dlist.rs | 32 +++++++++++++++-----------------
 1 file changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index b197ea83fdc..46a3a7d6e15 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -98,6 +98,12 @@ impl<T> Rawlink<T> {
     }
 }
 
+/// Set the .prev field on `next`, then return `Some(next)`
+fn link_with_prev<T>(mut next: ~Node<T>, prev: Rawlink<Node<T>>) -> Link<T> {
+    next.prev = prev;
+    Some(next)
+}
+
 impl<T> Container for List<T> {
     /// O(1)
     fn is_empty(&self) -> bool {
@@ -216,20 +222,17 @@ impl<T> List<T> {
     ///
     /// O(1)
     pub fn pop_front(&mut self) -> Option<T> {
-        match self.list_head {
+        match util::replace(&mut self.list_head, None) {
             None => None,
-            ref mut head @ Some(*) => {
+            Some(old_head) => {
                 self.length -= 1;
-                match *head.swap_unwrap() {
+                match *old_head {
                     Node{value: value, next: Some(next), prev: _} => {
-                        let mut mnext = next;
-                        mnext.prev = Rawlink::none();
-                        *head = Some(mnext);
+                        self.list_head = link_with_prev(next, Rawlink::none());
                         Some(value)
                     }
                     Node{value: value, next: None, prev: _} => {
                         self.list_tail = Rawlink::none();
-                        *head = None;
                         Some(value)
                     }
                 }
@@ -247,9 +250,7 @@ impl<T> List<T> {
                 match other {
                     List{list_head: None, list_tail: _, length: _} => return,
                     List{list_head: Some(node), list_tail: o_tail, length: o_length} => {
-                        let mut lnk_node = node;
-                        lnk_node.prev = self.list_tail;
-                        tail.next = Some(lnk_node);
+                        tail.next = link_with_prev(node, self.list_tail);
                         self.list_tail = o_tail;
                         self.length += o_length;
                     }
@@ -447,13 +448,10 @@ impl<'self, A> ListInsertCursor<A> for MutForwardIterator<'self, A> {
                     None => return self.list.push_front(elt),  // at head
                     Some(prev) => prev,
                 };
-                let mut node_own = prev_node.next.swap_unwrap();
-                let mut ins_node = ~Node{value: elt,
-                                         next: None,
-                                         prev: Rawlink::some(prev_node)};
-                node_own.prev = Rawlink::some(ins_node);
-                ins_node.next = Some(node_own);
-                prev_node.next = Some(ins_node);
+                let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()};
+                let node_own = prev_node.next.swap_unwrap();
+                ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node));
+                prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node));
                 self.list.length += 1;
             }
         }

From 4fa69ab97ca4a5d570eec28c0ef979cd829686c6 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 03:49:32 +0200
Subject: [PATCH 05/12] dlist: Put all tests into a tests module

The exception is the function check_links which needs access to struct
Node (which is not pub).
---
 src/libextra/dlist.rs | 556 +++++++++++++++++++++---------------------
 1 file changed, 277 insertions(+), 279 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 46a3a7d6e15..7cca33dbbd3 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -497,7 +497,7 @@ impl<A: Clone> Clone for List<A> {
 }
 
 #[cfg(test)]
-fn check_links<T>(list: &List<T>) {
+pub fn check_links<T>(list: &List<T>) {
     let mut len = 0u;
     let mut last_ptr: Option<&Node<T>> = None;
     let mut node_ptr: &Node<T>;
@@ -529,296 +529,294 @@ fn check_links<T>(list: &List<T>) {
     assert_eq!(len, list.length);
 }
 
-#[test]
-fn test_basic() {
-    let mut m = List::new::<~int>();
-    assert_eq!(m.pop_front(), None);
-    assert_eq!(m.pop_back(), None);
-    assert_eq!(m.pop_front(), None);
-    m.push_front(~1);
-    assert_eq!(m.pop_front(), Some(~1));
-    m.push_back(~2);
-    m.push_back(~3);
-    assert_eq!(m.len(), 2);
-    assert_eq!(m.pop_front(), Some(~2));
-    assert_eq!(m.pop_front(), Some(~3));
-    assert_eq!(m.len(), 0);
-    assert_eq!(m.pop_front(), None);
-    m.push_back(~1);
-    m.push_back(~3);
-    m.push_back(~5);
-    m.push_back(~7);
-    assert_eq!(m.pop_front(), Some(~1));
-
-    let mut n = List::new();
-    n.push_front(2);
-    n.push_front(3);
-    {
-        assert_eq!(n.peek_front().unwrap(), &3);
-        let x = n.peek_front_mut().unwrap();
-        assert_eq!(*x, 3);
-        *x = 0;
-    }
-    {
-        assert_eq!(n.peek_back().unwrap(), &2);
-        let y = n.peek_back_mut().unwrap();
-        assert_eq!(*y, 2);
-        *y = 1;
-    }
-    assert_eq!(n.pop_front(), Some(0));
-    assert_eq!(n.pop_front(), Some(1));
-}
-
 #[cfg(test)]
-fn generate_test() -> List<int> {
-    list_from(&[0,1,2,3,4,5,6])
-}
-
-#[cfg(test)]
-fn list_from<T: Copy>(v: &[T]) -> List<T> {
-    v.iter().transform(|x| copy *x).collect()
-}
-
-#[test]
-fn test_append() {
-    {
-        let mut m = List::new();
-        let mut n = List::new();
-        n.push_back(2);
-        m.append(n);
-        assert_eq!(m.len(), 1);
-        assert_eq!(m.pop_back(), Some(2));
-        check_links(&m);
-    }
-    {
-        let mut m = List::new();
-        let n = List::new();
-        m.push_back(2);
-        m.append(n);
-        assert_eq!(m.len(), 1);
-        assert_eq!(m.pop_back(), Some(2));
-        check_links(&m);
-    }
-
-    let v = ~[1,2,3,4,5];
-    let u = ~[9,8,1,2,3,4,5];
-    let mut m = list_from(v);
-    m.append(list_from(u));
-    check_links(&m);
-    let sum = v + u;
-    assert_eq!(sum.len(), m.len());
-    for sum.consume_iter().advance |elt| {
-        assert_eq!(m.pop_front(), Some(elt))
-    }
-}
-
-#[test]
-fn test_prepend() {
-    {
-        let mut m = List::new();
-        let mut n = List::new();
-        n.push_back(2);
-        m.prepend(n);
-        assert_eq!(m.len(), 1);
-        assert_eq!(m.pop_back(), Some(2));
-        check_links(&m);
-    }
-
-    let v = ~[1,2,3,4,5];
-    let u = ~[9,8,1,2,3,4,5];
-    let mut m = list_from(v);
-    m.prepend(list_from(u));
-    check_links(&m);
-    let sum = u + v;
-    assert_eq!(sum.len(), m.len());
-    for sum.consume_iter().advance |elt| {
-        assert_eq!(m.pop_front(), Some(elt))
-    }
-}
-
-#[test]
-fn test_iterator() {
-    let m = generate_test();
-    for m.iter().enumerate().advance |(i, elt)| {
-        assert_eq!(i as int, *elt);
-    }
-    let mut n = List::new();
-    assert_eq!(n.iter().next(), None);
-    n.push_front(4);
-    let mut it = n.iter();
-    assert_eq!(it.size_hint(), (1, Some(1)));
-    assert_eq!(it.next().unwrap(), &4);
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_rev_iter() {
-    let m = generate_test();
-    for m.rev_iter().enumerate().advance |(i, elt)| {
-        assert_eq!((6 - i) as int, *elt);
-    }
-    let mut n = List::new();
-    assert_eq!(n.rev_iter().next(), None);
-    n.push_front(4);
-    let mut it = n.rev_iter();
-    assert_eq!(it.size_hint(), (1, Some(1)));
-    assert_eq!(it.next().unwrap(), &4);
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert_eq!(it.next(), None);
-}
-
-#[test]
-fn test_mut_iter() {
-    let mut m = generate_test();
-    let mut len = m.len();
-    for m.mut_iter().enumerate().advance |(i, elt)| {
-        assert_eq!(i as int, *elt);
-        len -= 1;
-    }
-    assert_eq!(len, 0);
-    let mut n = List::new();
-    assert!(n.mut_iter().next().is_none());
-    n.push_front(4);
-    let mut it = n.mut_iter();
-    assert_eq!(it.size_hint(), (1, Some(1)));
-    assert!(it.next().is_some());
-    assert_eq!(it.size_hint(), (0, Some(0)));
-    assert!(it.next().is_none());
-}
-
-#[test]
-fn test_list_cursor() {
-    let mut m = generate_test();
-    let len = m.len();
-    {
-        let mut it = m.mut_iter();
-        loop {
-            match it.next() {
-                None => break,
-                Some(elt) => it.insert_before(*elt * 2),
-            }
-        }
-    }
-    assert_eq!(m.len(), len * 2);
-    check_links(&m);
-}
-
-#[test]
-fn test_merge() {
-    let mut m = list_from([0, 1, 3, 5, 6, 7, 2]);
-    let n = list_from([-1, 0, 0, 7, 7, 9]);
-    let len = m.len() + n.len();
-    m.merge(n, |a, b| a <= b);
-    assert_eq!(m.len(), len);
-    check_links(&m);
-    let res = m.consume_iter().collect::<~[int]>();
-    assert_eq!(res, ~[-1, 0, 0, 1, 0, 3, 5, 6, 7, 2, 7, 7, 9]);
-}
-
-#[test]
-fn test_insert_ordered() {
-    let mut n = List::new();
-    n.insert_ordered(1);
-    assert_eq!(n.len(), 1);
-    assert_eq!(n.pop_front(), Some(1));
-
-    let mut m = List::new();
-    m.push_back(2);
-    m.push_back(4);
-    m.insert_ordered(3);
-    check_links(&m);
-    assert_eq!(~[2,3,4], m.consume_iter().collect::<~[int]>());
-}
-
-#[test]
-fn test_mut_rev_iter() {
-    let mut m = generate_test();
-    for m.mut_rev_iter().enumerate().advance |(i, elt)| {
-        assert_eq!((6-i) as int, *elt);
-    }
-    let mut n = List::new();
-    assert!(n.mut_rev_iter().next().is_none());
-    n.push_front(4);
-    let mut it = n.mut_rev_iter();
-    assert!(it.next().is_some());
-    assert!(it.next().is_none());
-}
-
-#[test]
-fn test_send() {
-    let n = list_from([1,2,3]);
-    do spawn {
-        check_links(&n);
-        assert_eq!(~[&1,&2,&3], n.iter().collect::<~[&int]>());
-    }
-}
-
-#[test]
-fn test_eq() {
-    let mut n: List<u8> = list_from([]);
-    let mut m = list_from([]);
-    assert_eq!(&n, &m);
-    n.push_front(1);
-    assert!(n != m);
-    m.push_back(1);
-    assert_eq!(&n, &m);
-}
-
-#[test]
-fn test_fuzz() {
-    for 25.times {
-        fuzz_test(3);
-        fuzz_test(16);
-        fuzz_test(189);
-    }
-}
-
-#[cfg(test)]
-fn fuzz_test(sz: int) {
+mod tests {
+    use super::*;
     use std::rand;
     use std::int;
+    use extra::test;
 
-    let mut m = List::new::<int>();
-    let mut v = ~[];
-    for int::range(0i, sz) |i| {
+    #[test]
+    fn test_basic() {
+        let mut m = List::new::<~int>();
+        assert_eq!(m.pop_front(), None);
+        assert_eq!(m.pop_back(), None);
+        assert_eq!(m.pop_front(), None);
+        m.push_front(~1);
+        assert_eq!(m.pop_front(), Some(~1));
+        m.push_back(~2);
+        m.push_back(~3);
+        assert_eq!(m.len(), 2);
+        assert_eq!(m.pop_front(), Some(~2));
+        assert_eq!(m.pop_front(), Some(~3));
+        assert_eq!(m.len(), 0);
+        assert_eq!(m.pop_front(), None);
+        m.push_back(~1);
+        m.push_back(~3);
+        m.push_back(~5);
+        m.push_back(~7);
+        assert_eq!(m.pop_front(), Some(~1));
+
+        let mut n = List::new();
+        n.push_front(2);
+        n.push_front(3);
+        {
+            assert_eq!(n.peek_front().unwrap(), &3);
+            let x = n.peek_front_mut().unwrap();
+            assert_eq!(*x, 3);
+            *x = 0;
+        }
+        {
+            assert_eq!(n.peek_back().unwrap(), &2);
+            let y = n.peek_back_mut().unwrap();
+            assert_eq!(*y, 2);
+            *y = 1;
+        }
+        assert_eq!(n.pop_front(), Some(0));
+        assert_eq!(n.pop_front(), Some(1));
+    }
+
+    #[cfg(test)]
+    fn generate_test() -> List<int> {
+        list_from(&[0,1,2,3,4,5,6])
+    }
+
+    #[cfg(test)]
+    fn list_from<T: Copy>(v: &[T]) -> List<T> {
+        v.iter().transform(|x| copy *x).collect()
+    }
+
+    #[test]
+    fn test_append() {
+        {
+            let mut m = List::new();
+            let mut n = List::new();
+            n.push_back(2);
+            m.append(n);
+            assert_eq!(m.len(), 1);
+            assert_eq!(m.pop_back(), Some(2));
+            check_links(&m);
+        }
+        {
+            let mut m = List::new();
+            let n = List::new();
+            m.push_back(2);
+            m.append(n);
+            assert_eq!(m.len(), 1);
+            assert_eq!(m.pop_back(), Some(2));
+            check_links(&m);
+        }
+
+        let v = ~[1,2,3,4,5];
+        let u = ~[9,8,1,2,3,4,5];
+        let mut m = list_from(v);
+        m.append(list_from(u));
         check_links(&m);
-        let r: u8 = rand::random();
-        match r % 6 {
-            0 => {
-                m.pop_back();
-                if v.len() > 0 { v.pop(); }
-            }
-            1 => {
-                m.pop_front();
-                if v.len() > 0 { v.shift(); }
-            }
-            2 | 4 =>  {
-                m.push_front(-i);
-                v.unshift(-i);
-            }
-            3 | 5 | _ => {
-                m.push_back(i);
-                v.push(i);
-            }
+        let sum = v + u;
+        assert_eq!(sum.len(), m.len());
+        for sum.consume_iter().advance |elt| {
+            assert_eq!(m.pop_front(), Some(elt))
         }
     }
 
-    check_links(&m);
+    #[test]
+    fn test_prepend() {
+        {
+            let mut m = List::new();
+            let mut n = List::new();
+            n.push_back(2);
+            m.prepend(n);
+            assert_eq!(m.len(), 1);
+            assert_eq!(m.pop_back(), Some(2));
+            check_links(&m);
+        }
 
-    let mut i = 0u;
-    for m.consume_iter().zip(v.iter()).advance |(a, &b)| {
-        i += 1;
-        assert_eq!(a, b);
+        let v = ~[1,2,3,4,5];
+        let u = ~[9,8,1,2,3,4,5];
+        let mut m = list_from(v);
+        m.prepend(list_from(u));
+        check_links(&m);
+        let sum = u + v;
+        assert_eq!(sum.len(), m.len());
+        for sum.consume_iter().advance |elt| {
+            assert_eq!(m.pop_front(), Some(elt))
+        }
     }
-    assert_eq!(i, v.len());
-}
 
-#[cfg(test)]
-mod test_bench {
-    use extra::test;
+    #[test]
+    fn test_iterator() {
+        let m = generate_test();
+        for m.iter().enumerate().advance |(i, elt)| {
+            assert_eq!(i as int, *elt);
+        }
+        let mut n = List::new();
+        assert_eq!(n.iter().next(), None);
+        n.push_front(4);
+        let mut it = n.iter();
+        assert_eq!(it.size_hint(), (1, Some(1)));
+        assert_eq!(it.next().unwrap(), &4);
+        assert_eq!(it.size_hint(), (0, Some(0)));
+        assert_eq!(it.next(), None);
+    }
 
-    use super::*;
+    #[test]
+    fn test_rev_iter() {
+        let m = generate_test();
+        for m.rev_iter().enumerate().advance |(i, elt)| {
+            assert_eq!((6 - i) as int, *elt);
+        }
+        let mut n = List::new();
+        assert_eq!(n.rev_iter().next(), None);
+        n.push_front(4);
+        let mut it = n.rev_iter();
+        assert_eq!(it.size_hint(), (1, Some(1)));
+        assert_eq!(it.next().unwrap(), &4);
+        assert_eq!(it.size_hint(), (0, Some(0)));
+        assert_eq!(it.next(), None);
+    }
+
+    #[test]
+    fn test_mut_iter() {
+        let mut m = generate_test();
+        let mut len = m.len();
+        for m.mut_iter().enumerate().advance |(i, elt)| {
+            assert_eq!(i as int, *elt);
+            len -= 1;
+        }
+        assert_eq!(len, 0);
+        let mut n = List::new();
+        assert!(n.mut_iter().next().is_none());
+        n.push_front(4);
+        let mut it = n.mut_iter();
+        assert_eq!(it.size_hint(), (1, Some(1)));
+        assert!(it.next().is_some());
+        assert_eq!(it.size_hint(), (0, Some(0)));
+        assert!(it.next().is_none());
+    }
+
+    #[test]
+    fn test_list_cursor() {
+        let mut m = generate_test();
+        let len = m.len();
+        {
+            let mut it = m.mut_iter();
+            loop {
+                match it.next() {
+                    None => break,
+                    Some(elt) => it.insert_before(*elt * 2),
+                }
+            }
+        }
+        assert_eq!(m.len(), len * 2);
+        check_links(&m);
+    }
+
+    #[test]
+    fn test_merge() {
+        let mut m = list_from([0, 1, 3, 5, 6, 7, 2]);
+        let n = list_from([-1, 0, 0, 7, 7, 9]);
+        let len = m.len() + n.len();
+        m.merge(n, |a, b| a <= b);
+        assert_eq!(m.len(), len);
+        check_links(&m);
+        let res = m.consume_iter().collect::<~[int]>();
+        assert_eq!(res, ~[-1, 0, 0, 1, 0, 3, 5, 6, 7, 2, 7, 7, 9]);
+    }
+
+    #[test]
+    fn test_insert_ordered() {
+        let mut n = List::new();
+        n.insert_ordered(1);
+        assert_eq!(n.len(), 1);
+        assert_eq!(n.pop_front(), Some(1));
+
+        let mut m = List::new();
+        m.push_back(2);
+        m.push_back(4);
+        m.insert_ordered(3);
+        check_links(&m);
+        assert_eq!(~[2,3,4], m.consume_iter().collect::<~[int]>());
+    }
+
+    #[test]
+    fn test_mut_rev_iter() {
+        let mut m = generate_test();
+        for m.mut_rev_iter().enumerate().advance |(i, elt)| {
+            assert_eq!((6-i) as int, *elt);
+        }
+        let mut n = List::new();
+        assert!(n.mut_rev_iter().next().is_none());
+        n.push_front(4);
+        let mut it = n.mut_rev_iter();
+        assert!(it.next().is_some());
+        assert!(it.next().is_none());
+    }
+
+    #[test]
+    fn test_send() {
+        let n = list_from([1,2,3]);
+        do spawn {
+            check_links(&n);
+            assert_eq!(~[&1,&2,&3], n.iter().collect::<~[&int]>());
+        }
+    }
+
+    #[test]
+    fn test_eq() {
+        let mut n: List<u8> = list_from([]);
+        let mut m = list_from([]);
+        assert_eq!(&n, &m);
+        n.push_front(1);
+        assert!(n != m);
+        m.push_back(1);
+        assert_eq!(&n, &m);
+    }
+
+    #[test]
+    fn test_fuzz() {
+        for 25.times {
+            fuzz_test(3);
+            fuzz_test(16);
+            fuzz_test(189);
+        }
+    }
+
+    #[cfg(test)]
+    fn fuzz_test(sz: int) {
+        let mut m = List::new::<int>();
+        let mut v = ~[];
+        for int::range(0i, sz) |i| {
+            check_links(&m);
+            let r: u8 = rand::random();
+            match r % 6 {
+                0 => {
+                    m.pop_back();
+                    if v.len() > 0 { v.pop(); }
+                }
+                1 => {
+                    m.pop_front();
+                    if v.len() > 0 { v.shift(); }
+                }
+                2 | 4 =>  {
+                    m.push_front(-i);
+                    v.unshift(-i);
+                }
+                3 | 5 | _ => {
+                    m.push_back(i);
+                    v.push(i);
+                }
+            }
+        }
+
+        check_links(&m);
+
+        let mut i = 0u;
+        for m.consume_iter().zip(v.iter()).advance |(a, &b)| {
+            i += 1;
+            assert_eq!(a, b);
+        }
+        assert_eq!(i, v.len());
+    }
 
     #[bench]
     fn bench_collect_into(b: &mut test::BenchHarness) {

From 92842d6516d2c5d92bad553585340f2ae3284308 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 03:49:32 +0200
Subject: [PATCH 06/12] dlist: Expose ListInsertion trait with insert_before
 and peek_next

An iterator that allows mutating the list is very useful but needs care
to not be unsound. ListIteration exposes only insert_before (used for
insert_ordered) and peek_next so far.
---
 src/libextra/dlist.rs | 47 ++++++++++++++++++++++++++++++++-----------
 1 file changed, 35 insertions(+), 12 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 7cca33dbbd3..5722e39eb0f 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -272,7 +272,7 @@ impl<T> List<T> {
     ///
     /// O(N)
     #[inline]
-    pub fn insert_before(&mut self, elt: T, f: &fn(&T, &T) -> bool) {
+    pub fn insert_when(&mut self, elt: T, f: &fn(&T, &T) -> bool) {
         {
             let mut it = self.mut_iter();
             loop {
@@ -341,7 +341,7 @@ impl<T> List<T> {
 /// O(N)
 impl<T: cmp::TotalOrd> List<T> {
     fn insert_ordered(&mut self, elt: T) {
-        self.insert_before(elt, |a, b| a.cmp(b) != cmp::Less);
+        self.insert_when(elt, |a, b| a.cmp(b) != cmp::Less);
     }
 }
 
@@ -363,7 +363,7 @@ impl<'self, A> Iterator<&'self A> for ForwardIterator<'self, A> {
     }
 }
 
-// MutForwardIterator is different because it implements ListInsertCursor,
+// MutForwardIterator is different because it implements ListInsertion,
 // and can modify the list during traversal, used in insert_when and merge.
 impl<'self, A> Iterator<&'self mut A> for MutForwardIterator<'self, A> {
     #[inline]
@@ -433,19 +433,22 @@ impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
     }
 }
 
-// XXX: Should this be `pub`?
-trait ListInsertCursor<A> {
+/// Allow mutating the List while iterating
+pub trait ListInsertion<A> {
     /// Insert `elt` just previous to the most recently yielded element
     fn insert_before(&mut self, elt: A);
+
+    /// Provide a reference to the next element, without changing the iterator
+    fn peek_next<'a>(&'a mut self) -> Option<&'a mut A>;
 }
 
-impl<'self, A> ListInsertCursor<A> for MutForwardIterator<'self, A> {
+impl<'self, A> ListInsertion<A> for MutForwardIterator<'self, A> {
     fn insert_before(&mut self, elt: A) {
         match self.curs.resolve() {
-            None => self.list.push_front(elt),
+            None => { self.list.push_front(elt); self.next(); }
             Some(node) => {
                 let prev_node = match node.prev.resolve() {
-                    None => return self.list.push_front(elt),  // at head
+                    None => return self.list.push_front(elt),
                     Some(prev) => prev,
                 };
                 let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()};
@@ -456,6 +459,16 @@ impl<'self, A> ListInsertCursor<A> for MutForwardIterator<'self, A> {
             }
         }
     }
+
+    fn peek_next<'a>(&'a mut self) -> Option<&'a mut A> {
+        match self.curs.resolve() {
+            None => self.list.peek_front_mut(),
+            Some(curs) => match curs.next {
+                None => None,
+                Some(ref mut node) => Some(&mut node.value),
+            }
+        }
+    }
 }
 
 impl<A> Iterator<A> for ConsumeIterator<A> {
@@ -695,20 +708,30 @@ mod tests {
     }
 
     #[test]
-    fn test_list_cursor() {
-        let mut m = generate_test();
+    fn test_insert_prev() {
+        let mut m = list_from(&[0,2,4,6,8]);
         let len = m.len();
         {
             let mut it = m.mut_iter();
+            it.insert_before(-2);
             loop {
                 match it.next() {
                     None => break,
-                    Some(elt) => it.insert_before(*elt * 2),
+                    Some(elt) => {
+                        it.insert_before(*elt + 1);
+                        match it.peek_next() {
+                            Some(x) => assert_eq!(*x, *elt + 2),
+                            None => assert_eq!(8, *elt),
+                        }
+                    }
                 }
             }
+            it.insert_before(0);
+            it.insert_before(1);
         }
-        assert_eq!(m.len(), len * 2);
         check_links(&m);
+        assert_eq!(m.len(), 3 + len * 2);
+        assert_eq!(m.consume_iter().collect::<~[int]>(), ~[-2,1,0,3,2,5,4,7,6,9,0,1,8]);
     }
 
     #[test]

From 6a95e49fc5bad1367f597bf0eeab7197c9ca226a Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 15:27:14 +0200
Subject: [PATCH 07/12] extra: Add mod container with trait Deque

---
 src/libextra/container.rs | 40 +++++++++++++++++++++++++++++++++++++++
 src/libextra/extra.rs     |  1 +
 2 files changed, 41 insertions(+)
 create mode 100644 src/libextra/container.rs

diff --git a/src/libextra/container.rs b/src/libextra/container.rs
new file mode 100644
index 00000000000..fe622289b29
--- /dev/null
+++ b/src/libextra/container.rs
@@ -0,0 +1,40 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Container traits for extra
+
+use std::container::Mutable;
+
+/// A double-ended sequence that allows querying, insertion and deletion at both ends.
+pub trait Deque<T> : Mutable {
+    /// Provide a reference to the front element, or None if the sequence is empty
+    fn front<'a>(&'a self) -> Option<&'a T>;
+
+    /// Provide a mutable reference to the front element, or None if the sequence is empty
+    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T>;
+
+    /// Provide a reference to the back element, or None if the sequence is empty
+    fn back<'a>(&'a self) -> Option<&'a T>;
+
+    /// Provide a mutable reference to the back element, or None if the sequence is empty
+    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T>;
+
+    /// Insert an element first in the sequence
+    fn push_front(&mut self, elt: T);
+
+    /// Insert an element last in the sequence
+    fn push_back(&mut self, elt: T);
+
+    /// Remove the last element and return it, or None if the sequence is empty
+    fn pop_back(&mut self) -> Option<T>;
+
+    /// Remove the first element and return it, or None if the sequence is empty
+    fn pop_front(&mut self) -> Option<T>;
+}
diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs
index 7bec1d600b4..18322fcda59 100644
--- a/src/libextra/extra.rs
+++ b/src/libextra/extra.rs
@@ -67,6 +67,7 @@ pub mod flatpipes;
 
 // Collections
 
+pub mod container;
 pub mod bitv;
 pub mod deque;
 pub mod fun_treemap;

From 7052371e39268c08067048654a4e115ac86cc51b Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 15:27:14 +0200
Subject: [PATCH 08/12] extra: Rename deque::Deque to ringbuf::RingBuf and impl
 trait Deque

Let RingBuf have a logical name for a concrete type, and Deque is
used for the Deque trait (implemented by RingBuf and dlist).
---
 src/libextra/extra.rs                 |   2 +-
 src/libextra/{deque.rs => ringbuf.rs} | 421 ++++++++++++++------------
 src/libextra/serialize.rs             |  13 +-
 src/test/bench/graph500-bfs.rs        |  11 +-
 src/test/run-pass/issue-2383.rs       |   7 +-
 5 files changed, 239 insertions(+), 215 deletions(-)
 rename src/libextra/{deque.rs => ringbuf.rs} (60%)

diff --git a/src/libextra/extra.rs b/src/libextra/extra.rs
index 18322fcda59..66ee52f53db 100644
--- a/src/libextra/extra.rs
+++ b/src/libextra/extra.rs
@@ -69,9 +69,9 @@ pub mod flatpipes;
 
 pub mod container;
 pub mod bitv;
-pub mod deque;
 pub mod fun_treemap;
 pub mod list;
+pub mod ringbuf;
 pub mod priority_queue;
 pub mod smallintmap;
 
diff --git a/src/libextra/deque.rs b/src/libextra/ringbuf.rs
similarity index 60%
rename from src/libextra/deque.rs
rename to src/libextra/ringbuf.rs
index 9ce5e2c7ba2..28eab9d9012 100644
--- a/src/libextra/deque.rs
+++ b/src/libextra/ringbuf.rs
@@ -11,31 +11,34 @@
 //! A double-ended queue implemented as a circular buffer
 
 use std::num;
+use std::util;
 use std::uint;
 use std::vec;
 use std::iterator::FromIterator;
 
+use container::Deque;
+
 static INITIAL_CAPACITY: uint = 8u; // 2^3
 static MINIMUM_CAPACITY: uint = 2u;
 
 #[allow(missing_doc)]
 #[deriving(Clone)]
-pub struct Deque<T> {
+pub struct RingBuf<T> {
     priv nelts: uint,
     priv lo: uint,
     priv elts: ~[Option<T>]
 }
 
-impl<T> Container for Deque<T> {
-    /// Return the number of elements in the deque
+impl<T> Container for RingBuf<T> {
+    /// Return the number of elements in the RingBuf
     fn len(&self) -> uint { self.nelts }
 
-    /// Return true if the deque contains no elements
+    /// Return true if the RingBufcontains no elements
     fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
-impl<T> Mutable for Deque<T> {
-    /// Clear the deque, removing all values.
+impl<T> Mutable for RingBuf<T> {
+    /// Clear the RingBuf, removing all values.
     fn clear(&mut self) {
         for self.elts.mut_iter().advance |x| { *x = None }
         self.nelts = 0;
@@ -43,68 +46,50 @@ impl<T> Mutable for Deque<T> {
     }
 }
 
-impl<T> Deque<T> {
-    /// Create an empty Deque
-    pub fn new() -> Deque<T> {
-        Deque::with_capacity(INITIAL_CAPACITY)
+impl<T> Deque<T> for RingBuf<T> {
+    /// Return a reference to the first element in the RingBuf
+    fn front<'a>(&'a self) -> Option<&'a T> {
+        if self.nelts > 0 { Some(self.get(0)) } else { None }
     }
 
-    /// Create an empty Deque with space for at least `n` elements.
-    pub fn with_capacity(n: uint) -> Deque<T> {
-        Deque{nelts: 0, lo: 0,
-              elts: vec::from_fn(num::max(MINIMUM_CAPACITY, n), |_| None)}
+    /// Return a mutable reference to the first element in the RingBuf
+    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+        if self.nelts > 0 { Some(self.get_mut(0)) } else { None }
     }
 
-    /// Return a reference to the first element in the deque
-    ///
-    /// Fails if the deque is empty
-    pub fn peek_front<'a>(&'a self) -> &'a T { get(self.elts, self.raw_index(0)) }
+    /// Return a reference to the last element in the RingBuf
+    fn back<'a>(&'a self) -> Option<&'a T> {
+        if self.nelts > 0 { Some(self.get(self.nelts - 1)) } else { None }
+    }
 
-    /// Return a reference to the last element in the deque
-    ///
-    /// Fails if the deque is empty
-    pub fn peek_back<'a>(&'a self) -> &'a T {
-        if self.nelts > 0 {
-            get(self.elts, self.raw_index(self.nelts - 1))
-        } else {
-            fail!("peek_back: empty deque");
+    /// Return a mutable reference to the last element in the RingBuf
+    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+        if self.nelts > 0 { Some(self.get_mut(self.nelts - 1)) } else { None }
+    }
+
+    /// Remove and return the first element in the RingBuf, or None if it is empty
+    fn pop_front(&mut self) -> Option<T> {
+        let result = util::replace(&mut self.elts[self.lo], None);
+        if result.is_some() {
+            self.lo = (self.lo + 1u) % self.elts.len();
+            self.nelts -= 1u;
         }
-    }
-
-    /// Retrieve an element in the deque by index
-    ///
-    /// Fails if there is no element with the given index
-    pub fn get<'a>(&'a self, i: int) -> &'a T {
-        let idx = (self.lo + (i as uint)) % self.elts.len();
-        get(self.elts, idx)
-    }
-
-    /// Remove and return the first element in the deque
-    ///
-    /// Fails if the deque is empty
-    pub fn pop_front(&mut self) -> T {
-        let result = self.elts[self.lo].swap_unwrap();
-        self.lo = (self.lo + 1u) % self.elts.len();
-        self.nelts -= 1u;
         result
     }
 
-    /// Return index in underlying vec for a given logical element index
-    fn raw_index(&self, idx: uint) -> uint {
-        raw_index(self.lo, self.elts.len(), idx)
+    /// Remove and return the last element in the RingBuf, or None if it is empty
+    fn pop_back(&mut self) -> Option<T> {
+        if self.nelts > 0 {
+            self.nelts -= 1;
+            let hi = self.raw_index(self.nelts);
+            util::replace(&mut self.elts[hi], None)
+        } else {
+            None
+        }
     }
 
-    /// Remove and return the last element in the deque
-    ///
-    /// Fails if the deque is empty
-    pub fn pop_back(&mut self) -> T {
-        self.nelts -= 1;
-        let hi = self.raw_index(self.nelts);
-        self.elts[hi].swap_unwrap()
-    }
-
-    /// Prepend an element to the deque
-    pub fn add_front(&mut self, t: T) {
+    /// Prepend an element to the RingBuf
+    fn push_front(&mut self, t: T) {
         if self.nelts == self.elts.len() {
             grow(self.nelts, &mut self.lo, &mut self.elts);
         }
@@ -115,8 +100,8 @@ impl<T> Deque<T> {
         self.nelts += 1u;
     }
 
-    /// Append an element to the deque
-    pub fn add_back(&mut self, t: T) {
+    /// Append an element to the RingBuf
+    fn push_back(&mut self, t: T) {
         if self.nelts == self.elts.len() {
             grow(self.nelts, &mut self.lo, &mut self.elts);
         }
@@ -124,8 +109,48 @@ impl<T> Deque<T> {
         self.elts[hi] = Some(t);
         self.nelts += 1u;
     }
+}
 
-    /// Reserve capacity for exactly `n` elements in the given deque,
+impl<T> RingBuf<T> {
+    /// Create an empty RingBuf
+    pub fn new() -> RingBuf<T> {
+        RingBuf::with_capacity(INITIAL_CAPACITY)
+    }
+
+    /// Create an empty RingBuf with space for at least `n` elements.
+    pub fn with_capacity(n: uint) -> RingBuf<T> {
+        RingBuf{nelts: 0, lo: 0,
+              elts: vec::from_fn(num::max(MINIMUM_CAPACITY, n), |_| None)}
+    }
+
+    /// Retrieve an element in the RingBuf by index
+    ///
+    /// Fails if there is no element with the given index
+    pub fn get<'a>(&'a self, i: uint) -> &'a T {
+        let idx = self.raw_index(i);
+        match self.elts[idx] {
+            None => fail!(),
+            Some(ref v) => v
+        }
+    }
+
+    /// Retrieve an element in the RingBuf by index
+    ///
+    /// Fails if there is no element with the given index
+    pub fn get_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
+        let idx = self.raw_index(i);
+        match self.elts[idx] {
+            None => fail!(),
+            Some(ref mut v) => v
+        }
+    }
+
+    /// Return index in underlying vec for a given logical element index
+    fn raw_index(&self, idx: uint) -> uint {
+        raw_index(self.lo, self.elts.len(), idx)
+    }
+
+    /// Reserve capacity for exactly `n` elements in the given RingBuf,
     /// doing nothing if `self`'s capacity is already equal to or greater
     /// than the requested capacity
     ///
@@ -136,7 +161,7 @@ impl<T> Deque<T> {
         self.elts.reserve(n);
     }
 
-    /// Reserve capacity for at least `n` elements in the given deque,
+    /// Reserve capacity for at least `n` elements in the given RingBuf,
     /// over-allocating in case the caller needs to reserve additional
     /// space.
     ///
@@ -151,24 +176,24 @@ impl<T> Deque<T> {
     }
 
     /// Front-to-back iterator.
-    pub fn iter<'a>(&'a self) -> DequeIterator<'a, T> {
-        DequeIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo}
+    pub fn iter<'a>(&'a self) -> RingBufIterator<'a, T> {
+        RingBufIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo}
     }
 
     /// Front-to-back iterator which returns mutable values.
-    pub fn mut_iter<'a>(&'a mut self) -> DequeMutIterator<'a, T> {
-        DequeMutIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo}
+    pub fn mut_iter<'a>(&'a mut self) -> RingBufMutIterator<'a, T> {
+        RingBufMutIterator{index: 0, nelts: self.nelts, elts: self.elts, lo: self.lo}
     }
 
     /// Back-to-front iterator.
-    pub fn rev_iter<'a>(&'a self) -> DequeRevIterator<'a, T> {
-        DequeRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts,
+    pub fn rev_iter<'a>(&'a self) -> RingBufRevIterator<'a, T> {
+        RingBufRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts,
                          lo: self.lo}
     }
 
     /// Back-to-front iterator which returns mutable values.
-    pub fn mut_rev_iter<'a>(&'a mut self) -> DequeMutRevIterator<'a, T> {
-        DequeMutRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts,
+    pub fn mut_rev_iter<'a>(&'a mut self) -> RingBufMutRevIterator<'a, T> {
+        RingBufMutRevIterator{index: self.nelts-1, nelts: self.nelts, elts: self.elts,
                             lo: self.lo}
     }
 }
@@ -190,41 +215,41 @@ macro_rules! iterator {
     }
 }
 
-/// Deque iterator
-pub struct DequeIterator<'self, T> {
+/// RingBuf iterator
+pub struct RingBufIterator<'self, T> {
     priv lo: uint,
     priv nelts: uint,
     priv index: uint,
     priv elts: &'self [Option<T>],
 }
-iterator!{impl DequeIterator -> &'self T, get_ref, 1}
+iterator!{impl RingBufIterator -> &'self T, get_ref, 1}
 
-/// Deque reverse iterator
-pub struct DequeRevIterator<'self, T> {
+/// RingBuf reverse iterator
+pub struct RingBufRevIterator<'self, T> {
     priv lo: uint,
     priv nelts: uint,
     priv index: uint,
     priv elts: &'self [Option<T>],
 }
-iterator!{impl DequeRevIterator -> &'self T, get_ref, -1}
+iterator!{impl RingBufRevIterator -> &'self T, get_ref, -1}
 
-/// Deque mutable iterator
-pub struct DequeMutIterator<'self, T> {
+/// RingBuf mutable iterator
+pub struct RingBufMutIterator<'self, T> {
     priv lo: uint,
     priv nelts: uint,
     priv index: uint,
     priv elts: &'self mut [Option<T>],
 }
-iterator!{impl DequeMutIterator -> &'self mut T, get_mut_ref, 1}
+iterator!{impl RingBufMutIterator -> &'self mut T, get_mut_ref, 1}
 
-/// Deque mutable reverse iterator
-pub struct DequeMutRevIterator<'self, T> {
+/// RingBuf mutable reverse iterator
+pub struct RingBufMutRevIterator<'self, T> {
     priv lo: uint,
     priv nelts: uint,
     priv index: uint,
     priv elts: &'self mut [Option<T>],
 }
-iterator!{impl DequeMutRevIterator -> &'self mut T, get_mut_ref, -1}
+iterator!{impl RingBufMutRevIterator -> &'self mut T, get_mut_ref, -1}
 
 /// Grow is only called on full elts, so nelts is also len(elts), unlike
 /// elsewhere.
@@ -261,10 +286,6 @@ fn grow<T>(nelts: uint, loptr: &mut uint, elts: &mut ~[Option<T>]) {
     }
 }
 
-fn get<'r, T>(elts: &'r [Option<T>], i: uint) -> &'r T {
-    match elts[i] { Some(ref t) => t, _ => fail!() }
-}
-
 /// Return index in underlying vec for a given logical element index
 fn raw_index(lo: uint, len: uint, index: uint) -> uint {
     if lo >= len - index {
@@ -274,21 +295,21 @@ fn raw_index(lo: uint, len: uint, index: uint) -> uint {
     }
 }
 
-impl<A: Eq> Eq for Deque<A> {
-    fn eq(&self, other: &Deque<A>) -> bool {
+impl<A: Eq> Eq for RingBuf<A> {
+    fn eq(&self, other: &RingBuf<A>) -> bool {
         self.nelts == other.nelts &&
             self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
     }
-    fn ne(&self, other: &Deque<A>) -> bool {
+    fn ne(&self, other: &RingBuf<A>) -> bool {
         !self.eq(other)
     }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for Deque<A> {
-    fn from_iterator(iterator: &mut T) -> Deque<A> {
-        let mut deq = Deque::new();
+impl<A, T: Iterator<A>> FromIterator<A, T> for RingBuf<A> {
+    fn from_iterator(iterator: &mut T) -> RingBuf<A> {
+        let mut deq = RingBuf::new();
         for iterator.advance |elt| {
-            deq.add_back(elt);
+            deq.push_back(elt);
         }
         deq
     }
@@ -304,38 +325,38 @@ mod tests {
 
     #[test]
     fn test_simple() {
-        let mut d = Deque::new();
+        let mut d = RingBuf::new();
         assert_eq!(d.len(), 0u);
-        d.add_front(17);
-        d.add_front(42);
-        d.add_back(137);
+        d.push_front(17);
+        d.push_front(42);
+        d.push_back(137);
         assert_eq!(d.len(), 3u);
-        d.add_back(137);
+        d.push_back(137);
         assert_eq!(d.len(), 4u);
-        debug!(d.peek_front());
-        assert_eq!(*d.peek_front(), 42);
-        debug!(d.peek_back());
-        assert_eq!(*d.peek_back(), 137);
-        let mut i: int = d.pop_front();
+        debug!(d.front());
+        assert_eq!(*d.front().unwrap(), 42);
+        debug!(d.back());
+        assert_eq!(*d.back().unwrap(), 137);
+        let mut i = d.pop_front();
         debug!(i);
-        assert_eq!(i, 42);
+        assert_eq!(i, Some(42));
         i = d.pop_back();
         debug!(i);
-        assert_eq!(i, 137);
+        assert_eq!(i, Some(137));
         i = d.pop_back();
         debug!(i);
-        assert_eq!(i, 137);
+        assert_eq!(i, Some(137));
         i = d.pop_back();
         debug!(i);
-        assert_eq!(i, 17);
+        assert_eq!(i, Some(17));
         assert_eq!(d.len(), 0u);
-        d.add_back(3);
+        d.push_back(3);
         assert_eq!(d.len(), 1u);
-        d.add_front(2);
+        d.push_front(2);
         assert_eq!(d.len(), 2u);
-        d.add_back(4);
+        d.push_back(4);
         assert_eq!(d.len(), 3u);
-        d.add_front(1);
+        d.push_front(1);
         assert_eq!(d.len(), 4u);
         debug!(d.get(0));
         debug!(d.get(1));
@@ -354,28 +375,28 @@ mod tests {
         let c: @int = @64;
         let d: @int = @175;
 
-        let mut deq = Deque::new();
+        let mut deq = RingBuf::new();
         assert_eq!(deq.len(), 0);
-        deq.add_front(a);
-        deq.add_front(b);
-        deq.add_back(c);
+        deq.push_front(a);
+        deq.push_front(b);
+        deq.push_back(c);
         assert_eq!(deq.len(), 3);
-        deq.add_back(d);
+        deq.push_back(d);
         assert_eq!(deq.len(), 4);
-        assert_eq!(*deq.peek_front(), b);
-        assert_eq!(*deq.peek_back(), d);
-        assert_eq!(deq.pop_front(), b);
-        assert_eq!(deq.pop_back(), d);
-        assert_eq!(deq.pop_back(), c);
-        assert_eq!(deq.pop_back(), a);
+        assert_eq!(deq.front(), Some(&b));
+        assert_eq!(deq.back(), Some(&d));
+        assert_eq!(deq.pop_front(), Some(b));
+        assert_eq!(deq.pop_back(), Some(d));
+        assert_eq!(deq.pop_back(), Some(c));
+        assert_eq!(deq.pop_back(), Some(a));
         assert_eq!(deq.len(), 0);
-        deq.add_back(c);
+        deq.push_back(c);
         assert_eq!(deq.len(), 1);
-        deq.add_front(b);
+        deq.push_front(b);
         assert_eq!(deq.len(), 2);
-        deq.add_back(d);
+        deq.push_back(d);
         assert_eq!(deq.len(), 3);
-        deq.add_front(a);
+        deq.push_front(a);
         assert_eq!(deq.len(), 4);
         assert_eq!(*deq.get(0), a);
         assert_eq!(*deq.get(1), b);
@@ -385,28 +406,28 @@ mod tests {
 
     #[cfg(test)]
     fn test_parameterized<T:Copy + Eq>(a: T, b: T, c: T, d: T) {
-        let mut deq = Deque::new();
+        let mut deq = RingBuf::new();
         assert_eq!(deq.len(), 0);
-        deq.add_front(copy a);
-        deq.add_front(copy b);
-        deq.add_back(copy c);
+        deq.push_front(copy a);
+        deq.push_front(copy b);
+        deq.push_back(copy c);
         assert_eq!(deq.len(), 3);
-        deq.add_back(copy d);
+        deq.push_back(copy d);
         assert_eq!(deq.len(), 4);
-        assert_eq!(copy *deq.peek_front(), copy b);
-        assert_eq!(copy *deq.peek_back(), copy d);
-        assert_eq!(deq.pop_front(), copy b);
-        assert_eq!(deq.pop_back(), copy d);
-        assert_eq!(deq.pop_back(), copy c);
-        assert_eq!(deq.pop_back(), copy a);
+        assert_eq!(deq.front(), Some(&b));
+        assert_eq!(deq.back(), Some(&d));
+        assert_eq!(deq.pop_front(), Some(copy b));
+        assert_eq!(deq.pop_back(), Some(copy d));
+        assert_eq!(deq.pop_back(), Some(copy c));
+        assert_eq!(deq.pop_back(), Some(copy a));
         assert_eq!(deq.len(), 0);
-        deq.add_back(copy c);
+        deq.push_back(copy c);
         assert_eq!(deq.len(), 1);
-        deq.add_front(copy b);
+        deq.push_front(copy b);
         assert_eq!(deq.len(), 2);
-        deq.add_back(copy d);
+        deq.push_back(copy d);
         assert_eq!(deq.len(), 3);
-        deq.add_front(copy a);
+        deq.push_front(copy a);
         assert_eq!(deq.len(), 4);
         assert_eq!(copy *deq.get(0), copy a);
         assert_eq!(copy *deq.get(1), copy b);
@@ -415,23 +436,23 @@ mod tests {
     }
 
     #[test]
-    fn test_add_front_grow() {
-        let mut deq = Deque::new();
-        for int::range(0, 66) |i| {
-            deq.add_front(i);
+    fn test_push_front_grow() {
+        let mut deq = RingBuf::new();
+        for uint::range(0, 66) |i| {
+            deq.push_front(i);
         }
         assert_eq!(deq.len(), 66);
 
-        for int::range(0, 66) |i| {
+        for uint::range(0, 66) |i| {
             assert_eq!(*deq.get(i), 65 - i);
         }
 
-        let mut deq = Deque::new();
-        for int::range(0, 66) |i| {
-            deq.add_back(i);
+        let mut deq = RingBuf::new();
+        for uint::range(0, 66) |i| {
+            deq.push_back(i);
         }
 
-        for int::range(0, 66) |i| {
+        for uint::range(0, 66) |i| {
             assert_eq!(*deq.get(i), i);
         }
     }
@@ -439,32 +460,32 @@ mod tests {
     #[bench]
     fn bench_new(b: &mut test::BenchHarness) {
         do b.iter {
-            let _ = Deque::new::<u64>();
+            let _ = RingBuf::new::<u64>();
         }
     }
 
     #[bench]
-    fn bench_add_back(b: &mut test::BenchHarness) {
-        let mut deq = Deque::new();
+    fn bench_push_back(b: &mut test::BenchHarness) {
+        let mut deq = RingBuf::new();
         do b.iter {
-            deq.add_back(0);
+            deq.push_back(0);
         }
     }
 
     #[bench]
-    fn bench_add_front(b: &mut test::BenchHarness) {
-        let mut deq = Deque::new();
+    fn bench_push_front(b: &mut test::BenchHarness) {
+        let mut deq = RingBuf::new();
         do b.iter {
-            deq.add_front(0);
+            deq.push_front(0);
         }
     }
 
     #[bench]
     fn bench_grow(b: &mut test::BenchHarness) {
-        let mut deq = Deque::new();
+        let mut deq = RingBuf::new();
         do b.iter {
             for 65.times {
-                deq.add_front(1);
+                deq.push_front(1);
             }
         }
     }
@@ -518,77 +539,77 @@ mod tests {
 
     #[test]
     fn test_with_capacity() {
-        let mut d = Deque::with_capacity(0);
-        d.add_back(1);
+        let mut d = RingBuf::with_capacity(0);
+        d.push_back(1);
         assert_eq!(d.len(), 1);
-        let mut d = Deque::with_capacity(50);
-        d.add_back(1);
+        let mut d = RingBuf::with_capacity(50);
+        d.push_back(1);
         assert_eq!(d.len(), 1);
     }
 
     #[test]
     fn test_reserve() {
-        let mut d = Deque::new();
-        d.add_back(0u64);
+        let mut d = RingBuf::new();
+        d.push_back(0u64);
         d.reserve(50);
         assert_eq!(d.elts.capacity(), 50);
-        let mut d = Deque::new();
-        d.add_back(0u32);
+        let mut d = RingBuf::new();
+        d.push_back(0u32);
         d.reserve(50);
         assert_eq!(d.elts.capacity(), 50);
     }
 
     #[test]
     fn test_reserve_at_least() {
-        let mut d = Deque::new();
-        d.add_back(0u64);
+        let mut d = RingBuf::new();
+        d.push_back(0u64);
         d.reserve_at_least(50);
         assert_eq!(d.elts.capacity(), 64);
-        let mut d = Deque::new();
-        d.add_back(0u32);
+        let mut d = RingBuf::new();
+        d.push_back(0u32);
         d.reserve_at_least(50);
         assert_eq!(d.elts.capacity(), 64);
     }
 
     #[test]
     fn test_iter() {
-        let mut d = Deque::new();
+        let mut d = RingBuf::new();
         assert_eq!(d.iter().next(), None);
 
         for int::range(0,5) |i| {
-            d.add_back(i);
+            d.push_back(i);
         }
         assert_eq!(d.iter().collect::<~[&int]>(), ~[&0,&1,&2,&3,&4]);
 
         for int::range(6,9) |i| {
-            d.add_front(i);
+            d.push_front(i);
         }
         assert_eq!(d.iter().collect::<~[&int]>(), ~[&8,&7,&6,&0,&1,&2,&3,&4]);
     }
 
     #[test]
     fn test_rev_iter() {
-        let mut d = Deque::new();
+        let mut d = RingBuf::new();
         assert_eq!(d.rev_iter().next(), None);
 
         for int::range(0,5) |i| {
-            d.add_back(i);
+            d.push_back(i);
         }
         assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0]);
 
         for int::range(6,9) |i| {
-            d.add_front(i);
+            d.push_front(i);
         }
         assert_eq!(d.rev_iter().collect::<~[&int]>(), ~[&4,&3,&2,&1,&0,&6,&7,&8]);
     }
 
     #[test]
     fn test_mut_iter() {
-        let mut d = Deque::new();
+        let mut d = RingBuf::new();
         assert!(d.mut_iter().next().is_none());
 
         for uint::range(0,3) |i| {
-            d.add_front(i);
+            d.push_front(i);
         }
 
         for d.mut_iter().enumerate().advance |(i, elt)| {
@@ -607,11 +628,11 @@ mod tests {
 
     #[test]
     fn test_mut_rev_iter() {
-        let mut d = Deque::new();
+        let mut d = RingBuf::new();
         assert!(d.mut_rev_iter().next().is_none());
 
         for uint::range(0,3) |i| {
-            d.add_front(i);
+            d.push_front(i);
         }
 
         for d.mut_rev_iter().enumerate().advance |(i, elt)| {
@@ -632,12 +653,12 @@ mod tests {
     fn test_from_iterator() {
         use std::iterator;
         let v = ~[1,2,3,4,5,6,7];
-        let deq: Deque<int> = v.iter().transform(|&x| x).collect();
+        let deq: RingBuf<int> = v.iter().transform(|&x| x).collect();
         let u: ~[int] = deq.iter().transform(|&x| x).collect();
         assert_eq!(u, v);
 
         let mut seq = iterator::Counter::new(0u, 2).take_(256);
-        let deq: Deque<uint> = seq.collect();
+        let deq: RingBuf<uint> = seq.collect();
         for deq.iter().enumerate().advance |(i, &x)| {
             assert_eq!(2*i, x);
         }
@@ -646,11 +667,11 @@ mod tests {
 
     #[test]
     fn test_clone() {
-        let mut d = Deque::new();
-        d.add_front(17);
-        d.add_front(42);
-        d.add_back(137);
-        d.add_back(137);
+        let mut d = RingBuf::new();
+        d.push_front(17);
+        d.push_front(42);
+        d.push_back(137);
+        d.push_back(137);
         assert_eq!(d.len(), 4u);
         let mut e = d.clone();
         assert_eq!(e.len(), 4u);
@@ -663,22 +684,22 @@ mod tests {
 
     #[test]
     fn test_eq() {
-        let mut d = Deque::new();
-        assert_eq!(&d, &Deque::with_capacity(0));
-        d.add_front(137);
-        d.add_front(17);
-        d.add_front(42);
-        d.add_back(137);
-        let mut e = Deque::with_capacity(0);
-        e.add_back(42);
-        e.add_back(17);
-        e.add_back(137);
-        e.add_back(137);
+        let mut d = RingBuf::new();
+        assert_eq!(&d, &RingBuf::with_capacity(0));
+        d.push_front(137);
+        d.push_front(17);
+        d.push_front(42);
+        d.push_back(137);
+        let mut e = RingBuf::with_capacity(0);
+        e.push_back(42);
+        e.push_back(17);
+        e.push_back(137);
+        e.push_back(137);
         assert_eq!(&e, &d);
         e.pop_back();
-        e.add_back(0);
+        e.push_back(0);
         assert!(e != d);
         e.clear();
-        assert_eq!(e, Deque::new());
+        assert_eq!(e, RingBuf::new());
     }
 }
diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs
index 5a9072a68d8..f185f7d7321 100644
--- a/src/libextra/serialize.rs
+++ b/src/libextra/serialize.rs
@@ -23,7 +23,8 @@ use std::hashmap::{HashMap, HashSet};
 use std::trie::{TrieMap, TrieSet};
 use std::uint;
 use std::vec;
-use deque::Deque;
+use ringbuf::RingBuf;
+use container::Deque;
 use dlist::List;
 use treemap::{TreeMap, TreeSet};
 
@@ -679,7 +680,7 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for List<T> {
 impl<
     S: Encoder,
     T: Encodable<S>
-> Encodable<S> for Deque<T> {
+> Encodable<S> for RingBuf<T> {
     fn encode(&self, s: &mut S) {
         do s.emit_seq(self.len()) |s| {
             for self.iter().enumerate().advance |(i, e)| {
@@ -689,12 +690,12 @@ impl<
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for Deque<T> {
-    fn decode(d: &mut D) -> Deque<T> {
-        let mut deque = Deque::new();
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for RingBuf<T> {
+    fn decode(d: &mut D) -> RingBuf<T> {
+        let mut deque = RingBuf::new();
         do d.read_seq |d, len| {
             for uint::range(0, len) |i| {
-                deque.add_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
+                deque.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));
             }
         }
         deque
diff --git a/src/test/bench/graph500-bfs.rs b/src/test/bench/graph500-bfs.rs
index dbb8da1ebd7..f0ffa3237b5 100644
--- a/src/test/bench/graph500-bfs.rs
+++ b/src/test/bench/graph500-bfs.rs
@@ -19,7 +19,8 @@ An implementation of the Graph500 Breadth First Search problem in Rust.
 extern mod extra;
 use extra::arc;
 use extra::time;
-use extra::deque::Deque;
+use extra::ringbuf::RingBuf;
+use extra::container::Deque;
 use extra::par;
 use std::hashmap::HashSet;
 use std::num::abs;
@@ -133,18 +134,18 @@ fn bfs(graph: graph, key: node_id) -> bfs_result {
     let mut marks : ~[node_id]
         = vec::from_elem(graph.len(), -1i64);
 
-    let mut q = Deque::new();
+    let mut q = RingBuf::new();
 
-    q.add_back(key);
+    q.push_back(key);
     marks[key] = key;
 
     while !q.is_empty() {
-        let t = q.pop_front();
+        let t = q.pop_front().unwrap();
 
         do graph[t].iter().advance |k| {
             if marks[*k] == -1i64 {
                 marks[*k] = t;
-                q.add_back(*k);
+                q.push_back(*k);
             }
             true
         };
diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs
index 9d870168802..0314c7fed02 100644
--- a/src/test/run-pass/issue-2383.rs
+++ b/src/test/run-pass/issue-2383.rs
@@ -11,9 +11,10 @@
 // except according to those terms.
 
 extern mod extra;
-use extra::deque::Deque;
+use extra::ringbuf::RingBuf;
+use extra::container::Deque;
 
 pub fn main() {
-    let mut q = Deque::new();
-    q.add_back(10);
+    let mut q = RingBuf::new();
+    q.push_back(10);
 }

From 24d2d7b5bb4b046429f293ff5c2cde4d14dfac8b Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 15:27:15 +0200
Subject: [PATCH 09/12] dlist: Implement trait Deque

---
 src/libextra/dlist.rs | 47 +++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 22 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 5722e39eb0f..edbcdc1ff76 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -10,13 +10,14 @@
 // Backlinks over List::prev are raw pointers that form a full chain in
 // the reverse direction.
 
-
 use std::cast;
 use std::cmp;
 use std::ptr;
 use std::util;
 use std::iterator::FromIterator;
 
+use container::Deque;
+
 /// A doubly-linked list
 pub struct List<T> {
     priv length: uint,
@@ -124,20 +125,14 @@ impl<T> Mutable for List<T> {
     }
 }
 
-impl<T> List<T> {
-    /// Create an empty List
-    #[inline]
-    pub fn new() -> List<T> {
-        List{list_head: None, list_tail: Rawlink::none(), length: 0}
-    }
-
+impl<T> Deque<T> for List<T> {
     /// Provide a reference to the front element, or None if the list is empty
-    pub fn peek_front<'a>(&'a self) -> Option<&'a T> {
+    fn front<'a>(&'a self) -> Option<&'a T> {
         self.list_head.chain_ref(|x| Some(&x.value))
     }
 
     /// Provide a mutable reference to the front element, or None if the list is empty
-    pub fn peek_front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
         match self.list_head {
             None => None,
             Some(ref mut head) => Some(&mut head.value),
@@ -145,7 +140,7 @@ impl<T> List<T> {
     }
 
     /// Provide a reference to the back element, or None if the list is empty
-    pub fn peek_back<'a>(&'a self) -> Option<&'a T> {
+    fn back<'a>(&'a self) -> Option<&'a T> {
         match self.list_tail.resolve_immut() {
             None => None,
             Some(tail) => Some(&tail.value),
@@ -153,7 +148,7 @@ impl<T> List<T> {
     }
 
     /// Provide a mutable reference to the back element, or None if the list is empty
-    pub fn peek_back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
         match self.list_tail.resolve() {
             None => None,
             Some(tail) => Some(&mut tail.value),
@@ -163,7 +158,7 @@ impl<T> List<T> {
     /// Add an element last in the list
     ///
     /// O(1)
-    pub fn push_back(&mut self, elt: T) {
+    fn push_back(&mut self, elt: T) {
         match self.list_tail.resolve() {
             None => return self.push_front(elt),
             Some(tail) => {
@@ -179,7 +174,7 @@ impl<T> List<T> {
     ///
     /// O(1)
     #[inline]
-    pub fn pop_back(&mut self) -> Option<T> {
+    fn pop_back(&mut self) -> Option<T> {
         match self.list_tail.resolve() {
             None => None,
             Some(tail) => {
@@ -202,7 +197,7 @@ impl<T> List<T> {
     /// Add an element first in the list
     ///
     /// O(1)
-    pub fn push_front(&mut self, elt: T) {
+    fn push_front(&mut self, elt: T) {
         let mut new_head = ~Node{value: elt, next: None, prev: Rawlink::none()};
         match self.list_head {
             None => {
@@ -221,7 +216,7 @@ impl<T> List<T> {
     /// Remove the first element and return it, or None if the list is empty
     ///
     /// O(1)
-    pub fn pop_front(&mut self) -> Option<T> {
+    fn pop_front(&mut self) -> Option<T> {
         match util::replace(&mut self.list_head, None) {
             None => None,
             Some(old_head) => {
@@ -239,6 +234,14 @@ impl<T> List<T> {
             }
         }
     }
+}
+
+impl<T> List<T> {
+    /// Create an empty List
+    #[inline]
+    pub fn new() -> List<T> {
+        List{list_head: None, list_tail: Rawlink::none(), length: 0}
+    }
 
     /// Add all elements from `other` to the end of the list
     ///
@@ -292,7 +295,7 @@ impl<T> List<T> {
         {
             let mut it = self.mut_iter();
             loop {
-                match (it.next(), other.peek_front()) {
+                match (it.next(), other.front()) {
                     (None   , _      ) => break,
                     (_      , None   ) => return,
                     (Some(x), Some(y)) => if f(x, y) { loop }
@@ -462,7 +465,7 @@ impl<'self, A> ListInsertion<A> for MutForwardIterator<'self, A> {
 
     fn peek_next<'a>(&'a mut self) -> Option<&'a mut A> {
         match self.curs.resolve() {
-            None => self.list.peek_front_mut(),
+            None => self.list.front_mut(),
             Some(curs) => match curs.next {
                 None => None,
                 Some(ref mut node) => Some(&mut node.value),
@@ -574,14 +577,14 @@ mod tests {
         n.push_front(2);
         n.push_front(3);
         {
-            assert_eq!(n.peek_front().unwrap(), &3);
-            let x = n.peek_front_mut().unwrap();
+            assert_eq!(n.front().unwrap(), &3);
+            let x = n.front_mut().unwrap();
             assert_eq!(*x, 3);
             *x = 0;
         }
         {
-            assert_eq!(n.peek_back().unwrap(), &2);
-            let y = n.peek_back_mut().unwrap();
+            assert_eq!(n.back().unwrap(), &2);
+            let y = n.back_mut().unwrap();
             assert_eq!(*y, 2);
             *y = 1;
         }

From a8e7bdd142e6cc0cac89a88eef3bbadceb5e6489 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Wed, 10 Jul 2013 16:06:09 +0200
Subject: [PATCH 10/12] dlist: Fix license header

---
 src/libextra/dlist.rs | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index edbcdc1ff76..969340ffeaa 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -1,3 +1,12 @@
+// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
 
 //! A doubly-linked list with owned nodes.
 //!

From b2b88b326d476425f66d1def14aef3fd286d5aec Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Thu, 11 Jul 2013 15:47:52 +0200
Subject: [PATCH 11/12] dlist: Name the type DList for doubly-linked list

---
 src/libextra/dlist.rs     | 134 +++++++++++++++++++-------------------
 src/libextra/serialize.rs |  10 +--
 2 files changed, 72 insertions(+), 72 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 969340ffeaa..18629f8597c 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -10,13 +10,13 @@
 
 //! A doubly-linked list with owned nodes.
 //!
-//! The List allows pushing and popping elements at either end.
+//! The DList allows pushing and popping elements at either end.
 
 
-// List is constructed like a singly-linked list over the field `next`.
+// DList is constructed like a singly-linked list over the field `next`.
 // including the last link being None; each Node owns its `next` field.
 //
-// Backlinks over List::prev are raw pointers that form a full chain in
+// Backlinks over DList::prev are raw pointers that form a full chain in
 // the reverse direction.
 
 use std::cast;
@@ -28,7 +28,7 @@ use std::iterator::FromIterator;
 use container::Deque;
 
 /// A doubly-linked list
-pub struct List<T> {
+pub struct DList<T> {
     priv length: uint,
     priv list_head: Link<T>,
     priv list_tail: Rawlink<Node<T>>,
@@ -43,42 +43,42 @@ struct Node<T> {
     priv value: T,
 }
 
-/// List iterator
+/// DList iterator
 pub struct ForwardIterator<'self, T> {
-    priv list: &'self List<T>,
+    priv list: &'self DList<T>,
     priv next: &'self Link<T>,
     priv nelem: uint,
 }
 
-/// List reverse iterator
+/// DList reverse iterator
 pub struct ReverseIterator<'self, T> {
-    priv list: &'self List<T>,
+    priv list: &'self DList<T>,
     priv next: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
-/// List mutable iterator
+/// DList mutable iterator
 pub struct MutForwardIterator<'self, T> {
-    priv list: &'self mut List<T>,
+    priv list: &'self mut DList<T>,
     priv curs: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
-/// List mutable reverse iterator
+/// DList mutable reverse iterator
 pub struct MutReverseIterator<'self, T> {
-    priv list: &'self mut List<T>,
+    priv list: &'self mut DList<T>,
     priv next: Rawlink<Node<T>>,
     priv nelem: uint,
 }
 
-/// List consuming iterator
+/// DList consuming iterator
 pub struct ConsumeIterator<T> {
-    priv list: List<T>
+    priv list: DList<T>
 }
 
-/// List reverse consuming iterator
+/// DList reverse consuming iterator
 pub struct ConsumeRevIterator<T> {
-    priv list: List<T>
+    priv list: DList<T>
 }
 
 /// Rawlink is a type like Option<T> but for holding a raw pointer
@@ -114,7 +114,7 @@ fn link_with_prev<T>(mut next: ~Node<T>, prev: Rawlink<Node<T>>) -> Link<T> {
     Some(next)
 }
 
-impl<T> Container for List<T> {
+impl<T> Container for DList<T> {
     /// O(1)
     fn is_empty(&self) -> bool {
         self.list_head.is_none()
@@ -125,16 +125,16 @@ impl<T> Container for List<T> {
     }
 }
 
-impl<T> Mutable for List<T> {
-    /// Remove all elements from the List
+impl<T> Mutable for DList<T> {
+    /// Remove all elements from the DList
     ///
     /// O(N)
     fn clear(&mut self) {
-        *self = List::new()
+        *self = DList::new()
     }
 }
 
-impl<T> Deque<T> for List<T> {
+impl<T> Deque<T> for DList<T> {
     /// Provide a reference to the front element, or None if the list is empty
     fn front<'a>(&'a self) -> Option<&'a T> {
         self.list_head.chain_ref(|x| Some(&x.value))
@@ -245,23 +245,23 @@ impl<T> Deque<T> for List<T> {
     }
 }
 
-impl<T> List<T> {
-    /// Create an empty List
+impl<T> DList<T> {
+    /// Create an empty DList
     #[inline]
-    pub fn new() -> List<T> {
-        List{list_head: None, list_tail: Rawlink::none(), length: 0}
+    pub fn new() -> DList<T> {
+        DList{list_head: None, list_tail: Rawlink::none(), length: 0}
     }
 
     /// Add all elements from `other` to the end of the list
     ///
     /// O(1)
-    pub fn append(&mut self, other: List<T>) {
+    pub fn append(&mut self, other: DList<T>) {
         match self.list_tail.resolve() {
             None => *self = other,
             Some(tail) => {
                 match other {
-                    List{list_head: None, list_tail: _, length: _} => return,
-                    List{list_head: Some(node), list_tail: o_tail, length: o_length} => {
+                    DList{list_head: None, list_tail: _, length: _} => return,
+                    DList{list_head: Some(node), list_tail: o_tail, length: o_length} => {
                         tail.next = link_with_prev(node, self.list_tail);
                         self.list_tail = o_tail;
                         self.length += o_length;
@@ -274,7 +274,7 @@ impl<T> List<T> {
     /// Add all elements from `other` to the beginning of the list
     ///
     /// O(1)
-    pub fn prepend(&mut self, mut other: List<T>) {
+    pub fn prepend(&mut self, mut other: DList<T>) {
         util::swap(self, &mut other);
         self.append(other);
     }
@@ -300,7 +300,7 @@ impl<T> List<T> {
     /// Merge, using the function `f`; take `a` if `f(a, b)` is true, else `b`.
     ///
     /// O(max(N, M))
-    pub fn merge(&mut self, mut other: List<T>, f: &fn(&T, &T) -> bool) {
+    pub fn merge(&mut self, mut other: DList<T>, f: &fn(&T, &T) -> bool) {
         {
             let mut it = self.mut_iter();
             loop {
@@ -351,7 +351,7 @@ impl<T> List<T> {
 /// Insert sorted in ascending order
 ///
 /// O(N)
-impl<T: cmp::TotalOrd> List<T> {
+impl<T: cmp::TotalOrd> DList<T> {
     fn insert_ordered(&mut self, elt: T) {
         self.insert_when(elt, |a, b| a.cmp(b) != cmp::Less);
     }
@@ -445,7 +445,7 @@ impl<'self, A> Iterator<&'self mut A> for MutReverseIterator<'self, A> {
     }
 }
 
-/// Allow mutating the List while iterating
+/// Allow mutating the DList while iterating
 pub trait ListInsertion<A> {
     /// Insert `elt` just previous to the most recently yielded element
     fn insert_before(&mut self, elt: A);
@@ -497,32 +497,32 @@ impl<A> Iterator<A> for ConsumeRevIterator<A> {
     }
 }
 
-impl<A, T: Iterator<A>> FromIterator<A, T> for List<A> {
-    fn from_iterator(iterator: &mut T) -> List<A> {
-        let mut ret = List::new();
+impl<A, T: Iterator<A>> FromIterator<A, T> for DList<A> {
+    fn from_iterator(iterator: &mut T) -> DList<A> {
+        let mut ret = DList::new();
         for iterator.advance |elt| { ret.push_back(elt); }
         ret
     }
 }
 
-impl<A: Eq> Eq for List<A> {
-    fn eq(&self, other: &List<A>) -> bool {
+impl<A: Eq> Eq for DList<A> {
+    fn eq(&self, other: &DList<A>) -> bool {
         self.len() == other.len() &&
             self.iter().zip(other.iter()).all(|(a, b)| a.eq(b))
     }
-    fn ne(&self, other: &List<A>) -> bool {
+    fn ne(&self, other: &DList<A>) -> bool {
         !self.eq(other)
     }
 }
 
-impl<A: Clone> Clone for List<A> {
-    fn clone(&self) -> List<A> {
+impl<A: Clone> Clone for DList<A> {
+    fn clone(&self) -> DList<A> {
         self.iter().transform(|x| x.clone()).collect()
     }
 }
 
 #[cfg(test)]
-pub fn check_links<T>(list: &List<T>) {
+pub fn check_links<T>(list: &DList<T>) {
     let mut len = 0u;
     let mut last_ptr: Option<&Node<T>> = None;
     let mut node_ptr: &Node<T>;
@@ -563,7 +563,7 @@ mod tests {
 
     #[test]
     fn test_basic() {
-        let mut m = List::new::<~int>();
+        let mut m = DList::new::<~int>();
         assert_eq!(m.pop_front(), None);
         assert_eq!(m.pop_back(), None);
         assert_eq!(m.pop_front(), None);
@@ -582,7 +582,7 @@ mod tests {
         m.push_back(~7);
         assert_eq!(m.pop_front(), Some(~1));
 
-        let mut n = List::new();
+        let mut n = DList::new();
         n.push_front(2);
         n.push_front(3);
         {
@@ -602,20 +602,20 @@ mod tests {
     }
 
     #[cfg(test)]
-    fn generate_test() -> List<int> {
+    fn generate_test() -> DList<int> {
         list_from(&[0,1,2,3,4,5,6])
     }
 
     #[cfg(test)]
-    fn list_from<T: Copy>(v: &[T]) -> List<T> {
+    fn list_from<T: Copy>(v: &[T]) -> DList<T> {
         v.iter().transform(|x| copy *x).collect()
     }
 
     #[test]
     fn test_append() {
         {
-            let mut m = List::new();
-            let mut n = List::new();
+            let mut m = DList::new();
+            let mut n = DList::new();
             n.push_back(2);
             m.append(n);
             assert_eq!(m.len(), 1);
@@ -623,8 +623,8 @@ mod tests {
             check_links(&m);
         }
         {
-            let mut m = List::new();
-            let n = List::new();
+            let mut m = DList::new();
+            let n = DList::new();
             m.push_back(2);
             m.append(n);
             assert_eq!(m.len(), 1);
@@ -647,8 +647,8 @@ mod tests {
     #[test]
     fn test_prepend() {
         {
-            let mut m = List::new();
-            let mut n = List::new();
+            let mut m = DList::new();
+            let mut n = DList::new();
             n.push_back(2);
             m.prepend(n);
             assert_eq!(m.len(), 1);
@@ -674,7 +674,7 @@ mod tests {
         for m.iter().enumerate().advance |(i, elt)| {
             assert_eq!(i as int, *elt);
         }
-        let mut n = List::new();
+        let mut n = DList::new();
         assert_eq!(n.iter().next(), None);
         n.push_front(4);
         let mut it = n.iter();
@@ -690,7 +690,7 @@ mod tests {
         for m.rev_iter().enumerate().advance |(i, elt)| {
             assert_eq!((6 - i) as int, *elt);
         }
-        let mut n = List::new();
+        let mut n = DList::new();
         assert_eq!(n.rev_iter().next(), None);
         n.push_front(4);
         let mut it = n.rev_iter();
@@ -709,7 +709,7 @@ mod tests {
             len -= 1;
         }
         assert_eq!(len, 0);
-        let mut n = List::new();
+        let mut n = DList::new();
         assert!(n.mut_iter().next().is_none());
         n.push_front(4);
         let mut it = n.mut_iter();
@@ -760,12 +760,12 @@ mod tests {
 
     #[test]
     fn test_insert_ordered() {
-        let mut n = List::new();
+        let mut n = DList::new();
         n.insert_ordered(1);
         assert_eq!(n.len(), 1);
         assert_eq!(n.pop_front(), Some(1));
 
-        let mut m = List::new();
+        let mut m = DList::new();
         m.push_back(2);
         m.push_back(4);
         m.insert_ordered(3);
@@ -779,7 +779,7 @@ mod tests {
         for m.mut_rev_iter().enumerate().advance |(i, elt)| {
             assert_eq!((6-i) as int, *elt);
         }
-        let mut n = List::new();
+        let mut n = DList::new();
         assert!(n.mut_rev_iter().next().is_none());
         n.push_front(4);
         let mut it = n.mut_rev_iter();
@@ -798,7 +798,7 @@ mod tests {
 
     #[test]
     fn test_eq() {
-        let mut n: List<u8> = list_from([]);
+        let mut n: DList<u8> = list_from([]);
         let mut m = list_from([]);
         assert_eq!(&n, &m);
         n.push_front(1);
@@ -818,7 +818,7 @@ mod tests {
 
     #[cfg(test)]
     fn fuzz_test(sz: int) {
-        let mut m = List::new::<int>();
+        let mut m = DList::new::<int>();
         let mut v = ~[];
         for int::range(0i, sz) |i| {
             check_links(&m);
@@ -857,7 +857,7 @@ mod tests {
     fn bench_collect_into(b: &mut test::BenchHarness) {
         let v = &[0, ..64];
         do b.iter {
-            let _: List<int> = v.iter().transform(|&x|x).collect();
+            let _: DList<int> = v.iter().transform(|&x|x).collect();
         }
     }
     #[bench]
@@ -870,7 +870,7 @@ mod tests {
 
     #[bench]
     fn bench_push_front(b: &mut test::BenchHarness) {
-        let mut m = List::new::<int>();
+        let mut m = DList::new::<int>();
         do b.iter {
             m.push_front(0);
         }
@@ -886,7 +886,7 @@ mod tests {
 
     #[bench]
     fn bench_push_back(b: &mut test::BenchHarness) {
-        let mut m = List::new::<int>();
+        let mut m = DList::new::<int>();
         do b.iter {
             m.push_back(0);
         }
@@ -901,7 +901,7 @@ mod tests {
 
     #[bench]
     fn bench_push_back_pop_back(b: &mut test::BenchHarness) {
-        let mut m = List::new::<int>();
+        let mut m = DList::new::<int>();
         do b.iter {
             m.push_back(0);
             m.pop_back();
@@ -919,7 +919,7 @@ mod tests {
     #[bench]
     fn bench_iter(b: &mut test::BenchHarness) {
         let v = &[0, ..128];
-        let m: List<int> = v.iter().transform(|&x|x).collect();
+        let m: DList<int> = v.iter().transform(|&x|x).collect();
         do b.iter {
             for m.iter().advance |_| {}
         }
@@ -927,7 +927,7 @@ mod tests {
     #[bench]
     fn bench_iter_mut(b: &mut test::BenchHarness) {
         let v = &[0, ..128];
-        let mut m: List<int> = v.iter().transform(|&x|x).collect();
+        let mut m: DList<int> = v.iter().transform(|&x|x).collect();
         do b.iter {
             for m.mut_iter().advance |_| {}
         }
@@ -935,7 +935,7 @@ mod tests {
     #[bench]
     fn bench_iter_rev(b: &mut test::BenchHarness) {
         let v = &[0, ..128];
-        let m: List<int> = v.iter().transform(|&x|x).collect();
+        let m: DList<int> = v.iter().transform(|&x|x).collect();
         do b.iter {
             for m.rev_iter().advance |_| {}
         }
@@ -943,7 +943,7 @@ mod tests {
     #[bench]
     fn bench_iter_mut_rev(b: &mut test::BenchHarness) {
         let v = &[0, ..128];
-        let mut m: List<int> = v.iter().transform(|&x|x).collect();
+        let mut m: DList<int> = v.iter().transform(|&x|x).collect();
         do b.iter {
             for m.mut_rev_iter().advance |_| {}
         }
diff --git a/src/libextra/serialize.rs b/src/libextra/serialize.rs
index f185f7d7321..9fec58e7495 100644
--- a/src/libextra/serialize.rs
+++ b/src/libextra/serialize.rs
@@ -25,7 +25,7 @@ use std::uint;
 use std::vec;
 use ringbuf::RingBuf;
 use container::Deque;
-use dlist::List;
+use dlist::DList;
 use treemap::{TreeMap, TreeSet};
 
 pub trait Encoder {
@@ -653,7 +653,7 @@ impl<
 impl<
     S: Encoder,
     T: Encodable<S> + Copy
-> Encodable<S> for List<T> {
+> Encodable<S> for DList<T> {
     fn encode(&self, s: &mut S) {
         do s.emit_seq(self.len()) |s| {
             let mut i = 0;
@@ -665,9 +665,9 @@ impl<
     }
 }
 
-impl<D:Decoder,T:Decodable<D>> Decodable<D> for List<T> {
-    fn decode(d: &mut D) -> List<T> {
-        let mut list = List::new();
+impl<D:Decoder,T:Decodable<D>> Decodable<D> for DList<T> {
+    fn decode(d: &mut D) -> DList<T> {
+        let mut list = DList::new();
         do d.read_seq |d, len| {
             for uint::range(0, len) |i| {
                 list.push_back(d.read_seq_elt(i, |d| Decodable::decode(d)));

From 0f9b9a5fb7348471e9d51bcc298667c71647e0e1 Mon Sep 17 00:00:00 2001
From: blake2-ppc <blake2-ppc>
Date: Thu, 11 Jul 2013 16:17:51 +0200
Subject: [PATCH 12/12] extra: Mention extra::container::Deque trait in doc for
 RingBuf and DList

---
 src/libextra/dlist.rs   | 5 ++++-
 src/libextra/ringbuf.rs | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs
index 18629f8597c..fc6d05fcb58 100644
--- a/src/libextra/dlist.rs
+++ b/src/libextra/dlist.rs
@@ -11,6 +11,9 @@
 //! A doubly-linked list with owned nodes.
 //!
 //! The DList allows pushing and popping elements at either end.
+//!
+//! DList implements the trait Deque. It should be imported with `use
+//! extra::container::Deque`.
 
 
 // DList is constructed like a singly-linked list over the field `next`.
@@ -27,7 +30,7 @@ use std::iterator::FromIterator;
 
 use container::Deque;
 
-/// A doubly-linked list
+/// A doubly-linked list.
 pub struct DList<T> {
     priv length: uint,
     priv list_head: Link<T>,
diff --git a/src/libextra/ringbuf.rs b/src/libextra/ringbuf.rs
index 28eab9d9012..1d429a18a5c 100644
--- a/src/libextra/ringbuf.rs
+++ b/src/libextra/ringbuf.rs
@@ -9,6 +9,9 @@
 // except according to those terms.
 
 //! A double-ended queue implemented as a circular buffer
+//!
+//! RingBuf implements the trait Deque. It should be imported with `use
+//! extra::container::Deque`.
 
 use std::num;
 use std::util;
@@ -21,7 +24,7 @@ use container::Deque;
 static INITIAL_CAPACITY: uint = 8u; // 2^3
 static MINIMUM_CAPACITY: uint = 2u;
 
-#[allow(missing_doc)]
+/// RingBuf is a circular buffer that implements Deque.
 #[deriving(Clone)]
 pub struct RingBuf<T> {
     priv nelts: uint,