]> git.lizzy.rs Git - rust.git/commitdiff
std: Recreate a `collections` module
authorAlex Crichton <alex@alexcrichton.com>
Fri, 30 May 2014 01:50:12 +0000 (18:50 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 5 Jun 2014 20:55:10 +0000 (13:55 -0700)
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:

* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
  of libcollections is reexported through this module.

I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.

There are a number of notable points about the new organization:

* std::{str, slice, string, vec} all moved to libcollections. There is no reason
  that these primitives shouldn't be necessarily usable in a freestanding
  context that has allocation. These are all reexported in their usual places in
  the standard library.

* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
  `libcollections`, but rather in libstd. The reason for this is because the
  `HashMap::new` contructor requires access to the OSRng for initially seeding
  the hash map. Beyond this requirement, there is no reason that the hashmap
  could not move to libcollections.

  I do, however, have a plan to move the hash map to the collections module. The
  `HashMap::new` function could be altered to require that the `H` hasher
  parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
  to live in libcollections. The key idea would be that the default hasher would
  be different in libstd. Something along the lines of:

      // src/libstd/collections/mod.rs

      pub type HashMap<K, V, H = RandomizedSipHasher> =
            core_collections::HashMap<K, V, H>;

  This is not possible today because you cannot invoke static methods through
  type aliases. If we modified the compiler, however, to allow invocation of
  static methods through type aliases, then this type definition would
  essentially be switching the default hasher from `SipHasher` in libcollections
  to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
  implementation would randomly seed the `SipHasher` instance, and otherwise
  perform the same as `SipHasher`.

  This future state doesn't seem incredibly far off, but until that time comes,
  the hashmap module will live in libstd to not compromise on functionality.

* In preparation for the hashmap moving to libcollections, the `hash` module has
  moved from libstd to libcollections. A previously snapshotted commit enables a
  distinct `Writer` trait to live in the `hash` module which `Hash`
  implementations are now parameterized over.

  Due to using a custom trait, the `SipHasher` implementation has lost its
  specialized methods for writing integers. These can be re-added
  backwards-compatibly in the future via default methods if necessary, but the
  FNV hashing should satisfy much of the need for speedier hashing.

A list of breaking changes:

* HashMap::{get, get_mut} no longer fails with the key formatted into the error
  message with `{:?}`, instead, a generic message is printed. With backtraces,
  it should still be not-too-hard to track down errors.

* The HashMap, HashSet, and LruCache types are now available through
  std::collections instead of the collections crate.

* Manual implementations of hash should be parameterized over `hash::Writer`
  instead of just `Writer`.

[breaking-change]

39 files changed:
mk/crates.mk
src/libcollections/bitv.rs
src/libcollections/btree.rs
src/libcollections/deque.rs
src/libcollections/dlist.rs
src/libcollections/enum_set.rs
src/libcollections/hash/mod.rs [new file with mode: 0644]
src/libcollections/hash/sip.rs [new file with mode: 0644]
src/libcollections/hashmap.rs [deleted file]
src/libcollections/lib.rs
src/libcollections/lru_cache.rs [deleted file]
src/libcollections/macros.rs [new file with mode: 0644]
src/libcollections/priority_queue.rs
src/libcollections/ringbuf.rs
src/libcollections/slice.rs [new file with mode: 0644]
src/libcollections/smallintmap.rs
src/libcollections/str.rs [new file with mode: 0644]
src/libcollections/string.rs [new file with mode: 0644]
src/libcollections/treemap.rs
src/libcollections/trie.rs
src/libcollections/unicode.rs [new file with mode: 0644]
src/libcollections/vec.rs [new file with mode: 0644]
src/libcore/cell.rs
src/libcore/fmt/mod.rs
src/libcore/macros.rs
src/libstd/collections/hashmap.rs [new file with mode: 0644]
src/libstd/collections/lru_cache.rs [new file with mode: 0644]
src/libstd/collections/mod.rs [new file with mode: 0644]
src/libstd/from_str.rs
src/libstd/hash/mod.rs [deleted file]
src/libstd/hash/sip.rs [deleted file]
src/libstd/lib.rs
src/libstd/path/posix.rs
src/libstd/path/windows.rs
src/libstd/slice.rs [deleted file]
src/libstd/str.rs [deleted file]
src/libstd/string.rs [deleted file]
src/libstd/unicode.rs [deleted file]
src/libstd/vec.rs [deleted file]

index 9b252267aba0f8a0d6d3592afb42796020975d5f..cea9133e8351a34c920f2a0e1ea6d63c75645f13 100644 (file)
@@ -60,36 +60,36 @@ DEPS_core :=
 DEPS_rlibc :=
 DEPS_alloc := core libc native:jemalloc
 DEPS_debug := std
-DEPS_std := core rand libc alloc native:rustrt native:backtrace
+DEPS_std := core rand libc alloc collections native:rustrt native:backtrace
 DEPS_graphviz := std
 DEPS_green := std native:context_switch
 DEPS_rustuv := std native:uv native:uv_support
 DEPS_native := std
-DEPS_syntax := std term serialize collections log fmt_macros debug
+DEPS_syntax := std term serialize log fmt_macros debug
 DEPS_rustc := syntax native:rustllvm flate arena serialize sync getopts \
-              collections time log graphviz debug
-DEPS_rustdoc := rustc native:hoedown serialize sync getopts collections \
+              time log graphviz debug
+DEPS_rustdoc := rustc native:hoedown serialize sync getopts \
                 test time debug
 DEPS_flate := std native:miniz
-DEPS_arena := std collections
+DEPS_arena := std
 DEPS_graphviz := std
 DEPS_glob := std
-DEPS_serialize := std collections log
-DEPS_term := std collections log
+DEPS_serialize := std log
+DEPS_term := std log
 DEPS_semver := std
 DEPS_uuid := std serialize
 DEPS_sync := std alloc
 DEPS_getopts := std
-DEPS_collections := std debug
+DEPS_collections := core alloc
 DEPS_fourcc := syntax std
 DEPS_hexfloat := syntax std
 DEPS_num := std
-DEPS_test := std collections getopts serialize term time regex
+DEPS_test := std getopts serialize term time regex
 DEPS_time := std serialize sync
 DEPS_rand := core
-DEPS_url := std collections
+DEPS_url := std
 DEPS_log := std sync
-DEPS_regex := std collections
+DEPS_regex := std
 DEPS_regex_macros = syntax std regex
 DEPS_fmt_macros = std
 
@@ -105,6 +105,7 @@ ONLY_RLIB_libc := 1
 ONLY_RLIB_rlibc := 1
 ONLY_RLIB_alloc := 1
 ONLY_RLIB_rand := 1
+ONLY_RLIB_collections := 1
 
 ################################################################################
 # You should not need to edit below this line
index c91a5289faa130b3082e7ddccb336ee89bf50a03..6cd3616fc711cc851fb7de0c6c0c23a6d347375d 100644 (file)
 
 #![allow(missing_doc)]
 
+use core::prelude::*;
 
-use std::cmp;
-use std::fmt;
-use std::iter::RandomAccessIterator;
-use std::iter::{Enumerate, Repeat, Map, Zip};
-use std::ops;
-use std::slice;
-use std::uint;
+use core::cmp;
+use core::fmt;
+use core::iter::{Enumerate, Repeat, Map, Zip};
+use core::ops;
+use core::slice;
+use core::uint;
+
+use string::String;
+use vec::Vec;
 
 #[deriving(Clone)]
 struct SmallBitv {
index cebf21ee7e783b8ba1418ac1f0461cf84c0dd11a..d589aa73a52591560b75823e39b39e58e249d297 100644 (file)
 ///a length (the height of the tree), and lower and upper bounds on the
 ///number of elements that a given node can contain.
 
-use std::fmt;
-use std::fmt::Show;
+use core::prelude::*;
+
+use alloc::owned::Box;
+use core::fmt;
+use core::fmt::Show;
+
+use vec::Vec;
 
 #[allow(missing_doc)]
 pub struct BTree<K, V> {
index fa2cb233873d969e6dd426f241850251399d9f13..b4930173bb664131d90b1883d5c688c3d6263ee1 100644 (file)
@@ -10,7 +10,7 @@
 
 //! Container traits for collections
 
-use std::container::Mutable;
+use core::prelude::*;
 
 /// A double-ended sequence that allows querying, insertion and deletion at both ends.
 pub trait Deque<T> : Mutable {
index 014d4e680ee929158ddc18f7e586636f0e6acf24..062e94d21c097a95220c0ba3719ee7fc89f9498e 100644 (file)
 // Backlinks over DList::prev are raw pointers that form a full chain in
 // the reverse direction.
 
-use std::iter;
-use std::mem;
-use std::ptr;
+use core::prelude::*;
+
+use alloc::owned::Box;
+use core::iter;
+use core::mem;
+use core::ptr;
 
 use deque::Deque;
 
index 78485321aa5b57143506f6e3ce032fd2f4566b60..856aff64b6a22ede0e219461ea4bec9439d59238 100644 (file)
@@ -13,7 +13,9 @@
 //! This module defines a container which uses an efficient bit mask
 //! representation to hold C-like enum variants.
 
-use std::num::Bitwise;
+use core::prelude::*;
+
+use core::num::Bitwise;
 
 #[deriving(Clone, PartialEq, Eq, Hash, Show)]
 /// A specialized Set implementation to use enum types.
diff --git a/src/libcollections/hash/mod.rs b/src/libcollections/hash/mod.rs
new file mode 100644 (file)
index 0000000..067f266
--- /dev/null
@@ -0,0 +1,382 @@
+// Copyright 2012-2014 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.
+
+/*!
+ * Generic hashing support.
+ *
+ * This module provides a generic way to compute the hash of a value. The
+ * simplest way to make a type hashable is to use `#[deriving(Hash)]`:
+ *
+ * # Example
+ *
+ * ```rust
+ * use std::hash;
+ * use std::hash::Hash;
+ *
+ * #[deriving(Hash)]
+ * struct Person {
+ *     id: uint,
+ *     name: String,
+ *     phone: u64,
+ * }
+ *
+ * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
+ * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
+ *
+ * assert!(hash::hash(&person1) != hash::hash(&person2));
+ * ```
+ *
+ * If you need more control over how a value is hashed, you need to implement
+ * the trait `Hash`:
+ *
+ * ```rust
+ * use std::hash;
+ * use std::hash::Hash;
+ * use std::hash::sip::SipState;
+ *
+ * struct Person {
+ *     id: uint,
+ *     name: String,
+ *     phone: u64,
+ * }
+ *
+ * impl Hash for Person {
+ *     fn hash(&self, state: &mut SipState) {
+ *         self.id.hash(state);
+ *         self.phone.hash(state);
+ *     }
+ * }
+ *
+ * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
+ * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
+ *
+ * assert!(hash::hash(&person1) == hash::hash(&person2));
+ * ```
+ */
+
+#![allow(unused_must_use)]
+
+use core::prelude::*;
+
+use alloc::owned::Box;
+use alloc::rc::Rc;
+use core::intrinsics::TypeId;
+
+use vec::Vec;
+
+/// Reexport the `sip::hash` function as our default hasher.
+pub use hash = self::sip::hash;
+
+pub mod sip;
+
+/// A trait that represents a hashable type. The `S` type parameter is an
+/// abstract hash state that is used by the `Hash` to compute the hash.
+/// It defaults to `std::hash::sip::SipState`.
+pub trait Hash<S = sip::SipState> {
+    /// Compute a hash of the value.
+    fn hash(&self, state: &mut S);
+}
+
+/// A trait that computes a hash for a value. The main users of this trait are
+/// containers like `HashMap`, which need a generic way hash multiple types.
+pub trait Hasher<S> {
+    /// Compute a hash of the value.
+    fn hash<T: Hash<S>>(&self, value: &T) -> u64;
+}
+
+pub trait Writer {
+    fn write(&mut self, bytes: &[u8]);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+macro_rules! impl_hash(
+    ( $($ty:ident)* ) => (
+        $(
+            impl<S: Writer> Hash<S> for $ty {
+                #[inline]
+                fn hash(&self, state: &mut S) {
+                    let a: [u8, ..::core::$ty::BYTES] = unsafe {
+                        ::core::mem::transmute(*self)
+                    };
+                    state.write(a.as_slice())
+                }
+            }
+        )*
+    )
+)
+
+impl_hash!( u8 u16 u32 u64 uint i8 i16 i32 i64 int )
+
+impl<S: Writer> Hash<S> for bool {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (*self as u8).hash(state);
+    }
+}
+
+impl<S: Writer> Hash<S> for char {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (*self as u32).hash(state);
+    }
+}
+
+impl<'a, S: Writer> Hash<S> for &'a str {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        state.write(self.as_bytes());
+        0xffu8.hash(state)
+    }
+}
+
+macro_rules! impl_hash_tuple(
+    () => (
+        impl<S: Writer> Hash<S> for () {
+            #[inline]
+            fn hash(&self, state: &mut S) {
+                state.write([]);
+            }
+        }
+    );
+
+    ($A:ident $($B:ident)*) => (
+        impl<
+            S: Writer,
+            $A: Hash<S> $(, $B: Hash<S>)*
+        > Hash<S> for ($A, $($B),*) {
+            #[inline]
+            fn hash(&self, state: &mut S) {
+                match *self {
+                    (ref $A, $(ref $B),*) => {
+                        $A.hash(state);
+                        $(
+                            $B.hash(state);
+                        )*
+                    }
+                }
+            }
+        }
+
+        impl_hash_tuple!($($B)*)
+    );
+)
+
+impl_hash_tuple!(a0 a1 a2 a3 a4 a5 a6 a7)
+
+impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a [T] {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        self.len().hash(state);
+        for elt in self.iter() {
+            elt.hash(state);
+        }
+    }
+}
+
+
+impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a mut [T] {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        self.as_slice().hash(state);
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for ~[T] {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        self.as_slice().hash(state);
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for Vec<T> {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        self.as_slice().hash(state);
+    }
+}
+
+impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a T {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (**self).hash(state);
+    }
+}
+
+impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a mut T {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (**self).hash(state);
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for Box<T> {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (**self).hash(state);
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for @T {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (**self).hash(state);
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        (**self).hash(state);
+    }
+}
+
+impl<S: Writer, T: Hash<S>> Hash<S> for Option<T> {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        match *self {
+            Some(ref x) => {
+                0u8.hash(state);
+                x.hash(state);
+            }
+            None => {
+                1u8.hash(state);
+            }
+        }
+    }
+}
+
+impl<S: Writer, T> Hash<S> for *T {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        // NB: raw-pointer Hash does _not_ dereference
+        // to the target; it just gives you the pointer-bytes.
+        (*self as uint).hash(state);
+    }
+}
+
+impl<S: Writer, T> Hash<S> for *mut T {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        // NB: raw-pointer Hash does _not_ dereference
+        // to the target; it just gives you the pointer-bytes.
+        (*self as uint).hash(state);
+    }
+}
+
+impl<S: Writer> Hash<S> for TypeId {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        self.hash().hash(state)
+    }
+}
+
+impl<S: Writer, T: Hash<S>, U: Hash<S>> Hash<S> for Result<T, U> {
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        match *self {
+            Ok(ref t) => { 1u.hash(state); t.hash(state); }
+            Err(ref t) => { 2u.hash(state); t.hash(state); }
+        }
+    }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[cfg(test)]
+mod tests {
+    use mem;
+    use io::{IoResult, Writer};
+    use iter::{Iterator};
+    use option::{Some, None};
+    use result::Ok;
+    use slice::ImmutableVector;
+
+    use super::{Hash, Hasher};
+
+    struct MyWriterHasher;
+
+    impl Hasher<MyWriter> for MyWriterHasher {
+        fn hash<T: Hash<MyWriter>>(&self, value: &T) -> u64 {
+            let mut state = MyWriter { hash: 0 };
+            value.hash(&mut state);
+            state.hash
+        }
+    }
+
+    struct MyWriter {
+        hash: u64,
+    }
+
+    impl Writer for MyWriter {
+        // Most things we'll just add up the bytes.
+        fn write(&mut self, buf: &[u8]) -> IoResult<()> {
+            for byte in buf.iter() {
+                self.hash += *byte as u64;
+            }
+            Ok(())
+        }
+    }
+
+    #[test]
+    fn test_writer_hasher() {
+        let hasher = MyWriterHasher;
+
+        assert_eq!(hasher.hash(&()), 0);
+
+        assert_eq!(hasher.hash(&5u8), 5);
+        assert_eq!(hasher.hash(&5u16), 5);
+        assert_eq!(hasher.hash(&5u32), 5);
+        assert_eq!(hasher.hash(&5u64), 5);
+        assert_eq!(hasher.hash(&5u), 5);
+
+        assert_eq!(hasher.hash(&5i8), 5);
+        assert_eq!(hasher.hash(&5i16), 5);
+        assert_eq!(hasher.hash(&5i32), 5);
+        assert_eq!(hasher.hash(&5i64), 5);
+        assert_eq!(hasher.hash(&5i), 5);
+
+        assert_eq!(hasher.hash(&false), 0);
+        assert_eq!(hasher.hash(&true), 1);
+
+        assert_eq!(hasher.hash(&'a'), 97);
+
+        assert_eq!(hasher.hash(&("a")), 97 + 0xFF);
+        assert_eq!(hasher.hash(& &[1u8, 2u8, 3u8]), 9);
+
+        unsafe {
+            let ptr: *int = mem::transmute(5);
+            assert_eq!(hasher.hash(&ptr), 5);
+        }
+
+        unsafe {
+            let ptr: *mut int = mem::transmute(5);
+            assert_eq!(hasher.hash(&ptr), 5);
+        }
+    }
+
+    struct Custom {
+        hash: u64
+    }
+
+    impl Hash<u64> for Custom {
+        fn hash(&self, state: &mut u64) {
+            *state = self.hash;
+        }
+    }
+
+    #[test]
+    fn test_custom_state() {
+        let custom = Custom { hash: 5 };
+        let mut state = 0;
+        custom.hash(&mut state);
+        assert_eq!(state, 5);
+    }
+}
diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs
new file mode 100644 (file)
index 0000000..039aee7
--- /dev/null
@@ -0,0 +1,562 @@
+// Copyright 2012-2014 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.
+
+/*!
+ * Implementation of SipHash 2-4
+ *
+ * See: http://131002.net/siphash/
+ *
+ * Consider this as a main "general-purpose" hash for all hashtables: it
+ * runs at good speed (competitive with spooky and city) and permits
+ * strong _keyed_ hashing. Key your hashtables from a strong RNG,
+ * such as `rand::Rng`.
+ *
+ * Although the SipHash algorithm is considered to be cryptographically
+ * strong, this implementation has not been reviewed for such purposes.
+ * As such, all cryptographic uses of this implementation are strongly
+ * discouraged.
+ */
+
+use core::prelude::*;
+
+use core::default::Default;
+
+use super::{Hash, Hasher, Writer};
+
+/// `SipState` computes a SipHash 2-4 hash over a stream of bytes.
+pub struct SipState {
+    k0: u64,
+    k1: u64,
+    length: uint, // how many bytes we've processed
+    v0: u64,      // hash state
+    v1: u64,
+    v2: u64,
+    v3: u64,
+    tail: u64, // unprocessed bytes le
+    ntail: uint,  // how many bytes in tail are valid
+}
+
+// sadly, these macro definitions can't appear later,
+// because they're needed in the following defs;
+// this design could be improved.
+
+macro_rules! u8to64_le (
+    ($buf:expr, $i:expr) =>
+    ($buf[0+$i] as u64 |
+     $buf[1+$i] as u64 << 8 |
+     $buf[2+$i] as u64 << 16 |
+     $buf[3+$i] as u64 << 24 |
+     $buf[4+$i] as u64 << 32 |
+     $buf[5+$i] as u64 << 40 |
+     $buf[6+$i] as u64 << 48 |
+     $buf[7+$i] as u64 << 56);
+    ($buf:expr, $i:expr, $len:expr) =>
+    ({
+        let mut t = 0;
+        let mut out = 0u64;
+        while t < $len {
+            out |= $buf[t+$i] as u64 << t*8;
+            t += 1;
+        }
+        out
+    });
+)
+
+macro_rules! rotl (
+    ($x:expr, $b:expr) =>
+    (($x << $b) | ($x >> (64 - $b)))
+)
+
+macro_rules! compress (
+    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
+    ({
+        $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
+        $v0 = rotl!($v0, 32);
+        $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
+        $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
+        $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
+        $v2 = rotl!($v2, 32);
+    })
+)
+
+impl SipState {
+    /// Create a `SipState` that is keyed off the provided keys.
+    #[inline]
+    pub fn new() -> SipState {
+        SipState::new_with_keys(0, 0)
+    }
+
+    /// Create a `SipState` that is keyed off the provided keys.
+    #[inline]
+    pub fn new_with_keys(key0: u64, key1: u64) -> SipState {
+        let mut state = SipState {
+            k0: key0,
+            k1: key1,
+            length: 0,
+            v0: 0,
+            v1: 0,
+            v2: 0,
+            v3: 0,
+            tail: 0,
+            ntail: 0,
+        };
+        state.reset();
+        state
+    }
+
+    /// Reset the state back to it's initial state.
+    #[inline]
+    pub fn reset(&mut self) {
+        self.length = 0;
+        self.v0 = self.k0 ^ 0x736f6d6570736575;
+        self.v1 = self.k1 ^ 0x646f72616e646f6d;
+        self.v2 = self.k0 ^ 0x6c7967656e657261;
+        self.v3 = self.k1 ^ 0x7465646279746573;
+        self.ntail = 0;
+    }
+
+    /// Return the computed hash.
+    #[inline]
+    pub fn result(&self) -> u64 {
+        let mut v0 = self.v0;
+        let mut v1 = self.v1;
+        let mut v2 = self.v2;
+        let mut v3 = self.v3;
+
+        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
+
+        v3 ^= b;
+        compress!(v0, v1, v2, v3);
+        compress!(v0, v1, v2, v3);
+        v0 ^= b;
+
+        v2 ^= 0xff;
+        compress!(v0, v1, v2, v3);
+        compress!(v0, v1, v2, v3);
+        compress!(v0, v1, v2, v3);
+        compress!(v0, v1, v2, v3);
+
+        v0 ^ v1 ^ v2 ^ v3
+    }
+}
+
+impl Writer for SipState {
+    #[inline]
+    fn write(&mut self, msg: &[u8]) {
+        let length = msg.len();
+        self.length += length;
+
+        let mut needed = 0u;
+
+        if self.ntail != 0 {
+            needed = 8 - self.ntail;
+            if length < needed {
+                self.tail |= u8to64_le!(msg, 0, length) << 8*self.ntail;
+                self.ntail += length;
+                return
+            }
+
+            let m = self.tail | u8to64_le!(msg, 0, needed) << 8*self.ntail;
+
+            self.v3 ^= m;
+            compress!(self.v0, self.v1, self.v2, self.v3);
+            compress!(self.v0, self.v1, self.v2, self.v3);
+            self.v0 ^= m;
+
+            self.ntail = 0;
+        }
+
+        // Buffered tail is now flushed, process new input.
+        let len = length - needed;
+        let end = len & (!0x7);
+        let left = len & 0x7;
+
+        let mut i = needed;
+        while i < end {
+            let mi = u8to64_le!(msg, i);
+
+            self.v3 ^= mi;
+            compress!(self.v0, self.v1, self.v2, self.v3);
+            compress!(self.v0, self.v1, self.v2, self.v3);
+            self.v0 ^= mi;
+
+            i += 8;
+        }
+
+        self.tail = u8to64_le!(msg, i, left);
+        self.ntail = left;
+    }
+}
+
+impl Clone for SipState {
+    #[inline]
+    fn clone(&self) -> SipState {
+        *self
+    }
+}
+
+impl Default for SipState {
+    #[inline]
+    fn default() -> SipState {
+        SipState::new()
+    }
+}
+
+/// `SipHasher` computes the SipHash algorithm from a stream of bytes.
+#[deriving(Clone)]
+pub struct SipHasher {
+    k0: u64,
+    k1: u64,
+}
+
+impl SipHasher {
+    /// Create a `Sip`.
+    #[inline]
+    pub fn new() -> SipHasher {
+        SipHasher::new_with_keys(0, 0)
+    }
+
+    /// Create a `Sip` that is keyed off the provided keys.
+    #[inline]
+    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
+        SipHasher {
+            k0: key0,
+            k1: key1,
+        }
+    }
+}
+
+impl Hasher<SipState> for SipHasher {
+    #[inline]
+    fn hash<T: Hash<SipState>>(&self, value: &T) -> u64 {
+        let mut state = SipState::new_with_keys(self.k0, self.k1);
+        value.hash(&mut state);
+        state.result()
+    }
+}
+
+impl Default for SipHasher {
+    #[inline]
+    fn default() -> SipHasher {
+        SipHasher::new()
+    }
+}
+
+/// Hash a value using the SipHash algorithm.
+#[inline]
+pub fn hash<T: Hash<SipState>>(value: &T) -> u64 {
+    let mut state = SipState::new();
+    value.hash(&mut state);
+    state.result()
+}
+
+/// Hash a value with the SipHash algorithm with the provided keys.
+#[inline]
+pub fn hash_with_keys<T: Hash<SipState>>(k0: u64, k1: u64, value: &T) -> u64 {
+    let mut state = SipState::new_with_keys(k0, k1);
+    value.hash(&mut state);
+    state.result()
+}
+
+
+
+#[cfg(test)]
+mod tests {
+    extern crate test;
+    use prelude::*;
+    use num::ToStrRadix;
+    use option::{Some, None};
+    use str::Str;
+    use string::String;
+    use slice::{Vector, ImmutableVector};
+    use self::test::Bencher;
+
+    use super::super::Hash;
+    use super::{SipState, hash, hash_with_keys};
+
+    // Hash just the bytes of the slice, without length prefix
+    struct Bytes<'a>(&'a [u8]);
+
+    impl<'a, S: Writer> Hash<S> for Bytes<'a> {
+        #[allow(unused_must_use)]
+        fn hash(&self, state: &mut S) {
+            let Bytes(v) = *self;
+            state.write(v);
+        }
+    }
+
+    #[test]
+    #[allow(unused_must_use)]
+    fn test_siphash() {
+        let vecs : [[u8, ..8], ..64] = [
+            [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
+            [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
+            [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
+            [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
+            [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
+            [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
+            [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
+            [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
+            [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
+            [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
+            [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
+            [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
+            [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
+            [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
+            [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
+            [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
+            [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
+            [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
+            [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
+            [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
+            [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
+            [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
+            [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
+            [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
+            [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
+            [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
+            [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
+            [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
+            [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
+            [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
+            [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
+            [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
+            [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
+            [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
+            [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
+            [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
+            [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
+            [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
+            [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
+            [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
+            [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
+            [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
+            [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
+            [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
+            [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
+            [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
+            [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
+            [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
+            [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
+            [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
+            [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
+            [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
+            [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
+            [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
+            [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
+            [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
+            [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
+            [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
+            [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
+            [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
+            [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
+            [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
+            [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
+            [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
+        ];
+
+        let k0 = 0x_07_06_05_04_03_02_01_00_u64;
+        let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
+        let mut buf = Vec::new();
+        let mut t = 0;
+        let mut state_inc = SipState::new_with_keys(k0, k1);
+        let mut state_full = SipState::new_with_keys(k0, k1);
+
+        fn to_hex_str(r: &[u8, ..8]) -> String {
+            let mut s = String::new();
+            for b in r.iter() {
+                s.push_str((*b as uint).to_str_radix(16u).as_slice());
+            }
+            s
+        }
+
+        fn result_bytes(h: u64) -> ~[u8] {
+            box [(h >> 0) as u8,
+              (h >> 8) as u8,
+              (h >> 16) as u8,
+              (h >> 24) as u8,
+              (h >> 32) as u8,
+              (h >> 40) as u8,
+              (h >> 48) as u8,
+              (h >> 56) as u8,
+            ]
+        }
+
+        fn result_str(h: u64) -> String {
+            let r = result_bytes(h);
+            let mut s = String::new();
+            for b in r.iter() {
+                s.push_str((*b as uint).to_str_radix(16u).as_slice());
+            }
+            s
+        }
+
+        while t < 64 {
+            debug!("siphash test {}", t);
+            let vec = u8to64_le!(vecs[t], 0);
+            let out = hash_with_keys(k0, k1, &Bytes(buf.as_slice()));
+            debug!("got {:?}, expected {:?}", out, vec);
+            assert_eq!(vec, out);
+
+            state_full.reset();
+            state_full.write(buf.as_slice());
+            let f = result_str(state_full.result());
+            let i = result_str(state_inc.result());
+            let v = to_hex_str(&vecs[t]);
+            debug!("{}: ({}) => inc={} full={}", t, v, i, f);
+
+            assert!(f == i && f == v);
+
+            buf.push(t as u8);
+            state_inc.write_u8(t as u8);
+
+            t += 1;
+        }
+    }
+
+    #[test] #[cfg(target_arch = "arm")]
+    fn test_hash_uint() {
+        let val = 0xdeadbeef_deadbeef_u64;
+        assert!(hash(&(val as u64)) != hash(&(val as uint)));
+        assert_eq!(hash(&(val as u32)), hash(&(val as uint)));
+    }
+    #[test] #[cfg(target_arch = "x86_64")]
+    fn test_hash_uint() {
+        let val = 0xdeadbeef_deadbeef_u64;
+        assert_eq!(hash(&(val as u64)), hash(&(val as uint)));
+        assert!(hash(&(val as u32)) != hash(&(val as uint)));
+    }
+    #[test] #[cfg(target_arch = "x86")]
+    fn test_hash_uint() {
+        let val = 0xdeadbeef_deadbeef_u64;
+        assert!(hash(&(val as u64)) != hash(&(val as uint)));
+        assert_eq!(hash(&(val as u32)), hash(&(val as uint)));
+    }
+
+    #[test]
+    fn test_hash_idempotent() {
+        let val64 = 0xdeadbeef_deadbeef_u64;
+        assert_eq!(hash(&val64), hash(&val64));
+        let val32 = 0xdeadbeef_u32;
+        assert_eq!(hash(&val32), hash(&val32));
+    }
+
+    #[test]
+    fn test_hash_no_bytes_dropped_64() {
+        let val = 0xdeadbeef_deadbeef_u64;
+
+        assert!(hash(&val) != hash(&zero_byte(val, 0)));
+        assert!(hash(&val) != hash(&zero_byte(val, 1)));
+        assert!(hash(&val) != hash(&zero_byte(val, 2)));
+        assert!(hash(&val) != hash(&zero_byte(val, 3)));
+        assert!(hash(&val) != hash(&zero_byte(val, 4)));
+        assert!(hash(&val) != hash(&zero_byte(val, 5)));
+        assert!(hash(&val) != hash(&zero_byte(val, 6)));
+        assert!(hash(&val) != hash(&zero_byte(val, 7)));
+
+        fn zero_byte(val: u64, byte: uint) -> u64 {
+            assert!(byte < 8);
+            val & !(0xff << (byte * 8))
+        }
+    }
+
+    #[test]
+    fn test_hash_no_bytes_dropped_32() {
+        let val = 0xdeadbeef_u32;
+
+        assert!(hash(&val) != hash(&zero_byte(val, 0)));
+        assert!(hash(&val) != hash(&zero_byte(val, 1)));
+        assert!(hash(&val) != hash(&zero_byte(val, 2)));
+        assert!(hash(&val) != hash(&zero_byte(val, 3)));
+
+        fn zero_byte(val: u32, byte: uint) -> u32 {
+            assert!(byte < 4);
+            val & !(0xff << (byte * 8))
+        }
+    }
+
+    #[test]
+    fn test_hash_no_concat_alias() {
+        let s = ("aa", "bb");
+        let t = ("aabb", "");
+        let u = ("a", "abb");
+
+        assert!(s != t && t != u);
+        assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
+
+        let v = (&[1u8], &[0u8, 0], &[0u8]);
+        let w = (&[1u8, 0, 0, 0], &[], &[]);
+
+        assert!(v != w);
+        assert!(hash(&v) != hash(&w));
+    }
+
+    #[bench]
+    fn bench_str_under_8_bytes(b: &mut Bencher) {
+        let s = "foo";
+        b.iter(|| {
+            assert_eq!(hash(&s), 16262950014981195938);
+        })
+    }
+
+    #[bench]
+    fn bench_str_of_8_bytes(b: &mut Bencher) {
+        let s = "foobar78";
+        b.iter(|| {
+            assert_eq!(hash(&s), 4898293253460910787);
+        })
+    }
+
+    #[bench]
+    fn bench_str_over_8_bytes(b: &mut Bencher) {
+        let s = "foobarbaz0";
+        b.iter(|| {
+            assert_eq!(hash(&s), 10581415515220175264);
+        })
+    }
+
+    #[bench]
+    fn bench_long_str(b: &mut Bencher) {
+        let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \
+incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
+exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
+irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
+pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
+officia deserunt mollit anim id est laborum.";
+        b.iter(|| {
+            assert_eq!(hash(&s), 17717065544121360093);
+        })
+    }
+
+    #[bench]
+    fn bench_u64(b: &mut Bencher) {
+        let u = 16262950014981195938u64;
+        b.iter(|| {
+            assert_eq!(hash(&u), 5254097107239593357);
+        })
+    }
+
+    #[deriving(Hash)]
+    struct Compound {
+        x: u8,
+        y: u64,
+    }
+
+    #[bench]
+    fn bench_compound_1(b: &mut Bencher) {
+        let compound = Compound {
+            x: 1,
+            y: 2,
+        };
+        b.iter(|| {
+            assert_eq!(hash(&compound), 12506681940457338191);
+        })
+    }
+}
diff --git a/src/libcollections/hashmap.rs b/src/libcollections/hashmap.rs
deleted file mode 100644 (file)
index dfcb85a..0000000
+++ /dev/null
@@ -1,2498 +0,0 @@
-// Copyright 2014 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.
-
-//! Unordered containers, implemented as hash-tables (`HashSet` and `HashMap` types)
-
-use std::container::{Container, Mutable, Map, MutableMap, Set, MutableSet};
-use std::clone::Clone;
-use std::cmp::{PartialEq, Eq, Equiv, max};
-use std::default::Default;
-use std::fmt;
-use std::fmt::Show;
-use std::hash::{Hash, Hasher, sip};
-use std::iter;
-use std::iter::{Iterator, FromIterator, Extendable};
-use std::iter::{FilterMap, Chain, Repeat, Zip};
-use std::iter::{range, range_inclusive};
-use std::mem::replace;
-use std::num;
-use std::option::{Option, Some, None};
-use std::rand;
-use std::rand::Rng;
-use std::result::{Ok, Err};
-use std::slice::ImmutableVector;
-
-mod table {
-    use std::clone::Clone;
-    use std::cmp;
-    use std::cmp::PartialEq;
-    use std::hash::{Hash, Hasher};
-    use std::kinds::marker;
-    use std::num::{CheckedMul, is_power_of_two};
-    use std::option::{Option, Some, None};
-    use std::prelude::Drop;
-    use std::ptr;
-    use std::ptr::RawPtr;
-    use std::mem::{min_align_of, size_of};
-    use std::intrinsics::{move_val_init, set_memory, transmute};
-    use std::iter::{Iterator, range_step_inclusive};
-    use std::rt::heap::{allocate, deallocate};
-
-    static EMPTY_BUCKET: u64 = 0u64;
-
-    /// The raw hashtable, providing safe-ish access to the unzipped and highly
-    /// optimized arrays of hashes, keys, and values.
-    ///
-    /// This design uses less memory and is a lot faster than the naive
-    /// `Vec<Option<u64, K, V>>`, because we don't pay for the overhead of an
-    /// option on every element, and we get a generally more cache-aware design.
-    ///
-    /// Key invariants of this structure:
-    ///
-    ///   - if hashes[i] == EMPTY_BUCKET, then keys[i] and vals[i] have
-    ///     'undefined' contents. Don't read from them. This invariant is
-    ///     enforced outside this module with the `EmptyIndex`, `FullIndex`,
-    ///     and `SafeHash` types.
-    ///
-    ///   - An `EmptyIndex` is only constructed for a bucket at an index with
-    ///     a hash of EMPTY_BUCKET.
-    ///
-    ///   - A `FullIndex` is only constructed for a bucket at an index with a
-    ///     non-EMPTY_BUCKET hash.
-    ///
-    ///   - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
-    ///     around hashes of zero by changing them to 0x8000_0000_0000_0000,
-    ///     which will likely map to the same bucket, while not being confused
-    ///     with "empty".
-    ///
-    ///   - All three "arrays represented by pointers" are the same length:
-    ///     `capacity`. This is set at creation and never changes. The arrays
-    ///     are unzipped to save space (we don't have to pay for the padding
-    ///     between odd sized elements, such as in a map from u64 to u8), and
-    ///     be more cache aware (scanning through 8 hashes brings in 2 cache
-    ///     lines, since they're all right beside each other).
-    ///
-    /// You can kind of think of this module/data structure as a safe wrapper
-    /// around just the "table" part of the hashtable. It enforces some
-    /// invariants at the type level and employs some performance trickery,
-    /// but in general is just a tricked out `Vec<Option<u64, K, V>>`.
-    ///
-    /// FIXME(cgaebel):
-    ///
-    /// Feb 11, 2014: This hashtable was just implemented, and, hard as I tried,
-    /// isn't yet totally safe. There's a "known exploit" that you can create
-    /// multiple FullIndexes for a bucket, `take` one, and then still `take`
-    /// the other causing undefined behavior. Currently, there's no story
-    /// for how to protect against this statically. Therefore, there are asserts
-    /// on `take`, `get`, `get_mut`, and `put` which check the bucket state.
-    /// With time, and when we're confident this works correctly, they should
-    /// be removed. Also, the bounds check in `peek` is especially painful,
-    /// as that's called in the innermost loops of the hashtable and has the
-    /// potential to be a major performance drain. Remove this too.
-    ///
-    /// Or, better than remove, only enable these checks for debug builds.
-    /// There's currently no "debug-only" asserts in rust, so if you're reading
-    /// this and going "what? of course there are debug-only asserts!", then
-    /// please make this use them!
-    #[unsafe_no_drop_flag]
-    pub struct RawTable<K, V> {
-        capacity: uint,
-        size:     uint,
-        hashes:   *mut u64,
-        keys:     *mut K,
-        vals:     *mut V,
-    }
-
-    /// Represents an index into a `RawTable` with no key or value in it.
-    pub struct EmptyIndex {
-        idx:    int,
-        nocopy: marker::NoCopy,
-    }
-
-    /// Represents an index into a `RawTable` with a key, value, and hash
-    /// in it.
-    pub struct FullIndex {
-        idx:    int,
-        hash:   SafeHash,
-        nocopy: marker::NoCopy,
-    }
-
-    impl FullIndex {
-        /// Since we get the hash for free whenever we check the bucket state,
-        /// this function is provided for fast access, letting us avoid
-        /// redundant trips back to the hashtable.
-        #[inline(always)]
-        pub fn hash(&self) -> SafeHash { self.hash }
-
-        /// Same comment as with `hash`.
-        #[inline(always)]
-        pub fn raw_index(&self) -> uint { self.idx as uint }
-    }
-
-    /// Represents the state of a bucket: it can either have a key/value
-    /// pair (be full) or not (be empty). You cannot `take` empty buckets,
-    /// and you cannot `put` into full buckets.
-    pub enum BucketState {
-        Empty(EmptyIndex),
-        Full(FullIndex),
-    }
-
-    /// A hash that is not zero, since we use a hash of zero to represent empty
-    /// buckets.
-    #[deriving(PartialEq)]
-    pub struct SafeHash {
-        hash: u64,
-    }
-
-    impl SafeHash {
-        /// Peek at the hash value, which is guaranteed to be non-zero.
-        #[inline(always)]
-        pub fn inspect(&self) -> u64 { self.hash }
-    }
-
-    /// We need to remove hashes of 0. That's reserved for empty buckets.
-    /// This function wraps up `hash_keyed` to be the only way outside this
-    /// module to generate a SafeHash.
-    pub fn make_hash<T: Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
-        match hasher.hash(t) {
-            // This constant is exceedingly likely to hash to the same
-            // bucket, but it won't be counted as empty!
-            EMPTY_BUCKET => SafeHash { hash: 0x8000_0000_0000_0000 },
-            h            => SafeHash { hash: h },
-        }
-    }
-
-    fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint {
-        assert!(is_power_of_two(target_alignment));
-        (unrounded + target_alignment - 1) & !(target_alignment - 1)
-    }
-
-    #[test]
-    fn test_rounding() {
-        assert_eq!(round_up_to_next(0, 4), 0);
-        assert_eq!(round_up_to_next(1, 4), 4);
-        assert_eq!(round_up_to_next(2, 4), 4);
-        assert_eq!(round_up_to_next(3, 4), 4);
-        assert_eq!(round_up_to_next(4, 4), 4);
-        assert_eq!(round_up_to_next(5, 4), 8);
-    }
-
-    // Returns a tuple of (minimum required malloc alignment, hash_offset,
-    // key_offset, val_offset, array_size), from the start of a mallocated array.
-    fn calculate_offsets(
-        hash_size: uint, hash_align: uint,
-        keys_size: uint, keys_align: uint,
-        vals_size: uint, vals_align: uint) -> (uint, uint, uint, uint, uint) {
-
-        let hash_offset   = 0;
-        let end_of_hashes = hash_offset + hash_size;
-
-        let keys_offset   = round_up_to_next(end_of_hashes, keys_align);
-        let end_of_keys   = keys_offset + keys_size;
-
-        let vals_offset   = round_up_to_next(end_of_keys, vals_align);
-        let end_of_vals   = vals_offset + vals_size;
-
-        let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
-
-        (min_align, hash_offset, keys_offset, vals_offset, end_of_vals)
-    }
-
-    #[test]
-    fn test_offset_calculation() {
-        assert_eq!(calculate_offsets(128, 8, 15, 1, 4, 4 ), (8, 0, 128, 144, 148));
-        assert_eq!(calculate_offsets(3,   1, 2,  1, 1, 1 ), (1, 0, 3,   5,   6));
-        assert_eq!(calculate_offsets(6,   2, 12, 4, 24, 8), (8, 0, 8,   24,  48));
-    }
-
-    impl<K, V> RawTable<K, V> {
-
-        /// Does not initialize the buckets. The caller should ensure they,
-        /// at the very least, set every hash to EMPTY_BUCKET.
-        unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
-            let hashes_size =
-                capacity.checked_mul(&size_of::<u64>()).expect("capacity overflow");
-            let keys_size   =
-                capacity.checked_mul(&size_of::< K >()).expect("capacity overflow");
-            let vals_size   =
-                capacity.checked_mul(&size_of::< V >()).expect("capacity overflow");
-
-            // Allocating hashmaps is a little tricky. We need to allocate three
-            // arrays, but since we know their sizes and alignments up front,
-            // we just allocate a single array, and then have the subarrays
-            // point into it.
-            //
-            // This is great in theory, but in practice getting the alignment
-            // right is a little subtle. Therefore, calculating offsets has been
-            // factored out into a different function.
-            let (malloc_alignment, hash_offset, keys_offset, vals_offset, size) =
-                calculate_offsets(
-                    hashes_size, min_align_of::<u64>(),
-                    keys_size,   min_align_of::< K >(),
-                    vals_size,   min_align_of::< V >());
-
-            let buffer = allocate(size, malloc_alignment);
-
-            let hashes = buffer.offset(hash_offset as int) as *mut u64;
-            let keys   = buffer.offset(keys_offset as int) as *mut K;
-            let vals   = buffer.offset(vals_offset as int) as *mut V;
-
-            RawTable {
-                capacity: capacity,
-                size:     0,
-                hashes:   hashes,
-                keys:     keys,
-                vals:     vals,
-            }
-        }
-
-        /// Creates a new raw table from a given capacity. All buckets are
-        /// initially empty.
-        pub fn new(capacity: uint) -> RawTable<K, V> {
-            unsafe {
-                let ret = RawTable::new_uninitialized(capacity);
-                set_memory(ret.hashes, 0u8, capacity);
-                ret
-            }
-        }
-
-        /// Reads a bucket at a given index, returning an enum indicating whether
-        /// there's anything there or not. You need to match on this enum to get
-        /// the appropriate types to pass on to most of the other functions in
-        /// this module.
-        pub fn peek(&self, index: uint) -> BucketState {
-            debug_assert!(index < self.capacity);
-
-            let idx  = index as int;
-            let hash = unsafe { *self.hashes.offset(idx) };
-
-            let nocopy = marker::NoCopy;
-
-            match hash {
-                EMPTY_BUCKET =>
-                    Empty(EmptyIndex {
-                        idx:    idx,
-                        nocopy: nocopy
-                    }),
-                full_hash =>
-                    Full(FullIndex {
-                        idx:    idx,
-                        hash:   SafeHash { hash: full_hash },
-                        nocopy: nocopy,
-                    })
-            }
-        }
-
-        /// Gets references to the key and value at a given index.
-        pub fn read<'a>(&'a self, index: &FullIndex) -> (&'a K, &'a V) {
-            let idx = index.idx;
-
-            unsafe {
-                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (&'a *self.keys.offset(idx),
-                 &'a *self.vals.offset(idx))
-            }
-        }
-
-        /// Gets references to the key and value at a given index, with the
-        /// value's reference being mutable.
-        pub fn read_mut<'a>(&'a mut self, index: &FullIndex) -> (&'a K, &'a mut V) {
-            let idx = index.idx;
-
-            unsafe {
-                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (&'a     *self.keys.offset(idx),
-                 &'a mut *self.vals.offset(idx))
-            }
-        }
-
-        /// Read everything, mutably.
-        pub fn read_all_mut<'a>(&'a mut self, index: &FullIndex)
-            -> (&'a mut SafeHash, &'a mut K, &'a mut V) {
-            let idx = index.idx;
-
-            unsafe {
-                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-                (transmute(self.hashes.offset(idx)),
-                 &'a mut *self.keys.offset(idx),
-                 &'a mut *self.vals.offset(idx))
-            }
-        }
-
-        /// Puts a key and value pair, along with the key's hash, into a given
-        /// index in the hashtable. Note how the `EmptyIndex` is 'moved' into this
-        /// function, because that slot will no longer be empty when we return!
-        /// A FullIndex is returned for later use, pointing to the newly-filled
-        /// slot in the hashtable.
-        ///
-        /// Use `make_hash` to construct a `SafeHash` to pass to this function.
-        pub fn put(&mut self, index: EmptyIndex, hash: SafeHash, k: K, v: V) -> FullIndex {
-            let idx = index.idx;
-
-            unsafe {
-                debug_assert_eq!(*self.hashes.offset(idx), EMPTY_BUCKET);
-                *self.hashes.offset(idx) = hash.inspect();
-                move_val_init(&mut *self.keys.offset(idx), k);
-                move_val_init(&mut *self.vals.offset(idx), v);
-            }
-
-            self.size += 1;
-
-            FullIndex { idx: idx, hash: hash, nocopy: marker::NoCopy }
-        }
-
-        /// Removes a key and value from the hashtable.
-        ///
-        /// This works similarly to `put`, building an `EmptyIndex` out of the
-        /// taken FullIndex.
-        pub fn take(&mut self, index: FullIndex) -> (EmptyIndex, K, V) {
-            let idx  = index.idx;
-
-            unsafe {
-                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
-
-                *self.hashes.offset(idx) = EMPTY_BUCKET;
-
-                // Drop the mutable constraint.
-                let keys = self.keys as *K;
-                let vals = self.vals as *V;
-
-                let k = ptr::read(keys.offset(idx));
-                let v = ptr::read(vals.offset(idx));
-
-                self.size -= 1;
-
-                (EmptyIndex { idx: idx, nocopy: marker::NoCopy }, k, v)
-            }
-        }
-
-        /// The hashtable's capacity, similar to a vector's.
-        pub fn capacity(&self) -> uint {
-            self.capacity
-        }
-
-        /// The number of elements ever `put` in the hashtable, minus the number
-        /// of elements ever `take`n.
-        pub fn size(&self) -> uint {
-            self.size
-        }
-
-        pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
-            Entries { table: self, idx: 0, elems_seen: 0 }
-        }
-
-        pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
-            MutEntries { table: self, idx: 0, elems_seen: 0 }
-        }
-
-        pub fn move_iter(self) -> MoveEntries<K, V> {
-            MoveEntries { table: self, idx: 0, elems_seen: 0 }
-        }
-    }
-
-    // `read_all_mut` casts a `*u64` to a `*SafeHash`. Since we statically
-    // ensure that a `FullIndex` points to an index with a non-zero hash,
-    // and a `SafeHash` is just a `u64` with a different name, this is
-    // safe.
-    //
-    // This test ensures that a `SafeHash` really IS the same size as a
-    // `u64`. If you need to change the size of `SafeHash` (and
-    // consequently made this test fail), `read_all_mut` needs to be
-    // modified to no longer assume this.
-    #[test]
-    fn can_alias_safehash_as_u64() {
-        assert_eq!(size_of::<SafeHash>(), size_of::<u64>())
-    }
-
-    pub struct Entries<'a, K, V> {
-        table: &'a RawTable<K, V>,
-        idx: uint,
-        elems_seen: uint,
-    }
-
-    pub struct MutEntries<'a, K, V> {
-        table: &'a mut RawTable<K, V>,
-        idx: uint,
-        elems_seen: uint,
-    }
-
-    pub struct MoveEntries<K, V> {
-        table: RawTable<K, V>,
-        idx: uint,
-        elems_seen: uint,
-    }
-
-    impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
-        fn next(&mut self) -> Option<(&'a K, &'a V)> {
-            while self.idx < self.table.capacity() {
-                let i = self.idx;
-                self.idx += 1;
-
-                match self.table.peek(i) {
-                    Empty(_)  => {},
-                    Full(idx) => {
-                        self.elems_seen += 1;
-                        return Some(self.table.read(&idx));
-                    }
-                }
-            }
-
-            None
-        }
-
-        fn size_hint(&self) -> (uint, Option<uint>) {
-            let size = self.table.size() - self.elems_seen;
-            (size, Some(size))
-        }
-    }
-
-    impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
-        fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
-            while self.idx < self.table.capacity() {
-                let i = self.idx;
-                self.idx += 1;
-
-                match self.table.peek(i) {
-                    Empty(_)  => {},
-                    // the transmute here fixes:
-                    // error: lifetime of `self` is too short to guarantee its contents
-                    //        can be safely reborrowed
-                    Full(idx) => unsafe {
-                        self.elems_seen += 1;
-                        return Some(transmute(self.table.read_mut(&idx)));
-                    }
-                }
-            }
-
-            None
-        }
-
-        fn size_hint(&self) -> (uint, Option<uint>) {
-            let size = self.table.size() - self.elems_seen;
-            (size, Some(size))
-        }
-    }
-
-    impl<K, V> Iterator<(SafeHash, K, V)> for MoveEntries<K, V> {
-        fn next(&mut self) -> Option<(SafeHash, K, V)> {
-            while self.idx < self.table.capacity() {
-                let i = self.idx;
-                self.idx += 1;
-
-                match self.table.peek(i) {
-                    Empty(_) => {},
-                    Full(idx) => {
-                        let h = idx.hash();
-                        let (_, k, v) = self.table.take(idx);
-                        return Some((h, k, v));
-                    }
-                }
-            }
-
-            None
-        }
-
-        fn size_hint(&self) -> (uint, Option<uint>) {
-            let size = self.table.size();
-            (size, Some(size))
-        }
-    }
-
-    impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
-        fn clone(&self) -> RawTable<K, V> {
-            unsafe {
-                let mut new_ht = RawTable::new_uninitialized(self.capacity());
-
-                for i in range(0, self.capacity()) {
-                    match self.peek(i) {
-                        Empty(_)  => {
-                            *new_ht.hashes.offset(i as int) = EMPTY_BUCKET;
-                        },
-                        Full(idx) => {
-                            let hash = idx.hash().inspect();
-                            let (k, v) = self.read(&idx);
-                            *new_ht.hashes.offset(i as int) = hash;
-                            move_val_init(&mut *new_ht.keys.offset(i as int), (*k).clone());
-                            move_val_init(&mut *new_ht.vals.offset(i as int), (*v).clone());
-                        }
-                    }
-                }
-
-                new_ht.size = self.size();
-
-                new_ht
-            }
-        }
-    }
-
-    #[unsafe_destructor]
-    impl<K, V> Drop for RawTable<K, V> {
-        fn drop(&mut self) {
-            // This is in reverse because we're likely to have partially taken
-            // some elements out with `.move_iter()` from the front.
-            for i in range_step_inclusive(self.capacity as int - 1, 0, -1) {
-                // Check if the size is 0, so we don't do a useless scan when
-                // dropping empty tables such as on resize.
-                if self.size == 0 { break }
-
-                match self.peek(i as uint) {
-                    Empty(_)  => {},
-                    Full(idx) => { self.take(idx); }
-                }
-            }
-
-            assert_eq!(self.size, 0);
-
-            if self.hashes.is_not_null() {
-                let hashes_size = self.capacity * size_of::<u64>();
-                let keys_size = self.capacity * size_of::<K>();
-                let vals_size = self.capacity * size_of::<V>();
-                let (align, _, _, _, size) = calculate_offsets(hashes_size, min_align_of::<u64>(),
-                                                               keys_size, min_align_of::<K>(),
-                                                               vals_size, min_align_of::<V>());
-
-                unsafe {
-                    deallocate(self.hashes as *mut u8, size, align);
-                    // Remember how everything was allocated out of one buffer
-                    // during initialization? We only need one call to free here.
-                }
-
-                self.hashes = RawPtr::null();
-            }
-        }
-    }
-}
-
-static INITIAL_LOG2_CAP: uint = 5;
-static INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
-
-/// The default behavior of HashMap implements a load factor of 90.9%.
-/// This behavior is characterized by the following conditions:
-///
-/// - if `size * 1.1 < cap < size * 4` then shouldn't resize
-/// - if `cap < minimum_capacity * 2` then shouldn't shrink
-#[deriving(Clone)]
-struct DefaultResizePolicy {
-    /// Doubled minimal capacity. The capacity must never drop below
-    /// the minimum capacity. (The check happens before the capacity
-    /// is potentially halved.)
-    minimum_capacity2: uint
-}
-
-impl DefaultResizePolicy {
-    fn new(new_capacity: uint) -> DefaultResizePolicy {
-        DefaultResizePolicy {
-            minimum_capacity2: new_capacity << 1
-        }
-    }
-
-    #[inline]
-    fn capacity_range(&self, new_size: uint) -> (uint, uint) {
-        ((new_size * 11) / 10, max(new_size << 3, self.minimum_capacity2))
-    }
-
-    #[inline]
-    fn reserve(&mut self, new_capacity: uint) {
-        self.minimum_capacity2 = new_capacity << 1;
-    }
-}
-
-// The main performance trick in this hashmap is called Robin Hood Hashing.
-// It gains its excellent performance from one key invariant:
-//
-//    If an insertion collides with an existing element, and that elements
-//    "probe distance" (how far away the element is from its ideal location)
-//    is higher than how far we've already probed, swap the elements.
-//
-// This massively lowers variance in probe distance, and allows us to get very
-// high load factors with good performance. The 90% load factor I use is rather
-// conservative.
-//
-// > Why a load factor of approximately 90%?
-//
-// In general, all the distances to initial buckets will converge on the mean.
-// At a load factor of α, the odds of finding the target bucket after k
-// probes is approximately 1-α^k. If we set this equal to 50% (since we converge
-// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
-// this down to make the math easier on the CPU and avoid its FPU.
-// Since on average we start the probing in the middle of a cache line, this
-// strategy pulls in two cache lines of hashes on every lookup. I think that's
-// pretty good, but if you want to trade off some space, it could go down to one
-// cache line on average with an α of 0.84.
-//
-// > Wait, what? Where did you get 1-α^k from?
-//
-// On the first probe, your odds of a collision with an existing element is α.
-// The odds of doing this twice in a row is approximately α^2. For three times,
-// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
-// colliding after k tries is 1-α^k.
-//
-// Future Improvements (FIXME!)
-// ============================
-//
-// Allow the load factor to be changed dynamically and/or at initialization.
-//
-// Also, would it be possible for us to reuse storage when growing the
-// underlying table? This is exactly the use case for 'realloc', and may
-// be worth exploring.
-//
-// Future Optimizations (FIXME!)
-// =============================
-//
-// The paper cited below mentions an implementation which keeps track of the
-// distance-to-initial-bucket histogram. I'm suspicious of this approach because
-// it requires maintaining an internal map. If this map were replaced with a
-// hashmap, it would be faster, but now our data structure is self-referential
-// and blows up. Also, this allows very good first guesses, but array accesses
-// are no longer linear and in one direction, as we have now. There is also
-// memory and cache pressure that this map would entail that would be very
-// difficult to properly see in a microbenchmark.
-//
-// Another possible design choice that I made without any real reason is
-// parameterizing the raw table over keys and values. Technically, all we need
-// is the size and alignment of keys and values, and the code should be just as
-// efficient (well, we might need one for power-of-two size and one for not...).
-// This has the potential to reduce code bloat in rust executables, without
-// really losing anything except 4 words (key size, key alignment, val size,
-// val alignment) which can be passed in to every call of a `RawTable` function.
-// This would definitely be an avenue worth exploring if people start complaining
-// about the size of rust executables.
-//
-// There's also an "optimization" that has been omitted regarding how the
-// hashtable allocates. The vector type has set the expectation that a hashtable
-// which never has an element inserted should not allocate. I'm suspicious of
-// implementing this for hashtables, because supporting it has no performance
-// benefit over using an `Option<HashMap<K, V>>`, and is significantly more
-// complicated.
-
-/// A hash map implementation which uses linear probing with Robin
-/// Hood bucket stealing.
-///
-/// The hashes are all keyed by the task-local random number generator
-/// on creation by default, this means the ordering of the keys is
-/// randomized, but makes the tables more resistant to
-/// denial-of-service attacks (Hash DoS). This behaviour can be
-/// overridden with one of the constructors.
-///
-/// It is required that the keys implement the `PartialEq` and `Hash` traits, although
-/// this can frequently be achieved by using `#[deriving(PartialEq, Hash)]`.
-///
-/// Relevant papers/articles:
-///
-/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
-/// 2. Emmanuel Goossaert. ["Robin Hood
-///    hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
-/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
-///    deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
-///
-/// # Example
-///
-/// ```rust
-/// use collections::HashMap;
-///
-/// // type inference lets us omit an explicit type signature (which
-/// // would be `HashMap<&str, &str>` in this example).
-/// let mut book_reviews = HashMap::new();
-///
-/// // review some books.
-/// book_reviews.insert("Adventures of Huckleberry Finn",    "My favorite book.");
-/// book_reviews.insert("Grimms' Fairy Tales",               "Masterpiece.");
-/// book_reviews.insert("Pride and Prejudice",               "Very enjoyable.");
-/// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
-///
-/// // check for a specific one.
-/// if !book_reviews.contains_key(&("Les Misérables")) {
-///     println!("We've got {} reviews, but Les Misérables ain't one.",
-///              book_reviews.len());
-/// }
-///
-/// // oops, this review has a lot of spelling mistakes, let's delete it.
-/// book_reviews.remove(&("The Adventures of Sherlock Holmes"));
-///
-/// // look up the values associated with some keys.
-/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
-/// for book in to_find.iter() {
-///     match book_reviews.find(book) {
-///         Some(review) => println!("{}: {}", *book, *review),
-///         None => println!("{} is unreviewed.", *book)
-///     }
-/// }
-///
-/// // iterate over everything.
-/// for (book, review) in book_reviews.iter() {
-///     println!("{}: \"{}\"", *book, *review);
-/// }
-/// ```
-#[deriving(Clone)]
-pub struct HashMap<K, V, H = sip::SipHasher> {
-    // All hashes are keyed on these values, to prevent hash collision attacks.
-    hasher: H,
-
-    table: table::RawTable<K, V>,
-
-    // We keep this at the end since it might as well have tail padding.
-    resize_policy: DefaultResizePolicy,
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
-    // Probe the `idx`th bucket for a given hash, returning the index of the
-    // target bucket.
-    //
-    // This exploits the power-of-two size of the hashtable. As long as this
-    // is always true, we can use a bitmask of cap-1 to do modular arithmetic.
-    //
-    // Prefer using this with increasing values of `idx` rather than repeatedly
-    // calling `probe_next`. This reduces data-dependencies between loops, which
-    // can help the optimizer, and certainly won't hurt it. `probe_next` is
-    // simply for convenience, and is no more efficient than `probe`.
-    fn probe(&self, hash: &table::SafeHash, idx: uint) -> uint {
-        let hash_mask = self.table.capacity() - 1;
-
-        // So I heard a rumor that unsigned overflow is safe in rust..
-        ((hash.inspect() as uint) + idx) & hash_mask
-    }
-
-    // Generate the next probe in a sequence. Prefer using 'probe' by itself,
-    // but this can sometimes be useful.
-    fn probe_next(&self, probe: uint) -> uint {
-        let hash_mask = self.table.capacity() - 1;
-        (probe + 1) & hash_mask
-    }
-
-    fn make_hash<X: Hash<S>>(&self, x: &X) -> table::SafeHash {
-        table::make_hash(&self.hasher, x)
-    }
-
-    /// Get the distance of the bucket at the given index that it lies
-    /// from its 'ideal' location.
-    ///
-    /// In the cited blog posts above, this is called the "distance to
-    /// initial bucket", or DIB.
-    fn bucket_distance(&self, index_of_elem: &table::FullIndex) -> uint {
-        // where the hash of the element that happens to reside at
-        // `index_of_elem` tried to place itself first.
-        let first_probe_index = self.probe(&index_of_elem.hash(), 0);
-
-        let raw_index = index_of_elem.raw_index();
-
-        if first_probe_index <= raw_index {
-             // probe just went forward
-            raw_index - first_probe_index
-        } else {
-            // probe wrapped around the hashtable
-            raw_index + (self.table.capacity() - first_probe_index)
-        }
-    }
-
-    /// Search for a pre-hashed key.
-    fn search_hashed_generic(&self, hash: &table::SafeHash, is_match: |&K| -> bool)
-        -> Option<table::FullIndex> {
-        for num_probes in range(0u, self.table.size()) {
-            let probe = self.probe(hash, num_probes);
-
-            let idx = match self.table.peek(probe) {
-                table::Empty(_)  => return None, // hit an empty bucket
-                table::Full(idx) => idx
-            };
-
-            // We can finish the search early if we hit any bucket
-            // with a lower distance to initial bucket than we've probed.
-            if self.bucket_distance(&idx) < num_probes { return None }
-
-            // If the hash doesn't match, it can't be this one..
-            if *hash != idx.hash() { continue }
-
-            let (k, _) = self.table.read(&idx);
-
-            // If the key doesn't match, it can't be this one..
-            if !is_match(k) { continue }
-
-            return Some(idx);
-        }
-
-        return None
-    }
-
-    fn search_hashed(&self, hash: &table::SafeHash, k: &K) -> Option<table::FullIndex> {
-        self.search_hashed_generic(hash, |k_| *k == *k_)
-    }
-
-    fn search_equiv<Q: Hash<S> + Equiv<K>>(&self, q: &Q) -> Option<table::FullIndex> {
-        self.search_hashed_generic(&self.make_hash(q), |k| q.equiv(k))
-    }
-
-    /// Search for a key, yielding the index if it's found in the hashtable.
-    /// If you already have the hash for the key lying around, use
-    /// search_hashed.
-    fn search(&self, k: &K) -> Option<table::FullIndex> {
-        self.search_hashed(&self.make_hash(k), k)
-    }
-
-    fn pop_internal(&mut self, starting_index: table::FullIndex) -> Option<V> {
-        let starting_probe = starting_index.raw_index();
-
-        let ending_probe = {
-            let mut probe = self.probe_next(starting_probe);
-            for _ in range(0u, self.table.size()) {
-                match self.table.peek(probe) {
-                    table::Empty(_) => {}, // empty bucket. this is the end of our shifting.
-                    table::Full(idx) => {
-                        // Bucket that isn't us, which has a non-zero probe distance.
-                        // This isn't the ending index, so keep searching.
-                        if self.bucket_distance(&idx) != 0 {
-                            probe = self.probe_next(probe);
-                            continue;
-                        }
-
-                        // if we do have a bucket_distance of zero, we're at the end
-                        // of what we need to shift.
-                    }
-                }
-                break;
-            }
-
-            probe
-        };
-
-        let (_, _, retval) = self.table.take(starting_index);
-
-        let mut      probe = starting_probe;
-        let mut next_probe = self.probe_next(probe);
-
-        // backwards-shift all the elements after our newly-deleted one.
-        while next_probe != ending_probe {
-            match self.table.peek(next_probe) {
-                table::Empty(_) => {
-                    // nothing to shift in. just empty it out.
-                    match self.table.peek(probe) {
-                        table::Empty(_) => {},
-                        table::Full(idx) => { self.table.take(idx); }
-                    }
-                },
-                table::Full(next_idx) => {
-                    // something to shift. move it over!
-                    let next_hash = next_idx.hash();
-                    let (_, next_key, next_val) = self.table.take(next_idx);
-                    match self.table.peek(probe) {
-                        table::Empty(idx) => {
-                            self.table.put(idx, next_hash, next_key, next_val);
-                        },
-                        table::Full(idx) => {
-                            let (emptyidx, _, _) = self.table.take(idx);
-                            self.table.put(emptyidx, next_hash, next_key, next_val);
-                        }
-                    }
-                }
-            }
-
-            probe = next_probe;
-            next_probe = self.probe_next(next_probe);
-        }
-
-        // Done the backwards shift, but there's still an element left!
-        // Empty it out.
-        match self.table.peek(probe) {
-            table::Empty(_) => {},
-            table::Full(idx) => { self.table.take(idx); }
-        }
-
-        // Now we're done all our shifting. Return the value we grabbed
-        // earlier.
-        return Some(retval);
-    }
-
-    /// Like `pop`, but can operate on any type that is equivalent to a key.
-    #[experimental]
-    pub fn pop_equiv<Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
-        if self.table.size() == 0 {
-            return None
-        }
-
-        let potential_new_size = self.table.size() - 1;
-        self.make_some_room(potential_new_size);
-
-        let starting_index = match self.search_equiv(k) {
-            Some(idx) => idx,
-            None      => return None,
-        };
-
-        self.pop_internal(starting_index)
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
-    /// Return the number of elements in the map
-    fn len(&self) -> uint { self.table.size() }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
-    /// Clear the map, removing all key-value pairs. Keeps the allocated memory
-    /// for reuse.
-    fn clear(&mut self) {
-        // Prevent reallocations from happening from now on. Makes it possible
-        // for the map to be reused but has a downside: reserves permanently.
-        self.resize_policy.reserve(self.table.size());
-
-        for i in range(0, self.table.capacity()) {
-            match self.table.peek(i) {
-                table::Empty(_)  => {},
-                table::Full(idx) => { self.table.take(idx); }
-            }
-        }
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
-    fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
-        self.search(k).map(|idx| {
-            let (_, v) = self.table.read(&idx);
-            v
-        })
-    }
-
-    fn contains_key(&self, k: &K) -> bool {
-        self.search(k).is_some()
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
-    fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
-        match self.search(k) {
-            None => None,
-            Some(idx) => {
-                let (_, v) = self.table.read_mut(&idx);
-                Some(v)
-            }
-        }
-    }
-
-    fn swap(&mut self, k: K, v: V) -> Option<V> {
-        let hash = self.make_hash(&k);
-        let potential_new_size = self.table.size() + 1;
-        self.make_some_room(potential_new_size);
-
-        for dib in range_inclusive(0u, self.table.size()) {
-            let probe = self.probe(&hash, dib);
-
-            let idx = match self.table.peek(probe) {
-                table::Empty(idx) => {
-                    // Found a hole!
-                    self.table.put(idx, hash, k, v);
-                    return None;
-                },
-                table::Full(idx) => idx
-            };
-
-            if idx.hash() == hash {
-                let (bucket_k, bucket_v) = self.table.read_mut(&idx);
-                if k == *bucket_k {
-                    // Found an existing value.
-                    return Some(replace(bucket_v, v));
-                }
-            }
-
-            let probe_dib = self.bucket_distance(&idx);
-
-            if probe_dib < dib {
-                // Found a luckier bucket. This implies that the key does not
-                // already exist in the hashtable. Just do a robin hood
-                // insertion, then.
-                self.robin_hood(idx, probe_dib, hash, k, v);
-                return None;
-            }
-        }
-
-        // We really shouldn't be here.
-        fail!("Internal HashMap error: Out of space.");
-    }
-
-    fn pop(&mut self, k: &K) -> Option<V> {
-        if self.table.size() == 0 {
-            return None
-        }
-
-        let potential_new_size = self.table.size() - 1;
-        self.make_some_room(potential_new_size);
-
-        let starting_index = match self.search(k) {
-            Some(idx) => idx,
-            None      => return None,
-        };
-
-        self.pop_internal(starting_index)
-    }
-
-}
-
-impl<K: Hash + Eq, V> HashMap<K, V, sip::SipHasher> {
-    /// Create an empty HashMap.
-    pub fn new() -> HashMap<K, V, sip::SipHasher> {
-        HashMap::with_capacity(INITIAL_CAPACITY)
-    }
-
-    pub fn with_capacity(capacity: uint) -> HashMap<K, V, sip::SipHasher> {
-        let mut r = rand::task_rng();
-        let r0 = r.gen();
-        let r1 = r.gen();
-        let hasher = sip::SipHasher::new_with_keys(r0, r1);
-        HashMap::with_capacity_and_hasher(capacity, hasher)
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
-    pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
-        HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
-    }
-
-    /// Create an empty HashMap with space for at least `capacity`
-    /// elements, using `hasher` to hash the keys.
-    ///
-    /// Warning: `hasher` is normally randomly generated, and
-    /// is designed to allow HashMaps to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> {
-        let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity));
-        HashMap {
-            hasher:        hasher,
-            resize_policy: DefaultResizePolicy::new(cap),
-            table:         table::RawTable::new(cap),
-        }
-    }
-
-    /// The hashtable will never try to shrink below this size. You can use
-    /// this function to reduce reallocations if your hashtable frequently
-    /// grows and shrinks by large amounts.
-    ///
-    /// This function has no effect on the operational semantics of the
-    /// hashtable, only on performance.
-    pub fn reserve(&mut self, new_minimum_capacity: uint) {
-        let cap = num::next_power_of_two(
-            max(INITIAL_CAPACITY, new_minimum_capacity));
-
-        self.resize_policy.reserve(cap);
-
-        if self.table.capacity() < cap {
-            self.resize(cap);
-        }
-    }
-
-    /// Resizes the internal vectors to a new capacity. It's your responsibility to:
-    ///   1) Make sure the new capacity is enough for all the elements, accounting
-    ///      for the load factor.
-    ///   2) Ensure new_capacity is a power of two.
-    fn resize(&mut self, new_capacity: uint) {
-        assert!(self.table.size() <= new_capacity);
-        assert!(num::is_power_of_two(new_capacity));
-
-        let old_table = replace(&mut self.table, table::RawTable::new(new_capacity));
-        let old_size  = old_table.size();
-
-        for (h, k, v) in old_table.move_iter() {
-            self.insert_hashed_nocheck(h, k, v);
-        }
-
-        assert_eq!(self.table.size(), old_size);
-    }
-
-    /// Performs any necessary resize operations, such that there's space for
-    /// new_size elements.
-    fn make_some_room(&mut self, new_size: uint) {
-        let (grow_at, shrink_at) = self.resize_policy.capacity_range(new_size);
-        let cap = self.table.capacity();
-
-        // An invalid value shouldn't make us run out of space.
-        debug_assert!(grow_at >= new_size);
-
-        if cap <= grow_at {
-            let new_capacity = cap << 1;
-            self.resize(new_capacity);
-        } else if shrink_at <= cap {
-            let new_capacity = cap >> 1;
-            self.resize(new_capacity);
-        }
-    }
-
-    /// Perform robin hood bucket stealing at the given 'index'. You must
-    /// also pass that probe's "distance to initial bucket" so we don't have
-    /// to recalculate it, as well as the total number of probes already done
-    /// so we have some sort of upper bound on the number of probes to do.
-    ///
-    /// 'hash', 'k', and 'v' are the elements to robin hood into the hashtable.
-    fn robin_hood(&mut self, mut index: table::FullIndex, mut dib_param: uint,
-                  mut hash: table::SafeHash, mut k: K, mut v: V) {
-        'outer: loop {
-            let (old_hash, old_key, old_val) = {
-                let (old_hash_ref, old_key_ref, old_val_ref) =
-                        self.table.read_all_mut(&index);
-
-                let old_hash = replace(old_hash_ref, hash);
-                let old_key  = replace(old_key_ref,  k);
-                let old_val  = replace(old_val_ref,  v);
-
-                (old_hash, old_key, old_val)
-            };
-
-            let mut probe = self.probe_next(index.raw_index());
-
-            for dib in range(dib_param + 1, self.table.size()) {
-                let full_index = match self.table.peek(probe) {
-                    table::Empty(idx) => {
-                        // Finally. A hole!
-                        self.table.put(idx, old_hash, old_key, old_val);
-                        return;
-                    },
-                    table::Full(idx) => idx
-                };
-
-                let probe_dib = self.bucket_distance(&full_index);
-
-                // Robin hood! Steal the spot.
-                if probe_dib < dib {
-                    index = full_index;
-                    dib_param = probe_dib;
-                    hash = old_hash;
-                    k = old_key;
-                    v = old_val;
-                    continue 'outer;
-                }
-
-                probe = self.probe_next(probe);
-            }
-
-            fail!("HashMap fatal error: 100% load factor?");
-        }
-    }
-
-    /// Insert a pre-hashed key-value pair, without first checking
-    /// that there's enough room in the buckets. Returns a reference to the
-    /// newly insert value.
-    ///
-    /// If the key already exists, the hashtable will be returned untouched
-    /// and a reference to the existing element will be returned.
-    fn insert_hashed_nocheck<'a>(
-        &'a mut self, hash: table::SafeHash, k: K, v: V) -> &'a mut V {
-
-        for dib in range_inclusive(0u, self.table.size()) {
-            let probe = self.probe(&hash, dib);
-
-            let idx = match self.table.peek(probe) {
-                table::Empty(idx) => {
-                    // Found a hole!
-                    let fullidx  = self.table.put(idx, hash, k, v);
-                    let (_, val) = self.table.read_mut(&fullidx);
-                    return val;
-                },
-                table::Full(idx) => idx
-            };
-
-            if idx.hash() == hash {
-                let (bucket_k, bucket_v) = self.table.read_mut(&idx);
-                // FIXME #12147 the conditional return confuses
-                // borrowck if we return bucket_v directly
-                let bv: *mut V = bucket_v;
-                if k == *bucket_k {
-                    // Key already exists. Get its reference.
-                    return unsafe {&mut *bv};
-                }
-            }
-
-            let probe_dib = self.bucket_distance(&idx);
-
-            if  probe_dib < dib {
-                // Found a luckier bucket than me. Better steal his spot.
-                self.robin_hood(idx, probe_dib, hash, k, v);
-
-                // Now that it's stolen, just read the value's pointer
-                // right out of the table!
-                match self.table.peek(probe) {
-                    table::Empty(_)  => fail!("Just stole a spot, but now that spot's empty."),
-                    table::Full(idx) => {
-                        let (_, v) = self.table.read_mut(&idx);
-                        return v;
-                    }
-                }
-            }
-        }
-
-        // We really shouldn't be here.
-        fail!("Internal HashMap error: Out of space.");
-    }
-
-    /// Inserts an element which has already been hashed, returning a reference
-    /// to that element inside the hashtable. This is more efficient that using
-    /// `insert`, since the key will not be rehashed.
-    fn insert_hashed<'a>(&'a mut self, hash: table::SafeHash, k: K, v: V) -> &'a mut V {
-        let potential_new_size = self.table.size() + 1;
-        self.make_some_room(potential_new_size);
-        self.insert_hashed_nocheck(hash, k, v)
-    }
-
-    /// Return the value corresponding to the key in the map, or insert
-    /// and return the value if it doesn't exist.
-    pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
-        self.find_with_or_insert_with(k, v, |_k, _v, _a| (), |_k, a| a)
-    }
-
-    /// Return the value corresponding to the key in the map, or create,
-    /// insert, and return a new value if it doesn't exist.
-    pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: |&K| -> V)
-                               -> &'a mut V {
-        self.find_with_or_insert_with(k, (), |_k, _v, _a| (), |k, _a| f(k))
-    }
-
-    /// Insert a key-value pair into the map if the key is not already present.
-    /// Otherwise, modify the existing value for the key.
-    /// Returns the new or modified value for the key.
-    pub fn insert_or_update_with<'a>(
-                                 &'a mut self,
-                                 k: K,
-                                 v: V,
-                                 f: |&K, &mut V|)
-                                 -> &'a mut V {
-        self.find_with_or_insert_with(k, v, |k, v, _a| f(k, v), |_k, a| a)
-    }
-
-    /// Modify and return the value corresponding to the key in the map, or
-    /// insert and return a new value if it doesn't exist.
-    ///
-    /// This method allows for all insertion behaviours of a hashmap;
-    /// see methods like `insert`, `find_or_insert` and
-    /// `insert_or_update_with` for less general and more friendly
-    /// variations of this.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// use collections::HashMap;
-    ///
-    /// // map some strings to vectors of strings
-    /// let mut map = HashMap::new();
-    /// map.insert("a key", vec!["value"]);
-    /// map.insert("z key", vec!["value"]);
-    ///
-    /// let new = vec!["a key", "b key", "z key"];
-    ///
-    /// for k in new.move_iter() {
-    ///     map.find_with_or_insert_with(
-    ///         k, "new value",
-    ///         // if the key does exist either prepend or append this
-    ///         // new value based on the first letter of the key.
-    ///         |key, already, new| {
-    ///             if key.as_slice().starts_with("z") {
-    ///                 already.unshift(new);
-    ///             } else {
-    ///                 already.push(new);
-    ///             }
-    ///         },
-    ///         // if the key doesn't exist in the map yet, add it in
-    ///         // the obvious way.
-    ///         |_k, v| vec![v]);
-    /// }
-    ///
-    /// assert_eq!(map.len(), 3);
-    /// assert_eq!(map.get(&"a key"), &vec!["value", "new value"]);
-    /// assert_eq!(map.get(&"b key"), &vec!["new value"]);
-    /// assert_eq!(map.get(&"z key"), &vec!["new value", "value"]);
-    /// ```
-    pub fn find_with_or_insert_with<'a, A>(&'a mut self,
-                                           k: K,
-                                           a: A,
-                                           found: |&K, &mut V, A|,
-                                           not_found: |&K, A| -> V)
-                                          -> &'a mut V {
-        let hash = self.make_hash(&k);
-        match self.search_hashed(&hash, &k) {
-            None => {
-                let v = not_found(&k, a);
-                self.insert_hashed(hash, k, v)
-            },
-            Some(idx) => {
-                let (_, v_ref) = self.table.read_mut(&idx);
-                found(&k, v_ref, a);
-                v_ref
-            }
-        }
-    }
-
-    /// Retrieves a value for the given key, failing if the key is not present.
-    pub fn get<'a>(&'a self, k: &K) -> &'a V {
-        match self.find(k) {
-            Some(v) => v,
-            None => fail!("No entry found for key: {:?}", k)
-        }
-    }
-
-    /// Retrieves a (mutable) value for the given key, failing if the key is not present.
-    pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
-        match self.find_mut(k) {
-            Some(v) => v,
-            None => fail!("No entry found for key: {:?}", k)
-        }
-    }
-
-    /// Return true if the map contains a value for the specified key,
-    /// using equivalence.
-    pub fn contains_key_equiv<Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
-        self.search_equiv(key).is_some()
-    }
-
-    /// Return the value corresponding to the key in the map, using
-    /// equivalence.
-    pub fn find_equiv<'a, Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
-        match self.search_equiv(k) {
-            None      => None,
-            Some(idx) => {
-                let (_, v_ref) = self.table.read(&idx);
-                Some(v_ref)
-            }
-        }
-    }
-
-    /// An iterator visiting all keys in arbitrary order.
-    /// Iterator element type is &'a K.
-    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
-        self.iter().map(|(k, _v)| k)
-    }
-
-    /// An iterator visiting all values in arbitrary order.
-    /// Iterator element type is &'a V.
-    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
-        self.iter().map(|(_k, v)| v)
-    }
-
-    /// An iterator visiting all key-value pairs in arbitrary order.
-    /// Iterator element type is (&'a K, &'a V).
-    pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
-        self.table.iter()
-    }
-
-    /// An iterator visiting all key-value pairs in arbitrary order,
-    /// with mutable references to the values.
-    /// Iterator element type is (&'a K, &'a mut V).
-    pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
-        self.table.mut_iter()
-    }
-
-    /// Creates a consuming iterator, that is, one that moves each key-value
-    /// pair out of the map in arbitrary order. The map cannot be used after
-    /// calling this.
-    pub fn move_iter(self) -> MoveEntries<K, V> {
-        self.table.move_iter().map(|(_, k, v)| (k, v))
-    }
-}
-
-impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
-    /// Like `find`, but returns a copy of the value.
-    pub fn find_copy(&self, k: &K) -> Option<V> {
-        self.find(k).map(|v| (*v).clone())
-    }
-
-    /// Like `get`, but returns a copy of the value.
-    pub fn get_copy(&self, k: &K) -> V {
-        (*self.get(k)).clone()
-    }
-}
-
-impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
-    fn eq(&self, other: &HashMap<K, V, H>) -> bool {
-        if self.len() != other.len() { return false; }
-
-        self.iter()
-          .all(|(key, value)| {
-            match other.find(key) {
-                None    => false,
-                Some(v) => *value == *v
-            }
-        })
-    }
-}
-
-impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, r"\{"));
-
-        for (i, (k, v)) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{}: {}", *k, *v));
-        }
-
-        write!(f, r"\}")
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
-    fn default() -> HashMap<K, V, H> {
-        HashMap::with_hasher(Default::default())
-    }
-}
-
-/// HashMap iterator
-pub type Entries<'a, K, V> = table::Entries<'a, K, V>;
-
-/// HashMap mutable values iterator
-pub type MutEntries<'a, K, V> = table::MutEntries<'a, K, V>;
-
-/// HashMap move iterator
-pub type MoveEntries<K, V> =
-    iter::Map<'static, (table::SafeHash, K, V), (K, V), table::MoveEntries<K, V>>;
-
-/// HashMap keys iterator
-pub type Keys<'a, K, V> =
-    iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
-
-/// HashMap values iterator
-pub type Values<'a, K, V> =
-    iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
-    fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
-        let (lower, _) = iter.size_hint();
-        let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
-        map.extend(iter);
-        map
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
-    fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
-        for (k, v) in iter {
-            self.insert(k, v);
-        }
-    }
-}
-
-/// HashSet iterator
-pub type SetItems<'a, K> =
-    iter::Map<'static, (&'a K, &'a ()), &'a K, Entries<'a, K, ()>>;
-
-/// HashSet move iterator
-pub type SetMoveItems<K> =
-    iter::Map<'static, (K, ()), K, MoveEntries<K, ()>>;
-
-/// An implementation of a hash set using the underlying representation of a
-/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
-/// requires that the elements implement the `PartialEq` and `Hash` traits.
-#[deriving(Clone)]
-pub struct HashSet<T, H = sip::SipHasher> {
-    map: HashMap<T, (), H>
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
-    fn eq(&self, other: &HashSet<T, H>) -> bool {
-        if self.len() != other.len() { return false; }
-
-        self.iter().all(|key| other.contains(key))
-    }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
-    fn len(&self) -> uint { self.map.len() }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
-    fn clear(&mut self) { self.map.clear() }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
-    fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
-
-    fn is_disjoint(&self, other: &HashSet<T, H>) -> bool {
-        self.iter().all(|v| !other.contains(v))
-    }
-
-    fn is_subset(&self, other: &HashSet<T, H>) -> bool {
-        self.iter().all(|v| other.contains(v))
-    }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
-    fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
-
-    fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
-}
-
-impl<T: Hash + Eq> HashSet<T, sip::SipHasher> {
-    /// Create an empty HashSet
-    pub fn new() -> HashSet<T, sip::SipHasher> {
-        HashSet::with_capacity(INITIAL_CAPACITY)
-    }
-
-    /// Create an empty HashSet with space for at least `n` elements in
-    /// the hash table.
-    pub fn with_capacity(capacity: uint) -> HashSet<T, sip::SipHasher> {
-        HashSet { map: HashMap::with_capacity(capacity) }
-    }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
-    pub fn with_hasher(hasher: H) -> HashSet<T, H> {
-        HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
-    }
-
-    /// Create an empty HashSet with space for at least `capacity`
-    /// elements in the hash table, using `hasher` to hash the keys.
-    ///
-    /// Warning: `hasher` is normally randomly generated, and
-    /// is designed to allow `HashSet`s to be resistant to attacks that
-    /// cause many collisions and very poor performance. Setting it
-    /// manually using this function can expose a DoS attack vector.
-    pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashSet<T, H> {
-        HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) }
-    }
-
-    /// Reserve space for at least `n` elements in the hash table.
-    pub fn reserve(&mut self, n: uint) {
-        self.map.reserve(n)
-    }
-
-    /// Returns true if the hash set contains a value equivalent to the
-    /// given query value.
-    pub fn contains_equiv<Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
-      self.map.contains_key_equiv(value)
-    }
-
-    /// An iterator visiting all elements in arbitrary order.
-    /// Iterator element type is &'a T.
-    pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
-        self.map.keys()
-    }
-
-    /// Creates a consuming iterator, that is, one that moves each value out
-    /// of the set in arbitrary order. The set cannot be used after calling
-    /// this.
-    pub fn move_iter(self) -> SetMoveItems<T> {
-        self.map.move_iter().map(|(k, _)| k)
-    }
-
-    /// Visit the values representing the difference
-    pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
-        Repeat::new(other).zip(self.iter())
-            .filter_map(|(other, elt)| {
-                if !other.contains(elt) { Some(elt) } else { None }
-            })
-    }
-
-    /// Visit the values representing the symmetric difference
-    pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
-        -> Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>> {
-        self.difference(other).chain(other.difference(self))
-    }
-
-    /// Visit the values representing the intersection
-    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>)
-        -> SetAlgebraItems<'a, T, H> {
-        Repeat::new(other).zip(self.iter())
-            .filter_map(|(other, elt)| {
-                if other.contains(elt) { Some(elt) } else { None }
-            })
-    }
-
-    /// Visit the values representing the union
-    pub fn union<'a>(&'a self, other: &'a HashSet<T, H>)
-        -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>> {
-        self.iter().chain(other.difference(self))
-    }
-}
-
-impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, r"\{"));
-
-        for (i, x) in self.iter().enumerate() {
-            if i != 0 { try!(write!(f, ", ")); }
-            try!(write!(f, "{}", *x));
-        }
-
-        write!(f, r"\}")
-    }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
-    fn from_iter<I: Iterator<T>>(iter: I) -> HashSet<T, H> {
-        let (lower, _) = iter.size_hint();
-        let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
-        set.extend(iter);
-        set
-    }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
-    fn extend<I: Iterator<T>>(&mut self, mut iter: I) {
-        for k in iter {
-            self.insert(k);
-        }
-    }
-}
-
-impl<T: Eq + Hash> Default for HashSet<T, sip::SipHasher> {
-    fn default() -> HashSet<T> { HashSet::new() }
-}
-
-// `Repeat` is used to feed the filter closure an explicit capture
-// of a reference to the other set
-/// Set operations iterator
-pub type SetAlgebraItems<'a, T, H> =
-    FilterMap<'static, (&'a HashSet<T, H>, &'a T), &'a T,
-              Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>>;
-
-#[cfg(test)]
-mod test_map {
-    use super::HashMap;
-    use std::cmp::Equiv;
-    use std::hash::Hash;
-    use std::iter::{Iterator,range_inclusive,range_step_inclusive};
-    use std::cell::RefCell;
-
-    struct KindaIntLike(int);
-
-    impl Equiv<int> for KindaIntLike {
-        fn equiv(&self, other: &int) -> bool {
-            let KindaIntLike(this) = *self;
-            this == *other
-        }
-    }
-    impl<S: Writer> Hash<S> for KindaIntLike {
-        fn hash(&self, state: &mut S) {
-            let KindaIntLike(this) = *self;
-            this.hash(state)
-        }
-    }
-
-    #[test]
-    fn test_create_capacity_zero() {
-        let mut m = HashMap::with_capacity(0);
-
-        assert!(m.insert(1, 1));
-
-        assert!(m.contains_key(&1));
-        assert!(!m.contains_key(&0));
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut m = HashMap::new();
-        assert_eq!(m.len(), 0);
-        assert!(m.insert(1, 2));
-        assert_eq!(m.len(), 1);
-        assert!(m.insert(2, 4));
-        assert_eq!(m.len(), 2);
-        assert_eq!(*m.find(&1).unwrap(), 2);
-        assert_eq!(*m.find(&2).unwrap(), 4);
-    }
-
-    local_data_key!(drop_vector: RefCell<Vec<int>>)
-
-    #[deriving(Hash, PartialEq, Eq)]
-    struct Dropable {
-        k: uint
-    }
-
-
-    impl Dropable {
-        fn new(k: uint) -> Dropable {
-            let v = drop_vector.get().unwrap();
-            v.borrow_mut().as_mut_slice()[k] += 1;
-
-            Dropable { k: k }
-        }
-    }
-
-    impl Drop for Dropable {
-        fn drop(&mut self) {
-            let v = drop_vector.get().unwrap();
-            v.borrow_mut().as_mut_slice()[self.k] -= 1;
-        }
-    }
-
-    #[test]
-    fn test_drops() {
-        drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0))));
-
-        {
-            let mut m = HashMap::new();
-
-            let v = drop_vector.get().unwrap();
-            for i in range(0u, 200) {
-                assert_eq!(v.borrow().as_slice()[i], 0);
-            }
-            drop(v);
-
-            for i in range(0u, 100) {
-                let d1 = Dropable::new(i);
-                let d2 = Dropable::new(i+100);
-                m.insert(d1, d2);
-            }
-
-            let v = drop_vector.get().unwrap();
-            for i in range(0u, 200) {
-                assert_eq!(v.borrow().as_slice()[i], 1);
-            }
-            drop(v);
-
-            for i in range(0u, 50) {
-                let k = Dropable::new(i);
-                let v = m.pop(&k);
-
-                assert!(v.is_some());
-
-                let v = drop_vector.get().unwrap();
-                assert_eq!(v.borrow().as_slice()[i], 1);
-                assert_eq!(v.borrow().as_slice()[i+100], 1);
-            }
-
-            let v = drop_vector.get().unwrap();
-            for i in range(0u, 50) {
-                assert_eq!(v.borrow().as_slice()[i], 0);
-                assert_eq!(v.borrow().as_slice()[i+100], 0);
-            }
-
-            for i in range(50u, 100) {
-                assert_eq!(v.borrow().as_slice()[i], 1);
-                assert_eq!(v.borrow().as_slice()[i+100], 1);
-            }
-        }
-
-        let v = drop_vector.get().unwrap();
-        for i in range(0u, 200) {
-            assert_eq!(v.borrow().as_slice()[i], 0);
-        }
-    }
-
-    #[test]
-    fn test_empty_pop() {
-        let mut m: HashMap<int, bool> = HashMap::new();
-        assert_eq!(m.pop(&0), None);
-    }
-
-    #[test]
-    fn test_lots_of_insertions() {
-        let mut m = HashMap::new();
-
-        // Try this a few times to make sure we never screw up the hashmap's
-        // internal state.
-        for _ in range(0, 10) {
-            assert!(m.is_empty());
-
-            for i in range_inclusive(1, 1000) {
-                assert!(m.insert(i, i));
-
-                for j in range_inclusive(1, i) {
-                    let r = m.find(&j);
-                    assert_eq!(r, Some(&j));
-                }
-
-                for j in range_inclusive(i+1, 1000) {
-                    let r = m.find(&j);
-                    assert_eq!(r, None);
-                }
-            }
-
-            for i in range_inclusive(1001, 2000) {
-                assert!(!m.contains_key(&i));
-            }
-
-            // remove forwards
-            for i in range_inclusive(1, 1000) {
-                assert!(m.remove(&i));
-
-                for j in range_inclusive(1, i) {
-                    assert!(!m.contains_key(&j));
-                }
-
-                for j in range_inclusive(i+1, 1000) {
-                    assert!(m.contains_key(&j));
-                }
-            }
-
-            for i in range_inclusive(1, 1000) {
-                assert!(!m.contains_key(&i));
-            }
-
-            for i in range_inclusive(1, 1000) {
-                assert!(m.insert(i, i));
-            }
-
-            // remove backwards
-            for i in range_step_inclusive(1000, 1, -1) {
-                assert!(m.remove(&i));
-
-                for j in range_inclusive(i, 1000) {
-                    assert!(!m.contains_key(&j));
-                }
-
-                for j in range_inclusive(1, i-1) {
-                    assert!(m.contains_key(&j));
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn test_find_mut() {
-        let mut m = HashMap::new();
-        assert!(m.insert(1, 12));
-        assert!(m.insert(2, 8));
-        assert!(m.insert(5, 14));
-        let new = 100;
-        match m.find_mut(&5) {
-            None => fail!(), Some(x) => *x = new
-        }
-        assert_eq!(m.find(&5), Some(&new));
-    }
-
-    #[test]
-    fn test_insert_overwrite() {
-        let mut m = HashMap::new();
-        assert!(m.insert(1, 2));
-        assert_eq!(*m.find(&1).unwrap(), 2);
-        assert!(!m.insert(1, 3));
-        assert_eq!(*m.find(&1).unwrap(), 3);
-    }
-
-    #[test]
-    fn test_insert_conflicts() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2));
-        assert!(m.insert(5, 3));
-        assert!(m.insert(9, 4));
-        assert_eq!(*m.find(&9).unwrap(), 4);
-        assert_eq!(*m.find(&5).unwrap(), 3);
-        assert_eq!(*m.find(&1).unwrap(), 2);
-    }
-
-    #[test]
-    fn test_conflict_remove() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2));
-        assert_eq!(*m.find(&1).unwrap(), 2);
-        assert!(m.insert(5, 3));
-        assert_eq!(*m.find(&1).unwrap(), 2);
-        assert_eq!(*m.find(&5).unwrap(), 3);
-        assert!(m.insert(9, 4));
-        assert_eq!(*m.find(&1).unwrap(), 2);
-        assert_eq!(*m.find(&5).unwrap(), 3);
-        assert_eq!(*m.find(&9).unwrap(), 4);
-        assert!(m.remove(&1));
-        assert_eq!(*m.find(&9).unwrap(), 4);
-        assert_eq!(*m.find(&5).unwrap(), 3);
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let mut m = HashMap::with_capacity(4);
-        assert!(m.insert(1, 2));
-        assert!(!m.is_empty());
-        assert!(m.remove(&1));
-        assert!(m.is_empty());
-    }
-
-    #[test]
-    fn test_pop() {
-        let mut m = HashMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.pop(&1), Some(2));
-        assert_eq!(m.pop(&1), None);
-    }
-
-    #[test]
-    #[allow(experimental)]
-    fn test_pop_equiv() {
-        let mut m = HashMap::new();
-        m.insert(1, 2);
-        assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2));
-        assert_eq!(m.pop_equiv(&KindaIntLike(1)), None);
-    }
-
-    #[test]
-    fn test_swap() {
-        let mut m = HashMap::new();
-        assert_eq!(m.swap(1, 2), None);
-        assert_eq!(m.swap(1, 3), Some(2));
-        assert_eq!(m.swap(1, 4), Some(3));
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let hm = {
-            let mut hm = HashMap::new();
-
-            hm.insert('a', 1);
-            hm.insert('b', 2);
-
-            hm
-        };
-
-        let v = hm.move_iter().collect::<Vec<(char, int)>>();
-        assert!([('a', 1), ('b', 2)] == v.as_slice() || [('b', 2), ('a', 1)] == v.as_slice());
-    }
-
-    #[test]
-    fn test_iterate() {
-        let mut m = HashMap::with_capacity(4);
-        for i in range(0u, 32) {
-            assert!(m.insert(i, i*2));
-        }
-        assert_eq!(m.len(), 32);
-
-        let mut observed: u32 = 0;
-
-        for (k, v) in m.iter() {
-            assert_eq!(*v, *k * 2);
-            observed |= 1 << *k;
-        }
-        assert_eq!(observed, 0xFFFF_FFFF);
-    }
-
-    #[test]
-    fn test_keys() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map = vec.move_iter().collect::<HashMap<int, char>>();
-        let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
-        assert_eq!(keys.len(), 3);
-        assert!(keys.contains(&1));
-        assert!(keys.contains(&2));
-        assert!(keys.contains(&3));
-    }
-
-    #[test]
-    fn test_values() {
-        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
-        let map = vec.move_iter().collect::<HashMap<int, char>>();
-        let values = map.values().map(|&v| v).collect::<Vec<char>>();
-        assert_eq!(values.len(), 3);
-        assert!(values.contains(&'a'));
-        assert!(values.contains(&'b'));
-        assert!(values.contains(&'c'));
-    }
-
-    #[test]
-    fn test_find() {
-        let mut m = HashMap::new();
-        assert!(m.find(&1).is_none());
-        m.insert(1, 2);
-        match m.find(&1) {
-            None => fail!(),
-            Some(v) => assert_eq!(*v, 2)
-        }
-    }
-
-    #[test]
-    fn test_eq() {
-        let mut m1 = HashMap::new();
-        m1.insert(1, 2);
-        m1.insert(2, 3);
-        m1.insert(3, 4);
-
-        let mut m2 = HashMap::new();
-        m2.insert(1, 2);
-        m2.insert(2, 3);
-
-        assert!(m1 != m2);
-
-        m2.insert(3, 4);
-
-        assert_eq!(m1, m2);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut map: HashMap<int, int> = HashMap::new();
-        let empty: HashMap<int, int> = HashMap::new();
-
-        map.insert(1, 2);
-        map.insert(3, 4);
-
-        let map_str = format!("{}", map);
-
-        assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
-    }
-
-    #[test]
-    fn test_expand() {
-        let mut m = HashMap::new();
-
-        assert_eq!(m.len(), 0);
-        assert!(m.is_empty());
-
-        let mut i = 0u;
-        let old_cap = m.table.capacity();
-        while old_cap == m.table.capacity() {
-            m.insert(i, i);
-            i += 1;
-        }
-
-        assert_eq!(m.len(), i);
-        assert!(!m.is_empty());
-    }
-
-    #[test]
-    fn test_resize_policy() {
-        let mut m = HashMap::new();
-
-        assert_eq!(m.len(), 0);
-        assert!(m.is_empty());
-
-        let initial_cap = m.table.capacity();
-        m.reserve(initial_cap * 2);
-        let cap = m.table.capacity();
-
-        assert_eq!(cap, initial_cap * 2);
-
-        let mut i = 0u;
-        for _ in range(0, cap * 3 / 4) {
-            m.insert(i, i);
-            i += 1;
-        }
-
-        assert_eq!(m.len(), i);
-        assert_eq!(m.table.capacity(), cap);
-
-        for _ in range(0, cap / 4) {
-            m.insert(i, i);
-            i += 1;
-        }
-
-        let new_cap = m.table.capacity();
-        assert_eq!(new_cap, cap * 2);
-
-        for _ in range(0, cap / 2) {
-            i -= 1;
-            m.remove(&i);
-            assert_eq!(m.table.capacity(), new_cap);
-        }
-
-        for _ in range(0, cap / 2 - 1) {
-            i -= 1;
-            m.remove(&i);
-        }
-
-        assert_eq!(m.table.capacity(), cap);
-        assert_eq!(m.len(), i);
-        assert!(!m.is_empty());
-    }
-
-    #[test]
-    fn test_find_equiv() {
-        let mut m = HashMap::new();
-
-        let (foo, bar, baz) = (1,2,3);
-        m.insert("foo".to_string(), foo);
-        m.insert("bar".to_string(), bar);
-        m.insert("baz".to_string(), baz);
-
-
-        assert_eq!(m.find_equiv(&("foo")), Some(&foo));
-        assert_eq!(m.find_equiv(&("bar")), Some(&bar));
-        assert_eq!(m.find_equiv(&("baz")), Some(&baz));
-
-        assert_eq!(m.find_equiv(&("qux")), None);
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
-        for &(k, v) in xs.iter() {
-            assert_eq!(map.find(&k), Some(&v));
-        }
-    }
-
-    #[test]
-    fn test_size_hint() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
-        let mut iter = map.iter();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.size_hint(), (3, Some(3)));
-    }
-
-    #[test]
-    fn test_mut_size_hint() {
-        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
-
-        let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
-
-        let mut iter = map.mut_iter();
-
-        for _ in iter.by_ref().take(3) {}
-
-        assert_eq!(iter.size_hint(), (3, Some(3)));
-    }
-}
-
-#[cfg(test)]
-mod test_set {
-    use super::HashSet;
-    use std::container::Container;
-    use std::slice::ImmutableEqVector;
-
-    #[test]
-    fn test_disjoint() {
-        let mut xs = HashSet::new();
-        let mut ys = HashSet::new();
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(xs.insert(5));
-        assert!(ys.insert(11));
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(xs.insert(7));
-        assert!(xs.insert(19));
-        assert!(xs.insert(4));
-        assert!(ys.insert(2));
-        assert!(ys.insert(-11));
-        assert!(xs.is_disjoint(&ys));
-        assert!(ys.is_disjoint(&xs));
-        assert!(ys.insert(7));
-        assert!(!xs.is_disjoint(&ys));
-        assert!(!ys.is_disjoint(&xs));
-    }
-
-    #[test]
-    fn test_subset_and_superset() {
-        let mut a = HashSet::new();
-        assert!(a.insert(0));
-        assert!(a.insert(5));
-        assert!(a.insert(11));
-        assert!(a.insert(7));
-
-        let mut b = HashSet::new();
-        assert!(b.insert(0));
-        assert!(b.insert(7));
-        assert!(b.insert(19));
-        assert!(b.insert(250));
-        assert!(b.insert(11));
-        assert!(b.insert(200));
-
-        assert!(!a.is_subset(&b));
-        assert!(!a.is_superset(&b));
-        assert!(!b.is_subset(&a));
-        assert!(!b.is_superset(&a));
-
-        assert!(b.insert(5));
-
-        assert!(a.is_subset(&b));
-        assert!(!a.is_superset(&b));
-        assert!(!b.is_subset(&a));
-        assert!(b.is_superset(&a));
-    }
-
-    #[test]
-    fn test_iterate() {
-        let mut a = HashSet::new();
-        for i in range(0u, 32) {
-            assert!(a.insert(i));
-        }
-        let mut observed: u32 = 0;
-        for k in a.iter() {
-            observed |= 1 << *k;
-        }
-        assert_eq!(observed, 0xFFFF_FFFF);
-    }
-
-    #[test]
-    fn test_intersection() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(11));
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(77));
-        assert!(a.insert(103));
-        assert!(a.insert(5));
-        assert!(a.insert(-5));
-
-        assert!(b.insert(2));
-        assert!(b.insert(11));
-        assert!(b.insert(77));
-        assert!(b.insert(-9));
-        assert!(b.insert(-42));
-        assert!(b.insert(5));
-        assert!(b.insert(3));
-
-        let mut i = 0;
-        let expected = [3, 5, 11, 77];
-        for x in a.intersection(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_difference() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-
-        let mut i = 0;
-        let expected = [1, 5, 11];
-        for x in a.difference(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_symmetric_difference() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-
-        assert!(b.insert(-2));
-        assert!(b.insert(3));
-        assert!(b.insert(9));
-        assert!(b.insert(14));
-        assert!(b.insert(22));
-
-        let mut i = 0;
-        let expected = [-2, 1, 5, 11, 14, 22];
-        for x in a.symmetric_difference(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_union() {
-        let mut a = HashSet::new();
-        let mut b = HashSet::new();
-
-        assert!(a.insert(1));
-        assert!(a.insert(3));
-        assert!(a.insert(5));
-        assert!(a.insert(9));
-        assert!(a.insert(11));
-        assert!(a.insert(16));
-        assert!(a.insert(19));
-        assert!(a.insert(24));
-
-        assert!(b.insert(-2));
-        assert!(b.insert(1));
-        assert!(b.insert(5));
-        assert!(b.insert(9));
-        assert!(b.insert(13));
-        assert!(b.insert(19));
-
-        let mut i = 0;
-        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
-        for x in a.union(&b) {
-            assert!(expected.contains(x));
-            i += 1
-        }
-        assert_eq!(i, expected.len());
-    }
-
-    #[test]
-    fn test_from_iter() {
-        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
-
-        let set: HashSet<int> = xs.iter().map(|&x| x).collect();
-
-        for x in xs.iter() {
-            assert!(set.contains(x));
-        }
-    }
-
-    #[test]
-    fn test_move_iter() {
-        let hs = {
-            let mut hs = HashSet::new();
-
-            hs.insert('a');
-            hs.insert('b');
-
-            hs
-        };
-
-        let v = hs.move_iter().collect::<Vec<char>>();
-        assert!(['a', 'b'] == v.as_slice() || ['b', 'a'] == v.as_slice());
-    }
-
-    #[test]
-    fn test_eq() {
-        // These constants once happened to expose a bug in insert().
-        // I'm keeping them around to prevent a regression.
-        let mut s1 = HashSet::new();
-
-        s1.insert(1);
-        s1.insert(2);
-        s1.insert(3);
-
-        let mut s2 = HashSet::new();
-
-        s2.insert(1);
-        s2.insert(2);
-
-        assert!(s1 != s2);
-
-        s2.insert(3);
-
-        assert_eq!(s1, s2);
-    }
-
-    #[test]
-    fn test_show() {
-        let mut set: HashSet<int> = HashSet::new();
-        let empty: HashSet<int> = HashSet::new();
-
-        set.insert(1);
-        set.insert(2);
-
-        let set_str = format!("{}", set);
-
-        assert!(set_str == "{1, 2}".to_string() || set_str == "{2, 1}".to_string());
-        assert_eq!(format!("{}", empty), "{}".to_string());
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-    use std::iter::{range_inclusive};
-
-    #[bench]
-    fn new_drop(b : &mut Bencher) {
-        use super::HashMap;
-
-        b.iter(|| {
-            let m : HashMap<int, int> = HashMap::new();
-            assert_eq!(m.len(), 0);
-        })
-    }
-
-    #[bench]
-    fn new_insert_drop(b : &mut Bencher) {
-        use super::HashMap;
-
-        b.iter(|| {
-            let mut m = HashMap::new();
-            m.insert(0, 0);
-            assert_eq!(m.len(), 1);
-        })
-    }
-
-    #[bench]
-    fn insert(b: &mut Bencher) {
-        use super::HashMap;
-
-        let mut m = HashMap::new();
-
-        for i in range_inclusive(1, 1000) {
-            m.insert(i, i);
-        }
-
-        let mut k = 1001;
-
-        b.iter(|| {
-            m.insert(k, k);
-            k += 1;
-        });
-    }
-
-    #[bench]
-    fn find_existing(b: &mut Bencher) {
-        use super::HashMap;
-
-        let mut m = HashMap::new();
-
-        for i in range_inclusive(1, 1000) {
-            m.insert(i, i);
-        }
-
-        b.iter(|| {
-            for i in range_inclusive(1, 1000) {
-                m.contains_key(&i);
-            }
-        });
-    }
-
-    #[bench]
-    fn find_nonexisting(b: &mut Bencher) {
-        use super::HashMap;
-
-        let mut m = HashMap::new();
-
-        for i in range_inclusive(1, 1000) {
-            m.insert(i, i);
-        }
-
-        b.iter(|| {
-            for i in range_inclusive(1001, 2000) {
-                m.contains_key(&i);
-            }
-        });
-    }
-
-    #[bench]
-    fn hashmap_as_queue(b: &mut Bencher) {
-        use super::HashMap;
-
-        let mut m = HashMap::new();
-
-        for i in range_inclusive(1, 1000) {
-            m.insert(i, i);
-        }
-
-        let mut k = 1;
-
-        b.iter(|| {
-            m.pop(&k);
-            m.insert(k + 1000, k + 1000);
-            k += 1;
-        });
-    }
-
-    #[bench]
-    fn find_pop_insert(b: &mut Bencher) {
-        use super::HashMap;
-
-        let mut m = HashMap::new();
-
-        for i in range_inclusive(1, 1000) {
-            m.insert(i, i);
-        }
-
-        let mut k = 1;
-
-        b.iter(|| {
-            m.find(&(k + 400));
-            m.find(&(k + 2000));
-            m.pop(&k);
-            m.insert(k + 1000, k + 1000);
-            k += 1;
-        })
-    }
-}
index d1c75b895798ab33c95db763a7664382977cabbc..0ac26e686cd25c2da1c471d7e9f721a646873390 100644 (file)
 
 #![crate_id = "collections#0.11.0-pre"]
 #![crate_type = "rlib"]
-#![crate_type = "dylib"]
 #![license = "MIT/ASL2"]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
        html_root_url = "http://doc.rust-lang.org/")]
 
-#![feature(macro_rules, managed_boxes, default_type_params, phase)]
+#![feature(macro_rules, managed_boxes, default_type_params, phase, globs)]
+#![no_std]
 
-#![deny(deprecated_owned_vector)]
-
-extern crate debug;
+#[phase(syntax, link)] extern crate core;
+extern crate alloc;
 
+#[cfg(test)] extern crate native;
+#[cfg(test)] extern crate std;
 #[cfg(test)] extern crate test;
 #[cfg(test)] #[phase(syntax, link)] extern crate log;
 
-pub use bitv::Bitv;
+pub use bitv::{Bitv, BitvSet};
 pub use btree::BTree;
 pub use deque::Deque;
 pub use dlist::DList;
 pub use enum_set::EnumSet;
-pub use hashmap::{HashMap, HashSet};
-pub use lru_cache::LruCache;
 pub use priority_queue::PriorityQueue;
 pub use ringbuf::RingBuf;
 pub use smallintmap::SmallIntMap;
 pub use treemap::{TreeMap, TreeSet};
 pub use trie::{TrieMap, TrieSet};
 
+mod macros;
+
 pub mod bitv;
 pub mod btree;
 pub mod deque;
 pub mod dlist;
 pub mod enum_set;
-pub mod hashmap;
-pub mod lru_cache;
 pub mod priority_queue;
 pub mod ringbuf;
 pub mod smallintmap;
 pub mod treemap;
 pub mod trie;
+pub mod slice;
+pub mod str;
+pub mod string;
+pub mod vec;
+pub mod hash;
+
+// Internal unicode fiddly bits for the str module
+mod unicode;
+
+// FIXME(#14008) should this actually exist, or should a method be added?
+fn expect<T>(a: core::option::Option<T>, b: &str) -> T {
+    match a {
+        core::option::Some(a) => a,
+        core::option::None => fail!(b),
+    }
+}
+
+mod std {
+    pub use core::fmt;      // necessary for fail!()
+    pub use core::option;   // necessary for fail!()
+    pub use core::clone;    // deriving(Clone)
+    pub use core::cmp;      // deriving(Eq, Ord, etc.)
+    pub use hash;           // deriving(Hash)
+}
diff --git a/src/libcollections/lru_cache.rs b/src/libcollections/lru_cache.rs
deleted file mode 100644 (file)
index ea25eee..0000000
+++ /dev/null
@@ -1,343 +0,0 @@
-// 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.
-
-
-//! A cache that holds a limited number of key-value pairs. When the
-//! capacity of the cache is exceeded, the least-recently-used
-//! (where "used" means a look-up or putting the pair into the cache)
-//! pair is automatically removed.
-//!
-//! # Example
-//!
-//! ```rust
-//! use collections::LruCache;
-//!
-//! let mut cache: LruCache<int, int> = LruCache::new(2);
-//! cache.put(1, 10);
-//! cache.put(2, 20);
-//! cache.put(3, 30);
-//! assert!(cache.get(&1).is_none());
-//! assert_eq!(*cache.get(&2).unwrap(), 20);
-//! assert_eq!(*cache.get(&3).unwrap(), 30);
-//!
-//! cache.put(2, 22);
-//! assert_eq!(*cache.get(&2).unwrap(), 22);
-//!
-//! cache.put(6, 60);
-//! assert!(cache.get(&3).is_none());
-//!
-//! cache.change_capacity(1);
-//! assert!(cache.get(&2).is_none());
-//! ```
-
-use std::container::Container;
-use std::hash::Hash;
-use std::fmt;
-use std::mem;
-use std::ptr;
-
-use HashMap;
-
-struct KeyRef<K> { k: *K }
-
-struct LruEntry<K, V> {
-    next: *mut LruEntry<K, V>,
-    prev: *mut LruEntry<K, V>,
-    key: K,
-    value: V,
-}
-
-/// An LRU Cache.
-pub struct LruCache<K, V> {
-    map: HashMap<KeyRef<K>, Box<LruEntry<K, V>>>,
-    max_size: uint,
-    head: *mut LruEntry<K, V>,
-}
-
-impl<S, K: Hash<S>> Hash<S> for KeyRef<K> {
-    fn hash(&self, state: &mut S) {
-        unsafe { (*self.k).hash(state) }
-    }
-}
-
-impl<K: PartialEq> PartialEq for KeyRef<K> {
-    fn eq(&self, other: &KeyRef<K>) -> bool {
-        unsafe{ (*self.k).eq(&*other.k) }
-    }
-}
-
-impl<K: Eq> Eq for KeyRef<K> {}
-
-impl<K, V> LruEntry<K, V> {
-    fn new(k: K, v: V) -> LruEntry<K, V> {
-        LruEntry {
-            key: k,
-            value: v,
-            next: ptr::mut_null(),
-            prev: ptr::mut_null(),
-        }
-    }
-}
-
-impl<K: Hash + Eq, V> LruCache<K, V> {
-    /// Create an LRU Cache that holds at most `capacity` items.
-    pub fn new(capacity: uint) -> LruCache<K, V> {
-        let cache = LruCache {
-            map: HashMap::new(),
-            max_size: capacity,
-            head: unsafe{ mem::transmute(box mem::uninitialized::<LruEntry<K, V>>()) },
-        };
-        unsafe {
-            (*cache.head).next = cache.head;
-            (*cache.head).prev = cache.head;
-        }
-        return cache;
-    }
-
-    /// Put a key-value pair into cache.
-    pub fn put(&mut self, k: K, v: V) {
-        let (node_ptr, node_opt) = match self.map.find_mut(&KeyRef{k: &k}) {
-            Some(node) => {
-                node.value = v;
-                let node_ptr: *mut LruEntry<K, V> = &mut **node;
-                (node_ptr, None)
-            }
-            None => {
-                let mut node = box LruEntry::new(k, v);
-                let node_ptr: *mut LruEntry<K, V> = &mut *node;
-                (node_ptr, Some(node))
-            }
-        };
-        match node_opt {
-            None => {
-                // Existing node, just update LRU position
-                self.detach(node_ptr);
-                self.attach(node_ptr);
-            }
-            Some(node) => {
-                let keyref = unsafe { &(*node_ptr).key };
-                self.map.swap(KeyRef{k: keyref}, node);
-                self.attach(node_ptr);
-                if self.len() > self.capacity() {
-                    self.remove_lru();
-                }
-            }
-        }
-    }
-
-    /// Return a value corresponding to the key in the cache.
-    pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> {
-        let (value, node_ptr_opt) = match self.map.find_mut(&KeyRef{k: k}) {
-            None => (None, None),
-            Some(node) => {
-                let node_ptr: *mut LruEntry<K, V> = &mut **node;
-                (Some(unsafe { &(*node_ptr).value }), Some(node_ptr))
-            }
-        };
-        match node_ptr_opt {
-            None => (),
-            Some(node_ptr) => {
-                self.detach(node_ptr);
-                self.attach(node_ptr);
-            }
-        }
-        return value;
-    }
-
-    /// Remove and return a value corresponding to the key from the cache.
-    pub fn pop(&mut self, k: &K) -> Option<V> {
-        match self.map.pop(&KeyRef{k: k}) {
-            None => None,
-            Some(lru_entry) => Some(lru_entry.value)
-        }
-    }
-
-    /// Return the maximum number of key-value pairs the cache can hold.
-    pub fn capacity(&self) -> uint {
-        self.max_size
-    }
-
-    /// Change the number of key-value pairs the cache can hold. Remove
-    /// least-recently-used key-value pairs if necessary.
-    pub fn change_capacity(&mut self, capacity: uint) {
-        for _ in range(capacity, self.len()) {
-            self.remove_lru();
-        }
-        self.max_size = capacity;
-    }
-
-    #[inline]
-    fn remove_lru(&mut self) {
-        if self.len() > 0 {
-            let lru = unsafe { (*self.head).prev };
-            self.detach(lru);
-            self.map.pop(&KeyRef{k: unsafe { &(*lru).key }});
-        }
-    }
-
-    #[inline]
-    fn detach(&mut self, node: *mut LruEntry<K, V>) {
-        unsafe {
-            (*(*node).prev).next = (*node).next;
-            (*(*node).next).prev = (*node).prev;
-        }
-    }
-
-    #[inline]
-    fn attach(&mut self, node: *mut LruEntry<K, V>) {
-        unsafe {
-            (*node).next = (*self.head).next;
-            (*node).prev = self.head;
-            (*self.head).next = node;
-            (*(*node).next).prev = node;
-        }
-    }
-}
-
-impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
-    /// Return a string that lists the key-value pairs from most-recently
-    /// used to least-recently used.
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, r"\{"));
-        let mut cur = self.head;
-        for i in range(0, self.len()) {
-            if i > 0 { try!(write!(f, ", ")) }
-            unsafe {
-                cur = (*cur).next;
-                try!(write!(f, "{}", (*cur).key));
-            }
-            try!(write!(f, ": "));
-            unsafe {
-                try!(write!(f, "{}", (*cur).value));
-            }
-        }
-        write!(f, r"\}")
-    }
-}
-
-impl<K: Hash + Eq, V> Container for LruCache<K, V> {
-    /// Return the number of key-value pairs in the cache.
-    fn len(&self) -> uint {
-        self.map.len()
-    }
-}
-
-impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
-    /// Clear the cache of all key-value pairs.
-    fn clear(&mut self) {
-        self.map.clear();
-    }
-}
-
-#[unsafe_destructor]
-impl<K, V> Drop for LruCache<K, V> {
-    fn drop(&mut self) {
-        unsafe {
-            let node: Box<LruEntry<K, V>> = mem::transmute(self.head);
-            // Prevent compiler from trying to drop the un-initialized field in the sigil node.
-            let box LruEntry { key: k, value: v, .. } = node;
-            mem::forget(k);
-            mem::forget(v);
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::LruCache;
-
-    fn assert_opt_eq<V: PartialEq>(opt: Option<&V>, v: V) {
-        assert!(opt.is_some());
-        assert!(opt.unwrap() == &v);
-    }
-
-    #[test]
-    fn test_put_and_get() {
-        let mut cache: LruCache<int, int> = LruCache::new(2);
-        cache.put(1, 10);
-        cache.put(2, 20);
-        assert_opt_eq(cache.get(&1), 10);
-        assert_opt_eq(cache.get(&2), 20);
-        assert_eq!(cache.len(), 2);
-    }
-
-    #[test]
-    fn test_put_update() {
-        let mut cache: LruCache<String, Vec<u8>> = LruCache::new(1);
-        cache.put("1".to_string(), vec![10, 10]);
-        cache.put("1".to_string(), vec![10, 19]);
-        assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]);
-        assert_eq!(cache.len(), 1);
-    }
-
-    #[test]
-    fn test_expire_lru() {
-        let mut cache: LruCache<String, String> = LruCache::new(2);
-        cache.put("foo1".to_string(), "bar1".to_string());
-        cache.put("foo2".to_string(), "bar2".to_string());
-        cache.put("foo3".to_string(), "bar3".to_string());
-        assert!(cache.get(&"foo1".to_string()).is_none());
-        cache.put("foo2".to_string(), "bar2update".to_string());
-        cache.put("foo4".to_string(), "bar4".to_string());
-        assert!(cache.get(&"foo3".to_string()).is_none());
-    }
-
-    #[test]
-    fn test_pop() {
-        let mut cache: LruCache<int, int> = LruCache::new(2);
-        cache.put(1, 10);
-        cache.put(2, 20);
-        assert_eq!(cache.len(), 2);
-        let opt1 = cache.pop(&1);
-        assert!(opt1.is_some());
-        assert_eq!(opt1.unwrap(), 10);
-        assert!(cache.get(&1).is_none());
-        assert_eq!(cache.len(), 1);
-    }
-
-    #[test]
-    fn test_change_capacity() {
-        let mut cache: LruCache<int, int> = LruCache::new(2);
-        assert_eq!(cache.capacity(), 2);
-        cache.put(1, 10);
-        cache.put(2, 20);
-        cache.change_capacity(1);
-        assert!(cache.get(&1).is_none());
-        assert_eq!(cache.capacity(), 1);
-    }
-
-    #[test]
-    fn test_to_str() {
-        let mut cache: LruCache<int, int> = LruCache::new(3);
-        cache.put(1, 10);
-        cache.put(2, 20);
-        cache.put(3, 30);
-        assert_eq!(cache.to_str(), "{3: 30, 2: 20, 1: 10}".to_string());
-        cache.put(2, 22);
-        assert_eq!(cache.to_str(), "{2: 22, 3: 30, 1: 10}".to_string());
-        cache.put(6, 60);
-        assert_eq!(cache.to_str(), "{6: 60, 2: 22, 3: 30}".to_string());
-        cache.get(&3);
-        assert_eq!(cache.to_str(), "{3: 30, 6: 60, 2: 22}".to_string());
-        cache.change_capacity(2);
-        assert_eq!(cache.to_str(), "{3: 30, 6: 60}".to_string());
-    }
-
-    #[test]
-    fn test_clear() {
-        let mut cache: LruCache<int, int> = LruCache::new(2);
-        cache.put(1, 10);
-        cache.put(2, 20);
-        cache.clear();
-        assert!(cache.get(&1).is_none());
-        assert!(cache.get(&2).is_none());
-        assert_eq!(cache.to_str(), "{}".to_string());
-    }
-}
diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs
new file mode 100644 (file)
index 0000000..db062a7
--- /dev/null
@@ -0,0 +1,22 @@
+// Copyright 2014 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.
+
+#![macro_escape]
+
+/// Create a `std::vec::Vec` containing the arguments.
+macro_rules! vec(
+    ($($e:expr),*) => ({
+        // leading _ to allow empty construction without a warning.
+        let mut _temp = ::vec::Vec::new();
+        $(_temp.push($e);)*
+        _temp
+    });
+    ($($e:expr),+,) => (vec!($($e),+))
+)
index d73c07ee17d0bb82f2c8147e894cbc341fd44c04..d40051faf13fa22379d5590039f3a85f4136aa56 100644 (file)
 
 #![allow(missing_doc)]
 
-use std::clone::Clone;
-use std::mem::{zeroed, replace, swap};
-use std::ptr;
-use std::slice;
+use core::prelude::*;
+
+use core::mem::{overwrite, zeroed, replace, swap};
+
+use slice;
+use vec::Vec;
 
 /// A priority queue implemented with a binary heap
 #[deriving(Clone)]
index 7b8d416c4fed268ce7da558cfeeedd91b1807635..713888cf473370bc34c914d77210e66f2724d9cb 100644 (file)
 //! RingBuf implements the trait Deque. It should be imported with `use
 //! collections::deque::Deque`.
 
-use std::cmp;
-use std::fmt;
-use std::fmt::Show;
-use std::iter::RandomAccessIterator;
+use core::prelude::*;
+
+use core::cmp;
+use core::fmt;
+use core::iter::RandomAccessIterator;
 
 use deque::Deque;
+use vec::Vec;
 
 static INITIAL_CAPACITY: uint = 8u; // 2^3
 static MINIMUM_CAPACITY: uint = 2u;
@@ -393,7 +395,7 @@ fn extend<T: Iterator<A>>(&mut self, mut iterator: T) {
     }
 }
 
-impl<T: Show> Show for RingBuf<T> {
+impl<T: fmt::Show> fmt::Show for RingBuf<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "["));
 
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
new file mode 100644 (file)
index 0000000..a724307
--- /dev/null
@@ -0,0 +1,2542 @@
+// Copyright 2012-2014 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.
+
+/*!
+
+Utilities for vector manipulation
+
+The `vec` module contains useful code to help work with vector values.
+Vectors are Rust's list type. Vectors contain zero or more values of
+homogeneous types:
+
+```rust
+let int_vector = [1,2,3];
+let str_vector = ["one", "two", "three"];
+```
+
+This is a big module, but for a high-level overview:
+
+## Structs
+
+Several structs that are useful for vectors, such as `Items`, which
+represents iteration over a vector.
+
+## Traits
+
+A number of traits add methods that allow you to accomplish tasks with vectors.
+
+Traits defined for the `&[T]` type (a vector slice), have methods that can be
+called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
+These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
+case.
+
+An example is the method `.slice(a, b)` that returns an immutable "view" into
+a vector or a vector slice from the index interval `[a, b)`:
+
+```rust
+let numbers = [0, 1, 2];
+let last_numbers = numbers.slice(1, 3);
+// last_numbers is now &[1, 2]
+```
+
+Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
+on such vectors. These methods deal with adding elements or otherwise changing
+the allocation of the vector.
+
+An example is the method `.push(element)` that will add an element at the end
+of the vector:
+
+```rust
+let mut numbers = vec![0, 1, 2];
+numbers.push(7);
+// numbers is now vec![0, 1, 2, 7];
+```
+
+## Implementations of other traits
+
+Vectors are a very useful type, and so there's several implementations of
+traits from other modules. Some notable examples:
+
+* `Clone`
+* `Eq`, `Ord`, `Eq`, `Ord` -- vectors can be compared,
+  if the element type defines the corresponding trait.
+
+## Iteration
+
+The method `iter()` returns an iteration value for a vector or a vector slice.
+The iterator yields references to the vector's elements, so if the element
+type of the vector is `int`, the element type of the iterator is `&int`.
+
+```rust
+let numbers = [0, 1, 2];
+for &x in numbers.iter() {
+    println!("{} is a number!", x);
+}
+```
+
+* `.mut_iter()` returns an iterator that allows modifying each value.
+* `.move_iter()` converts an owned vector into an iterator that
+  moves out a value from the vector each iteration.
+* Further iterators exist that split, chunk or permute the vector.
+
+## Function definitions
+
+There are a number of free functions that create or take vectors, for example:
+
+* Creating a vector, like `from_elem` and `from_fn`
+* Creating a vector with a given size: `with_capacity`
+* Modifying a vector and returning it, like `append`
+* Operations on paired elements, like `unzip`.
+
+*/
+
+#![doc(primitive = "slice")]
+
+use core::prelude::*;
+
+use alloc::heap::{allocate, deallocate};
+use core::cmp;
+use core::finally::try_finally;
+use core::mem::size_of;
+use core::mem::transmute;
+use core::mem;
+use core::ptr;
+use core::iter::{range_step, MultiplicativeIterator};
+use vec::Vec;
+
+pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows};
+pub use core::slice::{Chunks, Vector, ImmutableVector, ImmutableEqVector};
+pub use core::slice::{ImmutableOrdVector, MutableVector, Items, MutItems};
+pub use core::slice::{MutSplits, MutChunks};
+pub use core::slice::{bytes, MutableCloneableVector};
+
+// Functional utilities
+
+#[allow(missing_doc)]
+pub trait VectorVector<T> {
+    // FIXME #5898: calling these .concat and .connect conflicts with
+    // StrVector::con{cat,nect}, since they have generic contents.
+    /// Flattens a vector of vectors of T into a single vector of T.
+    fn concat_vec(&self) -> Vec<T>;
+
+    /// Concatenate a vector of vectors, placing a given separator between each.
+    fn connect_vec(&self, sep: &T) -> Vec<T>;
+}
+
+impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
+    fn concat_vec(&self) -> Vec<T> {
+        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
+        let mut result = Vec::with_capacity(size);
+        for v in self.iter() {
+            result.push_all(v.as_slice())
+        }
+        result
+    }
+
+    fn connect_vec(&self, sep: &T) -> Vec<T> {
+        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
+        let mut result = Vec::with_capacity(size + self.len());
+        let mut first = true;
+        for v in self.iter() {
+            if first { first = false } else { result.push(sep.clone()) }
+            result.push_all(v.as_slice())
+        }
+        result
+    }
+}
+
+/// An Iterator that yields the element swaps needed to produce
+/// a sequence of all possible permutations for an indexed sequence of
+/// elements. Each permutation is only a single swap apart.
+///
+/// The Steinhaus–Johnson–Trotter algorithm is used.
+///
+/// Generates even and odd permutations alternately.
+///
+/// The last generated swap is always (0, 1), and it returns the
+/// sequence to its initial order.
+pub struct ElementSwaps {
+    sdir: Vec<SizeDirection>,
+    /// If true, emit the last swap that returns the sequence to initial state
+    emit_reset: bool,
+    swaps_made : uint,
+}
+
+impl ElementSwaps {
+    /// Create an `ElementSwaps` iterator for a sequence of `length` elements
+    pub fn new(length: uint) -> ElementSwaps {
+        // Initialize `sdir` with a direction that position should move in
+        // (all negative at the beginning) and the `size` of the
+        // element (equal to the original index).
+        ElementSwaps{
+            emit_reset: true,
+            sdir: range(0, length).map(|i| SizeDirection{ size: i, dir: Neg }).collect(),
+            swaps_made: 0
+        }
+    }
+}
+
+enum Direction { Pos, Neg }
+
+/// An Index and Direction together
+struct SizeDirection {
+    size: uint,
+    dir: Direction,
+}
+
+impl Iterator<(uint, uint)> for ElementSwaps {
+    #[inline]
+    fn next(&mut self) -> Option<(uint, uint)> {
+        fn new_pos(i: uint, s: Direction) -> uint {
+            i + match s { Pos => 1, Neg => -1 }
+        }
+
+        // Find the index of the largest mobile element:
+        // The direction should point into the vector, and the
+        // swap should be with a smaller `size` element.
+        let max = self.sdir.iter().map(|&x| x).enumerate()
+                           .filter(|&(i, sd)|
+                                new_pos(i, sd.dir) < self.sdir.len() &&
+                                self.sdir.get(new_pos(i, sd.dir)).size < sd.size)
+                           .max_by(|&(_, sd)| sd.size);
+        match max {
+            Some((i, sd)) => {
+                let j = new_pos(i, sd.dir);
+                self.sdir.as_mut_slice().swap(i, j);
+
+                // Swap the direction of each larger SizeDirection
+                for x in self.sdir.mut_iter() {
+                    if x.size > sd.size {
+                        x.dir = match x.dir { Pos => Neg, Neg => Pos };
+                    }
+                }
+                self.swaps_made += 1;
+                Some((i, j))
+            },
+            None => if self.emit_reset {
+                self.emit_reset = false;
+                if self.sdir.len() > 1 {
+                    // The last swap
+                    self.swaps_made += 1;
+                    Some((0, 1))
+                } else {
+                    // Vector is of the form [] or [x], and the only permutation is itself
+                    self.swaps_made += 1;
+                    Some((0,0))
+                }
+            } else { None }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        // For a vector of size n, there are exactly n! permutations.
+        let n = range(2, self.sdir.len() + 1).product();
+        (n - self.swaps_made, Some(n - self.swaps_made))
+    }
+}
+
+/// An Iterator that uses `ElementSwaps` to iterate through
+/// all possible permutations of a vector.
+///
+/// The first iteration yields a clone of the vector as it is,
+/// then each successive element is the vector with one
+/// swap applied.
+///
+/// Generates even and odd permutations alternately.
+pub struct Permutations<T> {
+    swaps: ElementSwaps,
+    v: ~[T],
+}
+
+impl<T: Clone> Iterator<~[T]> for Permutations<T> {
+    #[inline]
+    fn next(&mut self) -> Option<~[T]> {
+        match self.swaps.next() {
+            None => None,
+            Some((0,0)) => Some(self.v.clone()),
+            Some((a, b)) => {
+                let elt = self.v.clone();
+                self.v.swap(a, b);
+                Some(elt)
+            }
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.swaps.size_hint()
+    }
+}
+
+/// Extension methods for vector slices with cloneable elements
+pub trait CloneableVector<T> {
+    /// Copy `self` into a new owned vector
+    fn to_owned(&self) -> ~[T];
+
+    /// Convert `self` into an owned vector, not making a copy if possible.
+    fn into_owned(self) -> ~[T];
+}
+
+/// Extension methods for vector slices
+impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
+    /// Returns a copy of `v`.
+    #[inline]
+    fn to_owned(&self) -> ~[T] {
+        use RawVec = core::raw::Vec;
+        use core::num::{CheckedAdd, CheckedMul};
+
+        let len = self.len();
+        let data_size = len.checked_mul(&mem::size_of::<T>());
+        let data_size = ::expect(data_size, "overflow in to_owned()");
+        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
+        let size = ::expect(size, "overflow in to_owned()");
+
+        unsafe {
+            // this should pass the real required alignment
+            let ret = allocate(size, 8) as *mut RawVec<()>;
+
+            let a_size = mem::size_of::<T>();
+            let a_size = if a_size == 0 {1} else {a_size};
+            (*ret).fill = len * a_size;
+            (*ret).alloc = len * a_size;
+
+            // Be careful with the following loop. We want it to be optimized
+            // to a memcpy (or something similarly fast) when T is Copy. LLVM
+            // is easily confused, so any extra operations during the loop can
+            // prevent this optimization.
+            let mut i = 0;
+            let p = &mut (*ret).data as *mut _ as *mut T;
+            try_finally(
+                &mut i, (),
+                |i, ()| while *i < len {
+                    mem::overwrite(
+                        &mut(*p.offset(*i as int)),
+                        self.unsafe_ref(*i).clone());
+                    *i += 1;
+                },
+                |i| if *i < len {
+                    // we must be failing, clean up after ourselves
+                    for j in range(0, *i as int) {
+                        ptr::read(&*p.offset(j));
+                    }
+                    // FIXME: #13994 (should pass align and size here)
+                    deallocate(ret as *mut u8, 0, 8);
+                });
+            mem::transmute(ret)
+        }
+    }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self.to_owned() }
+}
+
+/// Extension methods for owned vectors
+impl<T: Clone> CloneableVector<T> for ~[T] {
+    #[inline]
+    fn to_owned(&self) -> ~[T] { self.clone() }
+
+    #[inline(always)]
+    fn into_owned(self) -> ~[T] { self }
+}
+
+/// Extension methods for vectors containing `Clone` elements.
+pub trait ImmutableCloneableVector<T> {
+    /// Partitions the vector into two vectors `(A,B)`, where all
+    /// elements of `A` satisfy `f` and all elements of `B` do not.
+    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
+
+    /// Create an iterator that yields every possible permutation of the
+    /// vector in succession.
+    fn permutations(self) -> Permutations<T>;
+}
+
+impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
+    #[inline]
+    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+        let mut lefts  = Vec::new();
+        let mut rights = Vec::new();
+
+        for elt in self.iter() {
+            if f(elt) {
+                lefts.push((*elt).clone());
+            } else {
+                rights.push((*elt).clone());
+            }
+        }
+
+        (lefts, rights)
+    }
+
+    fn permutations(self) -> Permutations<T> {
+        Permutations{
+            swaps: ElementSwaps::new(self.len()),
+            v: self.to_owned(),
+        }
+    }
+
+}
+
+/// Extension methods for owned vectors.
+pub trait OwnedVector<T> {
+    /// Creates a consuming iterator, that is, one that moves each
+    /// value out of the vector (from start to end). The vector cannot
+    /// be used after calling this.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// let v = ~["a".to_string(), "b".to_string()];
+    /// for s in v.move_iter() {
+    ///   // s has type ~str, not &~str
+    ///   println!("{}", s);
+    /// }
+    /// ```
+    fn move_iter(self) -> MoveItems<T>;
+
+    /**
+     * Partitions the vector into two vectors `(A,B)`, where all
+     * elements of `A` satisfy `f` and all elements of `B` do not.
+     */
+    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
+}
+
+impl<T> OwnedVector<T> for ~[T] {
+    #[inline]
+    fn move_iter(self) -> MoveItems<T> {
+        unsafe {
+            let iter = transmute(self.iter());
+            let ptr = transmute(self);
+            MoveItems { allocation: ptr, iter: iter }
+        }
+    }
+
+    #[inline]
+    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+        let mut lefts  = Vec::new();
+        let mut rights = Vec::new();
+
+        for elt in self.move_iter() {
+            if f(&elt) {
+                lefts.push(elt);
+            } else {
+                rights.push(elt);
+            }
+        }
+
+        (lefts, rights)
+    }
+}
+
+fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
+    let len = v.len() as int;
+    let buf_v = v.as_mut_ptr();
+
+    // 1 <= i < len;
+    for i in range(1, len) {
+        // j satisfies: 0 <= j <= i;
+        let mut j = i;
+        unsafe {
+            // `i` is in bounds.
+            let read_ptr = buf_v.offset(i) as *T;
+
+            // find where to insert, we need to do strict <,
+            // rather than <=, to maintain stability.
+
+            // 0 <= j - 1 < len, so .offset(j - 1) is in bounds.
+            while j > 0 &&
+                    compare(&*read_ptr, &*buf_v.offset(j - 1)) == Less {
+                j -= 1;
+            }
+
+            // shift everything to the right, to make space to
+            // insert this value.
+
+            // j + 1 could be `len` (for the last `i`), but in
+            // that case, `i == j` so we don't copy. The
+            // `.offset(j)` is always in bounds.
+
+            if i != j {
+                let tmp = ptr::read(read_ptr);
+                ptr::copy_memory(buf_v.offset(j + 1),
+                                 &*buf_v.offset(j),
+                                 (i - j) as uint);
+                ptr::copy_nonoverlapping_memory(buf_v.offset(j),
+                                                &tmp as *T,
+                                                1);
+                mem::forget(tmp);
+            }
+        }
+    }
+}
+
+fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
+    // warning: this wildly uses unsafe.
+    static BASE_INSERTION: uint = 32;
+    static LARGE_INSERTION: uint = 16;
+
+    // FIXME #12092: smaller insertion runs seems to make sorting
+    // vectors of large elements a little faster on some platforms,
+    // but hasn't been tested/tuned extensively
+    let insertion = if size_of::<T>() <= 16 {
+        BASE_INSERTION
+    } else {
+        LARGE_INSERTION
+    };
+
+    let len = v.len();
+
+    // short vectors get sorted in-place via insertion sort to avoid allocations
+    if len <= insertion {
+        insertion_sort(v, compare);
+        return;
+    }
+
+    // allocate some memory to use as scratch memory, we keep the
+    // length 0 so we can keep shallow copies of the contents of `v`
+    // without risking the dtors running on an object twice if
+    // `compare` fails.
+    let mut working_space = Vec::with_capacity(2 * len);
+    // these both are buffers of length `len`.
+    let mut buf_dat = working_space.as_mut_ptr();
+    let mut buf_tmp = unsafe {buf_dat.offset(len as int)};
+
+    // length `len`.
+    let buf_v = v.as_ptr();
+
+    // step 1. sort short runs with insertion sort. This takes the
+    // values from `v` and sorts them into `buf_dat`, leaving that
+    // with sorted runs of length INSERTION.
+
+    // We could hardcode the sorting comparisons here, and we could
+    // manipulate/step the pointers themselves, rather than repeatedly
+    // .offset-ing.
+    for start in range_step(0, len, insertion) {
+        // start <= i < len;
+        for i in range(start, cmp::min(start + insertion, len)) {
+            // j satisfies: start <= j <= i;
+            let mut j = i as int;
+            unsafe {
+                // `i` is in bounds.
+                let read_ptr = buf_v.offset(i as int);
+
+                // find where to insert, we need to do strict <,
+                // rather than <=, to maintain stability.
+
+                // start <= j - 1 < len, so .offset(j - 1) is in
+                // bounds.
+                while j > start as int &&
+                        compare(&*read_ptr, &*buf_dat.offset(j - 1)) == Less {
+                    j -= 1;
+                }
+
+                // shift everything to the right, to make space to
+                // insert this value.
+
+                // j + 1 could be `len` (for the last `i`), but in
+                // that case, `i == j` so we don't copy. The
+                // `.offset(j)` is always in bounds.
+                ptr::copy_memory(buf_dat.offset(j + 1),
+                                 &*buf_dat.offset(j),
+                                 i - j as uint);
+                ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
+            }
+        }
+    }
+
+    // step 2. merge the sorted runs.
+    let mut width = insertion;
+    while width < len {
+        // merge the sorted runs of length `width` in `buf_dat` two at
+        // a time, placing the result in `buf_tmp`.
+
+        // 0 <= start <= len.
+        for start in range_step(0, len, 2 * width) {
+            // manipulate pointers directly for speed (rather than
+            // using a `for` loop with `range` and `.offset` inside
+            // that loop).
+            unsafe {
+                // the end of the first run & start of the
+                // second. Offset of `len` is defined, since this is
+                // precisely one byte past the end of the object.
+                let right_start = buf_dat.offset(cmp::min(start + width, len) as int);
+                // end of the second. Similar reasoning to the above re safety.
+                let right_end_idx = cmp::min(start + 2 * width, len);
+                let right_end = buf_dat.offset(right_end_idx as int);
+
+                // the pointers to the elements under consideration
+                // from the two runs.
+
+                // both of these are in bounds.
+                let mut left = buf_dat.offset(start as int);
+                let mut right = right_start;
+
+                // where we're putting the results, it is a run of
+                // length `2*width`, so we step it once for each step
+                // of either `left` or `right`.  `buf_tmp` has length
+                // `len`, so these are in bounds.
+                let mut out = buf_tmp.offset(start as int);
+                let out_end = buf_tmp.offset(right_end_idx as int);
+
+                while out < out_end {
+                    // Either the left or the right run are exhausted,
+                    // so just copy the remainder from the other run
+                    // and move on; this gives a huge speed-up (order
+                    // of 25%) for mostly sorted vectors (the best
+                    // case).
+                    if left == right_start {
+                        // the number remaining in this run.
+                        let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
+                        ptr::copy_nonoverlapping_memory(out, &*right, elems);
+                        break;
+                    } else if right == right_end {
+                        let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
+                        ptr::copy_nonoverlapping_memory(out, &*left, elems);
+                        break;
+                    }
+
+                    // check which side is smaller, and that's the
+                    // next element for the new run.
+
+                    // `left < right_start` and `right < right_end`,
+                    // so these are valid.
+                    let to_copy = if compare(&*left, &*right) == Greater {
+                        step(&mut right)
+                    } else {
+                        step(&mut left)
+                    };
+                    ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
+                    step(&mut out);
+                }
+            }
+        }
+
+        mem::swap(&mut buf_dat, &mut buf_tmp);
+
+        width *= 2;
+    }
+
+    // write the result to `v` in one go, so that there are never two copies
+    // of the same object in `v`.
+    unsafe {
+        ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
+    }
+
+    // increment the pointer, returning the old pointer.
+    #[inline(always)]
+    unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
+        let old = *ptr;
+        *ptr = ptr.offset(1);
+        old
+    }
+}
+
+/// Extension methods for vectors such that their elements are
+/// mutable.
+pub trait MutableVectorAllocating<'a, T> {
+    /// Sort the vector, in place, using `compare` to compare
+    /// elements.
+    ///
+    /// This sort is `O(n log n)` worst-case and stable, but allocates
+    /// approximately `2 * n`, where `n` is the length of `self`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [5i, 4, 1, 3, 2];
+    /// v.sort_by(|a, b| a.cmp(b));
+    /// assert!(v == [1, 2, 3, 4, 5]);
+    ///
+    /// // reverse sorting
+    /// v.sort_by(|a, b| b.cmp(a));
+    /// assert!(v == [5, 4, 3, 2, 1]);
+    /// ```
+    fn sort_by(self, compare: |&T, &T| -> Ordering);
+
+    /**
+     * Consumes `src` and moves as many elements as it can into `self`
+     * from the range [start,end).
+     *
+     * Returns the number of elements copied (the shorter of self.len()
+     * and end - start).
+     *
+     * # Arguments
+     *
+     * * src - A mutable vector of `T`
+     * * start - The index into `src` to start copying from
+     * * end - The index into `str` to stop copying from
+     */
+    fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
+}
+
+impl<'a,T> MutableVectorAllocating<'a, T> for &'a mut [T] {
+    #[inline]
+    fn sort_by(self, compare: |&T, &T| -> Ordering) {
+        merge_sort(self, compare)
+    }
+
+    #[inline]
+    fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
+        for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
+            mem::swap(a, b);
+        }
+        cmp::min(self.len(), end-start)
+    }
+}
+
+/// Methods for mutable vectors with orderable elements, such as
+/// in-place sorting.
+pub trait MutableOrdVector<T> {
+    /// Sort the vector, in place.
+    ///
+    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = [-5, 4, 1, -3, 2];
+    ///
+    /// v.sort();
+    /// assert!(v == [-5, -3, 1, 2, 4]);
+    /// ```
+    fn sort(self);
+
+    /// Mutates the slice to the next lexicographic permutation.
+    ///
+    /// Returns `true` if successful, `false` if the slice is at the last-ordered permutation.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v = &mut [0, 1, 2];
+    /// v.next_permutation();
+    /// assert_eq!(v, &mut [0, 2, 1]);
+    /// v.next_permutation();
+    /// assert_eq!(v, &mut [1, 0, 2]);
+    /// ```
+    fn next_permutation(self) -> bool;
+
+    /// Mutates the slice to the previous lexicographic permutation.
+    ///
+    /// Returns `true` if successful, `false` if the slice is at the first-ordered permutation.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v = &mut [1, 0, 2];
+    /// v.prev_permutation();
+    /// assert_eq!(v, &mut [0, 2, 1]);
+    /// v.prev_permutation();
+    /// assert_eq!(v, &mut [0, 1, 2]);
+    /// ```
+    fn prev_permutation(self) -> bool;
+}
+
+impl<'a, T: Ord> MutableOrdVector<T> for &'a mut [T] {
+    #[inline]
+    fn sort(self) {
+        self.sort_by(|a,b| a.cmp(b))
+    }
+
+    fn next_permutation(self) -> bool {
+        // These cases only have 1 permutation each, so we can't do anything.
+        if self.len() < 2 { return false; }
+
+        // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
+        let mut i = self.len() - 1;
+        while i > 0 && self[i-1] >= self[i] {
+            i -= 1;
+        }
+
+        // If that is the entire vector, this is the last-ordered permutation.
+        if i == 0 {
+            return false;
+        }
+
+        // Step 2: Find the rightmost element larger than the pivot (i-1)
+        let mut j = self.len() - 1;
+        while j >= i && self[j] <= self[i-1]  {
+            j -= 1;
+        }
+
+        // Step 3: Swap that element with the pivot
+        self.swap(j, i-1);
+
+        // Step 4: Reverse the (previously) weakly decreasing part
+        self.mut_slice_from(i).reverse();
+
+        true
+    }
+
+    fn prev_permutation(self) -> bool {
+        // These cases only have 1 permutation each, so we can't do anything.
+        if self.len() < 2 { return false; }
+
+        // Step 1: Identify the longest, rightmost weakly increasing part of the vector
+        let mut i = self.len() - 1;
+        while i > 0 && self[i-1] <= self[i] {
+            i -= 1;
+        }
+
+        // If that is the entire vector, this is the first-ordered permutation.
+        if i == 0 {
+            return false;
+        }
+
+        // Step 2: Reverse the weakly increasing part
+        self.mut_slice_from(i).reverse();
+
+        // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
+        let mut j = self.len() - 1;
+        while j >= i && self[j-1] < self[i-1]  {
+            j -= 1;
+        }
+
+        // Step 4: Swap that element with the pivot
+        self.swap(i-1, j);
+
+        true
+    }
+}
+
+/// Unsafe operations
+pub mod raw {
+    pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
+    pub use core::slice::raw::{shift_ptr, pop_ptr};
+}
+
+/// An iterator that moves out of a vector.
+pub struct MoveItems<T> {
+    allocation: *mut u8, // the block of memory allocated for the vector
+    iter: Items<'static, T>
+}
+
+impl<T> Iterator<T> for MoveItems<T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        unsafe {
+            self.iter.next().map(|x| ptr::read(x))
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<T> DoubleEndedIterator<T> for MoveItems<T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        unsafe {
+            self.iter.next_back().map(|x| ptr::read(x))
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for MoveItems<T> {
+    fn drop(&mut self) {
+        // destroy the remaining elements
+        for _x in *self {}
+        unsafe {
+            // FIXME: #13994 (should pass align and size here)
+            deallocate(self.allocation, 0, 8)
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+    use cmp::*;
+    use mem;
+    use owned::Box;
+    use rand::{Rng, task_rng};
+    use slice::*;
+
+    fn square(n: uint) -> uint { n * n }
+
+    fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
+
+    #[test]
+    fn test_from_fn() {
+        // Test on-stack from_fn.
+        let mut v = Vec::from_fn(3u, square);
+        {
+            let v = v.as_slice();
+            assert_eq!(v.len(), 3u);
+            assert_eq!(v[0], 0u);
+            assert_eq!(v[1], 1u);
+            assert_eq!(v[2], 4u);
+        }
+
+        // Test on-heap from_fn.
+        v = Vec::from_fn(5u, square);
+        {
+            let v = v.as_slice();
+            assert_eq!(v.len(), 5u);
+            assert_eq!(v[0], 0u);
+            assert_eq!(v[1], 1u);
+            assert_eq!(v[2], 4u);
+            assert_eq!(v[3], 9u);
+            assert_eq!(v[4], 16u);
+        }
+    }
+
+    #[test]
+    fn test_from_elem() {
+        // Test on-stack from_elem.
+        let mut v = Vec::from_elem(2u, 10u);
+        {
+            let v = v.as_slice();
+            assert_eq!(v.len(), 2u);
+            assert_eq!(v[0], 10u);
+            assert_eq!(v[1], 10u);
+        }
+
+        // Test on-heap from_elem.
+        v = Vec::from_elem(6u, 20u);
+        {
+            let v = v.as_slice();
+            assert_eq!(v[0], 20u);
+            assert_eq!(v[1], 20u);
+            assert_eq!(v[2], 20u);
+            assert_eq!(v[3], 20u);
+            assert_eq!(v[4], 20u);
+            assert_eq!(v[5], 20u);
+        }
+    }
+
+    #[test]
+    fn test_is_empty() {
+        let xs: [int, ..0] = [];
+        assert!(xs.is_empty());
+        assert!(![0].is_empty());
+    }
+
+    #[test]
+    fn test_len_divzero() {
+        type Z = [i8, ..0];
+        let v0 : &[Z] = &[];
+        let v1 : &[Z] = &[[]];
+        let v2 : &[Z] = &[[], []];
+        assert_eq!(mem::size_of::<Z>(), 0);
+        assert_eq!(v0.len(), 0);
+        assert_eq!(v1.len(), 1);
+        assert_eq!(v2.len(), 2);
+    }
+
+    #[test]
+    fn test_get() {
+        let mut a = box [11];
+        assert_eq!(a.get(1), None);
+        a = box [11, 12];
+        assert_eq!(a.get(1).unwrap(), &12);
+        a = box [11, 12, 13];
+        assert_eq!(a.get(1).unwrap(), &12);
+    }
+
+    #[test]
+    fn test_head() {
+        let mut a = box [];
+        assert_eq!(a.head(), None);
+        a = box [11];
+        assert_eq!(a.head().unwrap(), &11);
+        a = box [11, 12];
+        assert_eq!(a.head().unwrap(), &11);
+    }
+
+    #[test]
+    fn test_tail() {
+        let mut a = box [11];
+        assert_eq!(a.tail(), &[]);
+        a = box [11, 12];
+        assert_eq!(a.tail(), &[12]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_tail_empty() {
+        let a: ~[int] = box [];
+        a.tail();
+    }
+
+    #[test]
+    fn test_tailn() {
+        let mut a = box [11, 12, 13];
+        assert_eq!(a.tailn(0), &[11, 12, 13]);
+        a = box [11, 12, 13];
+        assert_eq!(a.tailn(2), &[13]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_tailn_empty() {
+        let a: ~[int] = box [];
+        a.tailn(2);
+    }
+
+    #[test]
+    fn test_init() {
+        let mut a = box [11];
+        assert_eq!(a.init(), &[]);
+        a = box [11, 12];
+        assert_eq!(a.init(), &[11]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_init_empty() {
+        let a: ~[int] = box [];
+        a.init();
+    }
+
+    #[test]
+    fn test_initn() {
+        let mut a = box [11, 12, 13];
+        assert_eq!(a.initn(0), &[11, 12, 13]);
+        a = box [11, 12, 13];
+        assert_eq!(a.initn(2), &[11]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_initn_empty() {
+        let a: ~[int] = box [];
+        a.initn(2);
+    }
+
+    #[test]
+    fn test_last() {
+        let mut a = box [];
+        assert_eq!(a.last(), None);
+        a = box [11];
+        assert_eq!(a.last().unwrap(), &11);
+        a = box [11, 12];
+        assert_eq!(a.last().unwrap(), &12);
+    }
+
+    #[test]
+    fn test_slice() {
+        // Test fixed length vector.
+        let vec_fixed = [1, 2, 3, 4];
+        let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
+        assert_eq!(v_a.len(), 3u);
+        assert_eq!(v_a[0], 2);
+        assert_eq!(v_a[1], 3);
+        assert_eq!(v_a[2], 4);
+
+        // Test on stack.
+        let vec_stack = &[1, 2, 3];
+        let v_b = vec_stack.slice(1u, 3u).to_owned();
+        assert_eq!(v_b.len(), 2u);
+        assert_eq!(v_b[0], 2);
+        assert_eq!(v_b[1], 3);
+
+        // Test `Box<[T]>`
+        let vec_unique = box [1, 2, 3, 4, 5, 6];
+        let v_d = vec_unique.slice(1u, 6u).to_owned();
+        assert_eq!(v_d.len(), 5u);
+        assert_eq!(v_d[0], 2);
+        assert_eq!(v_d[1], 3);
+        assert_eq!(v_d[2], 4);
+        assert_eq!(v_d[3], 5);
+        assert_eq!(v_d[4], 6);
+    }
+
+    #[test]
+    fn test_slice_from() {
+        let vec = &[1, 2, 3, 4];
+        assert_eq!(vec.slice_from(0), vec);
+        assert_eq!(vec.slice_from(2), &[3, 4]);
+        assert_eq!(vec.slice_from(4), &[]);
+    }
+
+    #[test]
+    fn test_slice_to() {
+        let vec = &[1, 2, 3, 4];
+        assert_eq!(vec.slice_to(4), vec);
+        assert_eq!(vec.slice_to(2), &[1, 2]);
+        assert_eq!(vec.slice_to(0), &[]);
+    }
+
+
+    #[test]
+    fn test_pop() {
+        let mut v = vec![5];
+        let e = v.pop();
+        assert_eq!(v.len(), 0);
+        assert_eq!(e, Some(5));
+        let f = v.pop();
+        assert_eq!(f, None);
+        let g = v.pop();
+        assert_eq!(g, None);
+    }
+
+    #[test]
+    fn test_swap_remove() {
+        let mut v = vec![1, 2, 3, 4, 5];
+        let mut e = v.swap_remove(0);
+        assert_eq!(e, Some(1));
+        assert_eq!(v, vec![5, 2, 3, 4]);
+        e = v.swap_remove(3);
+        assert_eq!(e, Some(4));
+        assert_eq!(v, vec![5, 2, 3]);
+
+        e = v.swap_remove(3);
+        assert_eq!(e, None);
+        assert_eq!(v, vec![5, 2, 3]);
+    }
+
+    #[test]
+    fn test_swap_remove_noncopyable() {
+        // Tests that we don't accidentally run destructors twice.
+        let mut v = vec![::unstable::sync::Exclusive::new(()),
+                         ::unstable::sync::Exclusive::new(()),
+                         ::unstable::sync::Exclusive::new(())];
+        let mut _e = v.swap_remove(0);
+        assert_eq!(v.len(), 2);
+        _e = v.swap_remove(1);
+        assert_eq!(v.len(), 1);
+        _e = v.swap_remove(0);
+        assert_eq!(v.len(), 0);
+    }
+
+    #[test]
+    fn test_push() {
+        // Test on-stack push().
+        let mut v = vec![];
+        v.push(1);
+        assert_eq!(v.len(), 1u);
+        assert_eq!(v.as_slice()[0], 1);
+
+        // Test on-heap push().
+        v.push(2);
+        assert_eq!(v.len(), 2u);
+        assert_eq!(v.as_slice()[0], 1);
+        assert_eq!(v.as_slice()[1], 2);
+    }
+
+    #[test]
+    fn test_grow() {
+        // Test on-stack grow().
+        let mut v = vec![];
+        v.grow(2u, &1);
+        {
+            let v = v.as_slice();
+            assert_eq!(v.len(), 2u);
+            assert_eq!(v[0], 1);
+            assert_eq!(v[1], 1);
+        }
+
+        // Test on-heap grow().
+        v.grow(3u, &2);
+        {
+            let v = v.as_slice();
+            assert_eq!(v.len(), 5u);
+            assert_eq!(v[0], 1);
+            assert_eq!(v[1], 1);
+            assert_eq!(v[2], 2);
+            assert_eq!(v[3], 2);
+            assert_eq!(v[4], 2);
+        }
+    }
+
+    #[test]
+    fn test_grow_fn() {
+        let mut v = vec![];
+        v.grow_fn(3u, square);
+        let v = v.as_slice();
+        assert_eq!(v.len(), 3u);
+        assert_eq!(v[0], 0u);
+        assert_eq!(v[1], 1u);
+        assert_eq!(v[2], 4u);
+    }
+
+    #[test]
+    fn test_grow_set() {
+        let mut v = vec![1, 2, 3];
+        v.grow_set(4u, &4, 5);
+        let v = v.as_slice();
+        assert_eq!(v.len(), 5u);
+        assert_eq!(v[0], 1);
+        assert_eq!(v[1], 2);
+        assert_eq!(v[2], 3);
+        assert_eq!(v[3], 4);
+        assert_eq!(v[4], 5);
+    }
+
+    #[test]
+    fn test_truncate() {
+        let mut v = vec![box 6,box 5,box 4];
+        v.truncate(1);
+        let v = v.as_slice();
+        assert_eq!(v.len(), 1);
+        assert_eq!(*(v[0]), 6);
+        // If the unsafe block didn't drop things properly, we blow up here.
+    }
+
+    #[test]
+    fn test_clear() {
+        let mut v = vec![box 6,box 5,box 4];
+        v.clear();
+        assert_eq!(v.len(), 0);
+        // If the unsafe block didn't drop things properly, we blow up here.
+    }
+
+    #[test]
+    fn test_dedup() {
+        fn case(a: Vec<uint>, b: Vec<uint>) {
+            let mut v = a;
+            v.dedup();
+            assert_eq!(v, b);
+        }
+        case(vec![], vec![]);
+        case(vec![1], vec![1]);
+        case(vec![1,1], vec![1]);
+        case(vec![1,2,3], vec![1,2,3]);
+        case(vec![1,1,2,3], vec![1,2,3]);
+        case(vec![1,2,2,3], vec![1,2,3]);
+        case(vec![1,2,3,3], vec![1,2,3]);
+        case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
+    }
+
+    #[test]
+    fn test_dedup_unique() {
+        let mut v0 = vec![box 1, box 1, box 2, box 3];
+        v0.dedup();
+        let mut v1 = vec![box 1, box 2, box 2, box 3];
+        v1.dedup();
+        let mut v2 = vec![box 1, box 2, box 3, box 3];
+        v2.dedup();
+        /*
+         * If the boxed pointers were leaked or otherwise misused, valgrind
+         * and/or rustrt should raise errors.
+         */
+    }
+
+    #[test]
+    fn test_dedup_shared() {
+        let mut v0 = vec![box 1, box 1, box 2, box 3];
+        v0.dedup();
+        let mut v1 = vec![box 1, box 2, box 2, box 3];
+        v1.dedup();
+        let mut v2 = vec![box 1, box 2, box 3, box 3];
+        v2.dedup();
+        /*
+         * If the pointers were leaked or otherwise misused, valgrind and/or
+         * rustrt should raise errors.
+         */
+    }
+
+    #[test]
+    fn test_retain() {
+        let mut v = vec![1, 2, 3, 4, 5];
+        v.retain(is_odd);
+        assert_eq!(v, vec![1, 3, 5]);
+    }
+
+    #[test]
+    fn test_element_swaps() {
+        let mut v = [1, 2, 3];
+        for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
+            v.swap(a, b);
+            match i {
+                0 => assert!(v == [1, 3, 2]),
+                1 => assert!(v == [3, 1, 2]),
+                2 => assert!(v == [3, 2, 1]),
+                3 => assert!(v == [2, 3, 1]),
+                4 => assert!(v == [2, 1, 3]),
+                5 => assert!(v == [1, 2, 3]),
+                _ => fail!(),
+            }
+        }
+    }
+
+    #[test]
+    fn test_permutations() {
+        {
+            let v: [int, ..0] = [];
+            let mut it = v.permutations();
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 1);
+            assert_eq!(max_opt.unwrap(), 1);
+            assert_eq!(it.next(), Some(v.as_slice().to_owned()));
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = ["Hello".to_string()];
+            let mut it = v.permutations();
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 1);
+            assert_eq!(max_opt.unwrap(), 1);
+            assert_eq!(it.next(), Some(v.as_slice().to_owned()));
+            assert_eq!(it.next(), None);
+        }
+        {
+            let v = [1, 2, 3];
+            let mut it = v.permutations();
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 3*2);
+            assert_eq!(max_opt.unwrap(), 3*2);
+            assert_eq!(it.next(), Some(box [1,2,3]));
+            assert_eq!(it.next(), Some(box [1,3,2]));
+            assert_eq!(it.next(), Some(box [3,1,2]));
+            let (min_size, max_opt) = it.size_hint();
+            assert_eq!(min_size, 3);
+            assert_eq!(max_opt.unwrap(), 3);
+            assert_eq!(it.next(), Some(box [3,2,1]));
+            assert_eq!(it.next(), Some(box [2,3,1]));
+            assert_eq!(it.next(), Some(box [2,1,3]));
+            assert_eq!(it.next(), None);
+        }
+        {
+            // check that we have N! permutations
+            let v = ['A', 'B', 'C', 'D', 'E', 'F'];
+            let mut amt = 0;
+            let mut it = v.permutations();
+            let (min_size, max_opt) = it.size_hint();
+            for _perm in it {
+                amt += 1;
+            }
+            assert_eq!(amt, it.swaps.swaps_made);
+            assert_eq!(amt, min_size);
+            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
+            assert_eq!(amt, max_opt.unwrap());
+        }
+    }
+
+    #[test]
+    fn test_lexicographic_permutations() {
+        let v : &mut[int] = &mut[1, 2, 3, 4, 5];
+        assert!(v.prev_permutation() == false);
+        assert!(v.next_permutation());
+        assert_eq!(v, &mut[1, 2, 3, 5, 4]);
+        assert!(v.prev_permutation());
+        assert_eq!(v, &mut[1, 2, 3, 4, 5]);
+        assert!(v.next_permutation());
+        assert!(v.next_permutation());
+        assert_eq!(v, &mut[1, 2, 4, 3, 5]);
+        assert!(v.next_permutation());
+        assert_eq!(v, &mut[1, 2, 4, 5, 3]);
+
+        let v : &mut[int] = &mut[1, 0, 0, 0];
+        assert!(v.next_permutation() == false);
+        assert!(v.prev_permutation());
+        assert_eq!(v, &mut[0, 1, 0, 0]);
+        assert!(v.prev_permutation());
+        assert_eq!(v, &mut[0, 0, 1, 0]);
+        assert!(v.prev_permutation());
+        assert_eq!(v, &mut[0, 0, 0, 1]);
+        assert!(v.prev_permutation() == false);
+    }
+
+    #[test]
+    fn test_lexicographic_permutations_empty_and_short() {
+        let empty : &mut[int] = &mut[];
+        assert!(empty.next_permutation() == false);
+        assert_eq!(empty, &mut[]);
+        assert!(empty.prev_permutation() == false);
+        assert_eq!(empty, &mut[]);
+
+        let one_elem : &mut[int] = &mut[4];
+        assert!(one_elem.prev_permutation() == false);
+        assert_eq!(one_elem, &mut[4]);
+        assert!(one_elem.next_permutation() == false);
+        assert_eq!(one_elem, &mut[4]);
+
+        let two_elem : &mut[int] = &mut[1, 2];
+        assert!(two_elem.prev_permutation() == false);
+        assert_eq!(two_elem, &mut[1, 2]);
+        assert!(two_elem.next_permutation());
+        assert_eq!(two_elem, &mut[2, 1]);
+        assert!(two_elem.next_permutation() == false);
+        assert_eq!(two_elem, &mut[2, 1]);
+        assert!(two_elem.prev_permutation());
+        assert_eq!(two_elem, &mut[1, 2]);
+        assert!(two_elem.prev_permutation() == false);
+        assert_eq!(two_elem, &mut[1, 2]);
+    }
+
+    #[test]
+    fn test_position_elem() {
+        assert!([].position_elem(&1).is_none());
+
+        let v1 = box [1, 2, 3, 3, 2, 5];
+        assert_eq!(v1.position_elem(&1), Some(0u));
+        assert_eq!(v1.position_elem(&2), Some(1u));
+        assert_eq!(v1.position_elem(&5), Some(5u));
+        assert!(v1.position_elem(&4).is_none());
+    }
+
+    #[test]
+    fn test_bsearch_elem() {
+        assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1));
+        assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0));
+
+        assert_eq!([2,4,6,8,10].bsearch_elem(&1), None);
+        assert_eq!([2,4,6,8,10].bsearch_elem(&5), None);
+        assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1));
+        assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4));
+
+        assert_eq!([2,4,6,8].bsearch_elem(&1), None);
+        assert_eq!([2,4,6,8].bsearch_elem(&5), None);
+        assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1));
+        assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3));
+
+        assert_eq!([2,4,6].bsearch_elem(&1), None);
+        assert_eq!([2,4,6].bsearch_elem(&5), None);
+        assert_eq!([2,4,6].bsearch_elem(&4), Some(1));
+        assert_eq!([2,4,6].bsearch_elem(&6), Some(2));
+
+        assert_eq!([2,4].bsearch_elem(&1), None);
+        assert_eq!([2,4].bsearch_elem(&5), None);
+        assert_eq!([2,4].bsearch_elem(&2), Some(0));
+        assert_eq!([2,4].bsearch_elem(&4), Some(1));
+
+        assert_eq!([2].bsearch_elem(&1), None);
+        assert_eq!([2].bsearch_elem(&5), None);
+        assert_eq!([2].bsearch_elem(&2), Some(0));
+
+        assert_eq!([].bsearch_elem(&1), None);
+        assert_eq!([].bsearch_elem(&5), None);
+
+        assert!([1,1,1,1,1].bsearch_elem(&1) != None);
+        assert!([1,1,1,1,2].bsearch_elem(&1) != None);
+        assert!([1,1,1,2,2].bsearch_elem(&1) != None);
+        assert!([1,1,2,2,2].bsearch_elem(&1) != None);
+        assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0));
+
+        assert_eq!([1,2,3,4,5].bsearch_elem(&6), None);
+        assert_eq!([1,2,3,4,5].bsearch_elem(&0), None);
+    }
+
+    #[test]
+    fn test_reverse() {
+        let mut v: ~[int] = box [10, 20];
+        assert_eq!(v[0], 10);
+        assert_eq!(v[1], 20);
+        v.reverse();
+        assert_eq!(v[0], 20);
+        assert_eq!(v[1], 10);
+
+        let mut v3: ~[int] = box [];
+        v3.reverse();
+        assert!(v3.is_empty());
+    }
+
+    #[test]
+    fn test_sort() {
+        use realstd::slice::Vector;
+        use realstd::clone::Clone;
+        for len in range(4u, 25) {
+            for _ in range(0, 100) {
+                let mut v = task_rng().gen_iter::<uint>().take(len)
+                                      .collect::<Vec<uint>>();
+                let mut v1 = v.clone();
+
+                v.as_mut_slice().sort();
+                assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
+
+                v1.as_mut_slice().sort_by(|a, b| a.cmp(b));
+                assert!(v1.as_slice().windows(2).all(|w| w[0] <= w[1]));
+
+                v1.as_mut_slice().sort_by(|a, b| b.cmp(a));
+                assert!(v1.as_slice().windows(2).all(|w| w[0] >= w[1]));
+            }
+        }
+
+        // shouldn't fail/crash
+        let mut v: [uint, .. 0] = [];
+        v.sort();
+
+        let mut v = [0xDEADBEEFu];
+        v.sort();
+        assert!(v == [0xDEADBEEF]);
+    }
+
+    #[test]
+    fn test_sort_stability() {
+        for len in range(4, 25) {
+            for _ in range(0 , 10) {
+                let mut counts = [0, .. 10];
+
+                // create a vector like [(6, 1), (5, 1), (6, 2), ...],
+                // where the first item of each tuple is random, but
+                // the second item represents which occurrence of that
+                // number this element is, i.e. the second elements
+                // will occur in sorted order.
+                let mut v = range(0, len).map(|_| {
+                        let n = task_rng().gen::<uint>() % 10;
+                        counts[n] += 1;
+                        (n, counts[n])
+                    }).collect::<Vec<(uint, int)>>();
+
+                // only sort on the first element, so an unstable sort
+                // may mix up the counts.
+                v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
+
+                // this comparison includes the count (the second item
+                // of the tuple), so elements with equal first items
+                // will need to be ordered with increasing
+                // counts... i.e. exactly asserting that this sort is
+                // stable.
+                assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
+            }
+        }
+    }
+
+    #[test]
+    fn test_partition() {
+        assert_eq!((box []).partition(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_partitioned() {
+        assert_eq!(([]).partitioned(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_concat() {
+        let v: [~[int], ..0] = [];
+        assert_eq!(v.concat_vec(), vec![]);
+        assert_eq!([box [1], box [2,3]].concat_vec(), vec![1, 2, 3]);
+
+        assert_eq!([&[1], &[2,3]].concat_vec(), vec![1, 2, 3]);
+    }
+
+    #[test]
+    fn test_connect() {
+        let v: [~[int], ..0] = [];
+        assert_eq!(v.connect_vec(&0), vec![]);
+        assert_eq!([box [1], box [2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
+        assert_eq!([box [1], box [2], box [3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
+
+        assert_eq!([&[1], &[2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
+        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
+    }
+
+    #[test]
+    fn test_shift() {
+        let mut x = vec![1, 2, 3];
+        assert_eq!(x.shift(), Some(1));
+        assert_eq!(&x, &vec![2, 3]);
+        assert_eq!(x.shift(), Some(2));
+        assert_eq!(x.shift(), Some(3));
+        assert_eq!(x.shift(), None);
+        assert_eq!(x.len(), 0);
+    }
+
+    #[test]
+    fn test_unshift() {
+        let mut x = vec![1, 2, 3];
+        x.unshift(0);
+        assert_eq!(x, vec![0, 1, 2, 3]);
+    }
+
+    #[test]
+    fn test_insert() {
+        let mut a = vec![1, 2, 4];
+        a.insert(2, 3);
+        assert_eq!(a, vec![1, 2, 3, 4]);
+
+        let mut a = vec![1, 2, 3];
+        a.insert(0, 0);
+        assert_eq!(a, vec![0, 1, 2, 3]);
+
+        let mut a = vec![1, 2, 3];
+        a.insert(3, 4);
+        assert_eq!(a, vec![1, 2, 3, 4]);
+
+        let mut a = vec![];
+        a.insert(0, 1);
+        assert_eq!(a, vec![1]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_insert_oob() {
+        let mut a = vec![1, 2, 3];
+        a.insert(4, 5);
+    }
+
+    #[test]
+    fn test_remove() {
+        let mut a = vec![1,2,3,4];
+
+        assert_eq!(a.remove(2), Some(3));
+        assert_eq!(a, vec![1,2,4]);
+
+        assert_eq!(a.remove(2), Some(4));
+        assert_eq!(a, vec![1,2]);
+
+        assert_eq!(a.remove(2), None);
+        assert_eq!(a, vec![1,2]);
+
+        assert_eq!(a.remove(0), Some(1));
+        assert_eq!(a, vec![2]);
+
+        assert_eq!(a.remove(0), Some(2));
+        assert_eq!(a, vec![]);
+
+        assert_eq!(a.remove(0), None);
+        assert_eq!(a.remove(10), None);
+    }
+
+    #[test]
+    fn test_capacity() {
+        let mut v = vec![0u64];
+        v.reserve_exact(10u);
+        assert_eq!(v.capacity(), 10u);
+        let mut v = vec![0u32];
+        v.reserve_exact(10u);
+        assert_eq!(v.capacity(), 10u);
+    }
+
+    #[test]
+    fn test_slice_2() {
+        let v = vec![1, 2, 3, 4, 5];
+        let v = v.slice(1u, 3u);
+        assert_eq!(v.len(), 2u);
+        assert_eq!(v[0], 2);
+        assert_eq!(v[1], 3);
+    }
+
+
+    #[test]
+    #[should_fail]
+    fn test_from_fn_fail() {
+        Vec::from_fn(100, |v| {
+            if v == 50 { fail!() }
+            box 0
+        });
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_from_elem_fail() {
+        use cell::Cell;
+        use rc::Rc;
+
+        struct S {
+            f: Cell<int>,
+            boxes: (Box<int>, Rc<int>)
+        }
+
+        impl Clone for S {
+            fn clone(&self) -> S {
+                self.f.set(self.f.get() + 1);
+                if self.f.get() == 10 { fail!() }
+                S { f: self.f, boxes: self.boxes.clone() }
+            }
+        }
+
+        let s = S { f: Cell::new(0), boxes: (box 0, Rc::new(0)) };
+        let _ = Vec::from_elem(100, s);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_grow_fn_fail() {
+        use rc::Rc;
+        let mut v = vec![];
+        v.grow_fn(100, |i| {
+            if i == 50 {
+                fail!()
+            }
+            (box 0, Rc::new(0))
+        })
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_permute_fail() {
+        use rc::Rc;
+        let v = [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
+                 (box 0, Rc::new(0)), (box 0, Rc::new(0))];
+        let mut i = 0;
+        for _ in v.permutations() {
+            if i == 2 {
+                fail!()
+            }
+            i += 1;
+        }
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_copy_memory_oob() {
+        unsafe {
+            let mut a = [1, 2, 3, 4];
+            let b = [1, 2, 3, 4, 5];
+            a.copy_memory(b);
+        }
+    }
+
+    #[test]
+    fn test_total_ord() {
+        [1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
+        [1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
+        [1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
+        [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
+        [2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
+    }
+
+    #[test]
+    fn test_iterator() {
+        use iter::*;
+        let xs = [1, 2, 5, 10, 11];
+        let mut it = xs.iter();
+        assert_eq!(it.size_hint(), (5, Some(5)));
+        assert_eq!(it.next().unwrap(), &1);
+        assert_eq!(it.size_hint(), (4, Some(4)));
+        assert_eq!(it.next().unwrap(), &2);
+        assert_eq!(it.size_hint(), (3, Some(3)));
+        assert_eq!(it.next().unwrap(), &5);
+        assert_eq!(it.size_hint(), (2, Some(2)));
+        assert_eq!(it.next().unwrap(), &10);
+        assert_eq!(it.size_hint(), (1, Some(1)));
+        assert_eq!(it.next().unwrap(), &11);
+        assert_eq!(it.size_hint(), (0, Some(0)));
+        assert!(it.next().is_none());
+    }
+
+    #[test]
+    fn test_random_access_iterator() {
+        use iter::*;
+        let xs = [1, 2, 5, 10, 11];
+        let mut it = xs.iter();
+
+        assert_eq!(it.indexable(), 5);
+        assert_eq!(it.idx(0).unwrap(), &1);
+        assert_eq!(it.idx(2).unwrap(), &5);
+        assert_eq!(it.idx(4).unwrap(), &11);
+        assert!(it.idx(5).is_none());
+
+        assert_eq!(it.next().unwrap(), &1);
+        assert_eq!(it.indexable(), 4);
+        assert_eq!(it.idx(0).unwrap(), &2);
+        assert_eq!(it.idx(3).unwrap(), &11);
+        assert!(it.idx(4).is_none());
+
+        assert_eq!(it.next().unwrap(), &2);
+        assert_eq!(it.indexable(), 3);
+        assert_eq!(it.idx(1).unwrap(), &10);
+        assert!(it.idx(3).is_none());
+
+        assert_eq!(it.next().unwrap(), &5);
+        assert_eq!(it.indexable(), 2);
+        assert_eq!(it.idx(1).unwrap(), &11);
+
+        assert_eq!(it.next().unwrap(), &10);
+        assert_eq!(it.indexable(), 1);
+        assert_eq!(it.idx(0).unwrap(), &11);
+        assert!(it.idx(1).is_none());
+
+        assert_eq!(it.next().unwrap(), &11);
+        assert_eq!(it.indexable(), 0);
+        assert!(it.idx(0).is_none());
+
+        assert!(it.next().is_none());
+    }
+
+    #[test]
+    fn test_iter_size_hints() {
+        use iter::*;
+        let mut xs = [1, 2, 5, 10, 11];
+        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
+        assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
+    }
+
+    #[test]
+    fn test_iter_clone() {
+        let xs = [1, 2, 5];
+        let mut it = xs.iter();
+        it.next();
+        let mut jt = it.clone();
+        assert_eq!(it.next(), jt.next());
+        assert_eq!(it.next(), jt.next());
+        assert_eq!(it.next(), jt.next());
+    }
+
+    #[test]
+    fn test_mut_iterator() {
+        use iter::*;
+        let mut xs = [1, 2, 3, 4, 5];
+        for x in xs.mut_iter() {
+            *x += 1;
+        }
+        assert!(xs == [2, 3, 4, 5, 6])
+    }
+
+    #[test]
+    fn test_rev_iterator() {
+        use iter::*;
+
+        let xs = [1, 2, 5, 10, 11];
+        let ys = [11, 10, 5, 2, 1];
+        let mut i = 0;
+        for &x in xs.iter().rev() {
+            assert_eq!(x, ys[i]);
+            i += 1;
+        }
+        assert_eq!(i, 5);
+    }
+
+    #[test]
+    fn test_mut_rev_iterator() {
+        use iter::*;
+        let mut xs = [1u, 2, 3, 4, 5];
+        for (i,x) in xs.mut_iter().rev().enumerate() {
+            *x += i;
+        }
+        assert!(xs == [5, 5, 5, 5, 5])
+    }
+
+    #[test]
+    fn test_move_iterator() {
+        use iter::*;
+        let xs = box [1u,2,3,4,5];
+        assert_eq!(xs.move_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
+    }
+
+    #[test]
+    fn test_move_rev_iterator() {
+        use iter::*;
+        let xs = box [1u,2,3,4,5];
+        assert_eq!(xs.move_iter().rev().fold(0, |a: uint, b: uint| 10*a + b), 54321);
+    }
+
+    #[test]
+    fn test_splitator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1], &[3], &[5]]);
+        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[2,3,4,5]]);
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4], &[]]);
+        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[], &[], &[]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
+    }
+
+    #[test]
+    fn test_splitnator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1], &[3,4,5]]);
+        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[4,5]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
+    }
+
+    #[test]
+    fn test_rsplitator() {
+        let xs = &[1i,2,3,4,5];
+
+        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[5], &[3], &[1]]);
+        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[2,3,4,5], &[]]);
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[1,2,3,4]]);
+        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(), &[&[]]);
+    }
+
+    #[test]
+    fn test_rsplitnator() {
+        let xs = &[1,2,3,4,5];
+
+        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[1,2,3,4,5]]);
+        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[5], &[1,2,3]]);
+        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
+                   &[&[], &[], &[], &[1,2]]);
+
+        let xs: &[int] = &[];
+        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
+    }
+
+    #[test]
+    fn test_windowsator() {
+        let v = &[1i,2,3,4];
+
+        assert_eq!(v.windows(2).collect::<Vec<&[int]>>().as_slice(), &[&[1,2], &[2,3], &[3,4]]);
+        assert_eq!(v.windows(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[2,3,4]]);
+        assert!(v.windows(6).next().is_none());
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_windowsator_0() {
+        let v = &[1i,2,3,4];
+        let _it = v.windows(0);
+    }
+
+    #[test]
+    fn test_chunksator() {
+        let v = &[1i,2,3,4,5];
+
+        assert_eq!(v.chunks(2).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2], &[3,4], &[5]]);
+        assert_eq!(v.chunks(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[4,5]]);
+        assert_eq!(v.chunks(6).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3,4,5]]);
+
+        assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>().as_slice(), &[&[5i], &[3,4], &[1,2]]);
+        let mut it = v.chunks(2);
+        assert_eq!(it.indexable(), 3);
+        assert_eq!(it.idx(0).unwrap(), &[1,2]);
+        assert_eq!(it.idx(1).unwrap(), &[3,4]);
+        assert_eq!(it.idx(2).unwrap(), &[5]);
+        assert_eq!(it.idx(3), None);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_chunksator_0() {
+        let v = &[1i,2,3,4];
+        let _it = v.chunks(0);
+    }
+
+    #[test]
+    fn test_move_from() {
+        let mut a = [1,2,3,4,5];
+        let b = box [6,7,8];
+        assert_eq!(a.move_from(b, 0, 3), 3);
+        assert!(a == [6,7,8,4,5]);
+        let mut a = [7,2,8,1];
+        let b = box [3,1,4,1,5,9];
+        assert_eq!(a.move_from(b, 0, 6), 4);
+        assert!(a == [3,1,4,1]);
+        let mut a = [1,2,3,4];
+        let b = box [5,6,7,8,9,0];
+        assert_eq!(a.move_from(b, 2, 3), 1);
+        assert!(a == [7,2,3,4]);
+        let mut a = [1,2,3,4,5];
+        let b = box [5,6,7,8,9,0];
+        assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
+        assert!(a == [1,2,6,7,5]);
+    }
+
+    #[test]
+    fn test_copy_from() {
+        let mut a = [1,2,3,4,5];
+        let b = [6,7,8];
+        assert_eq!(a.copy_from(b), 3);
+        assert!(a == [6,7,8,4,5]);
+        let mut c = [7,2,8,1];
+        let d = [3,1,4,1,5,9];
+        assert_eq!(c.copy_from(d), 4);
+        assert!(c == [3,1,4,1]);
+    }
+
+    #[test]
+    fn test_reverse_part() {
+        let mut values = [1,2,3,4,5];
+        values.mut_slice(1, 4).reverse();
+        assert!(values == [1,4,3,2,5]);
+    }
+
+    #[test]
+    fn test_show() {
+        macro_rules! test_show_vec(
+            ($x:expr, $x_str:expr) => ({
+                let (x, x_str) = ($x, $x_str);
+                assert_eq!(format!("{}", x), x_str);
+                assert_eq!(format!("{}", x.as_slice()), x_str);
+            })
+        )
+        let empty: ~[int] = box [];
+        test_show_vec!(empty, "[]".to_string());
+        test_show_vec!(box [1], "[1]".to_string());
+        test_show_vec!(box [1, 2, 3], "[1, 2, 3]".to_string());
+        test_show_vec!(box [box [], box [1u], box [1u, 1u]],
+                       "[[], [1], [1, 1]]".to_string());
+
+        let empty_mut: &mut [int] = &mut[];
+        test_show_vec!(empty_mut, "[]".to_string());
+        test_show_vec!(&mut[1], "[1]".to_string());
+        test_show_vec!(&mut[1, 2, 3], "[1, 2, 3]".to_string());
+        test_show_vec!(&mut[&mut[], &mut[1u], &mut[1u, 1u]],
+                       "[[], [1], [1, 1]]".to_string());
+    }
+
+    #[test]
+    fn test_vec_default() {
+        use default::Default;
+        macro_rules! t (
+            ($ty:ty) => {{
+                let v: $ty = Default::default();
+                assert!(v.is_empty());
+            }}
+        );
+
+        t!(&[int]);
+        t!(~[int]);
+        t!(Vec<int>);
+    }
+
+    #[test]
+    fn test_bytes_set_memory() {
+        use slice::bytes::MutableByteVector;
+        let mut values = [1u8,2,3,4,5];
+        values.mut_slice(0,5).set_memory(0xAB);
+        assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
+        values.mut_slice(2,4).set_memory(0xFF);
+        assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_overflow_does_not_cause_segfault() {
+        let mut v = vec![];
+        v.reserve_exact(-1);
+        v.push(1);
+        v.push(2);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_overflow_does_not_cause_segfault_managed() {
+        use rc::Rc;
+        let mut v = vec![Rc::new(1)];
+        v.reserve_exact(-1);
+        v.push(Rc::new(2));
+    }
+
+    #[test]
+    fn test_mut_split_at() {
+        let mut values = [1u8,2,3,4,5];
+        {
+            let (left, right) = values.mut_split_at(2);
+            assert!(left.slice(0, left.len()) == [1, 2]);
+            for p in left.mut_iter() {
+                *p += 1;
+            }
+
+            assert!(right.slice(0, right.len()) == [3, 4, 5]);
+            for p in right.mut_iter() {
+                *p += 2;
+            }
+        }
+
+        assert!(values == [2, 3, 5, 6, 7]);
+    }
+
+    #[deriving(Clone, PartialEq)]
+    struct Foo;
+
+    #[test]
+    fn test_iter_zero_sized() {
+        let mut v = vec![Foo, Foo, Foo];
+        assert_eq!(v.len(), 3);
+        let mut cnt = 0;
+
+        for f in v.iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 3);
+
+        for f in v.slice(1, 3).iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 5);
+
+        for f in v.mut_iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 8);
+
+        for f in v.move_iter() {
+            assert!(f == Foo);
+            cnt += 1;
+        }
+        assert_eq!(cnt, 11);
+
+        let xs: [Foo, ..3] = [Foo, Foo, Foo];
+        cnt = 0;
+        for f in xs.iter() {
+            assert!(*f == Foo);
+            cnt += 1;
+        }
+        assert!(cnt == 3);
+    }
+
+    #[test]
+    fn test_shrink_to_fit() {
+        let mut xs = vec![0, 1, 2, 3];
+        for i in range(4, 100) {
+            xs.push(i)
+        }
+        assert_eq!(xs.capacity(), 128);
+        xs.shrink_to_fit();
+        assert_eq!(xs.capacity(), 100);
+        assert_eq!(xs, range(0, 100).collect::<Vec<_>>());
+    }
+
+    #[test]
+    fn test_starts_with() {
+        assert!(bytes!("foobar").starts_with(bytes!("foo")));
+        assert!(!bytes!("foobar").starts_with(bytes!("oob")));
+        assert!(!bytes!("foobar").starts_with(bytes!("bar")));
+        assert!(!bytes!("foo").starts_with(bytes!("foobar")));
+        assert!(!bytes!("bar").starts_with(bytes!("foobar")));
+        assert!(bytes!("foobar").starts_with(bytes!("foobar")));
+        let empty: &[u8] = [];
+        assert!(empty.starts_with(empty));
+        assert!(!empty.starts_with(bytes!("foo")));
+        assert!(bytes!("foobar").starts_with(empty));
+    }
+
+    #[test]
+    fn test_ends_with() {
+        assert!(bytes!("foobar").ends_with(bytes!("bar")));
+        assert!(!bytes!("foobar").ends_with(bytes!("oba")));
+        assert!(!bytes!("foobar").ends_with(bytes!("foo")));
+        assert!(!bytes!("foo").ends_with(bytes!("foobar")));
+        assert!(!bytes!("bar").ends_with(bytes!("foobar")));
+        assert!(bytes!("foobar").ends_with(bytes!("foobar")));
+        let empty: &[u8] = [];
+        assert!(empty.ends_with(empty));
+        assert!(!empty.ends_with(bytes!("foo")));
+        assert!(bytes!("foobar").ends_with(empty));
+    }
+
+    #[test]
+    fn test_shift_ref() {
+        let mut x: &[int] = [1, 2, 3, 4, 5];
+        let h = x.shift_ref();
+        assert_eq!(*h.unwrap(), 1);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 2);
+        assert_eq!(x[3], 5);
+
+        let mut y: &[int] = [];
+        assert_eq!(y.shift_ref(), None);
+    }
+
+    #[test]
+    fn test_pop_ref() {
+        let mut x: &[int] = [1, 2, 3, 4, 5];
+        let h = x.pop_ref();
+        assert_eq!(*h.unwrap(), 5);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 1);
+        assert_eq!(x[3], 4);
+
+        let mut y: &[int] = [];
+        assert!(y.pop_ref().is_none());
+    }
+
+    #[test]
+    fn test_mut_splitator() {
+        let mut xs = [0,1,0,2,3,0,0,4,5,0];
+        assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
+        for slice in xs.mut_split(|x| *x == 0) {
+            slice.reverse();
+        }
+        assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
+
+        let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
+        for slice in xs.mut_split(|x| *x == 0).take(5) {
+            slice.reverse();
+        }
+        assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
+    }
+
+    #[test]
+    fn test_mut_splitator_rev() {
+        let mut xs = [1,2,0,3,4,0,0,5,6,0];
+        for slice in xs.mut_split(|x| *x == 0).rev().take(4) {
+            slice.reverse();
+        }
+        assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
+    }
+
+    #[test]
+    fn test_mut_chunks() {
+        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
+        for (i, chunk) in v.mut_chunks(3).enumerate() {
+            for x in chunk.mut_iter() {
+                *x = i as u8;
+            }
+        }
+        let result = [0u8, 0, 0, 1, 1, 1, 2];
+        assert!(v == result);
+    }
+
+    #[test]
+    fn test_mut_chunks_rev() {
+        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
+        for (i, chunk) in v.mut_chunks(3).rev().enumerate() {
+            for x in chunk.mut_iter() {
+                *x = i as u8;
+            }
+        }
+        let result = [2u8, 2, 2, 1, 1, 1, 0];
+        assert!(v == result);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_mut_chunks_0() {
+        let mut v = [1, 2, 3, 4];
+        let _it = v.mut_chunks(0);
+    }
+
+    #[test]
+    fn test_mut_shift_ref() {
+        let mut x: &mut [int] = [1, 2, 3, 4, 5];
+        let h = x.mut_shift_ref();
+        assert_eq!(*h.unwrap(), 1);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 2);
+        assert_eq!(x[3], 5);
+
+        let mut y: &mut [int] = [];
+        assert!(y.mut_shift_ref().is_none());
+    }
+
+    #[test]
+    fn test_mut_pop_ref() {
+        let mut x: &mut [int] = [1, 2, 3, 4, 5];
+        let h = x.mut_pop_ref();
+        assert_eq!(*h.unwrap(), 5);
+        assert_eq!(x.len(), 4);
+        assert_eq!(x[0], 1);
+        assert_eq!(x[3], 4);
+
+        let mut y: &mut [int] = [];
+        assert!(y.mut_pop_ref().is_none());
+    }
+
+    #[test]
+    fn test_mut_last() {
+        let mut x = [1, 2, 3, 4, 5];
+        let h = x.mut_last();
+        assert_eq!(*h.unwrap(), 5);
+
+        let y: &mut [int] = [];
+        assert!(y.mut_last().is_none());
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::Bencher;
+    use mem;
+    use prelude::*;
+    use ptr;
+    use rand::{weak_rng, Rng};
+
+    #[bench]
+    fn iterator(b: &mut Bencher) {
+        // peculiar numbers to stop LLVM from optimising the summation
+        // out.
+        let v = Vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
+
+        b.iter(|| {
+            let mut sum = 0;
+            for x in v.iter() {
+                sum += *x;
+            }
+            // sum == 11806, to stop dead code elimination.
+            if sum == 0 {fail!()}
+        })
+    }
+
+    #[bench]
+    fn mut_iterator(b: &mut Bencher) {
+        let mut v = Vec::from_elem(100, 0);
+
+        b.iter(|| {
+            let mut i = 0;
+            for x in v.mut_iter() {
+                *x = i;
+                i += 1;
+            }
+        })
+    }
+
+    #[bench]
+    fn concat(b: &mut Bencher) {
+        let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
+        b.iter(|| {
+            xss.as_slice().concat_vec()
+        });
+    }
+
+    #[bench]
+    fn connect(b: &mut Bencher) {
+        let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
+        b.iter(|| {
+            xss.as_slice().connect_vec(&0)
+        });
+    }
+
+    #[bench]
+    fn push(b: &mut Bencher) {
+        let mut vec: Vec<uint> = vec![];
+        b.iter(|| {
+            vec.push(0);
+            &vec
+        })
+    }
+
+    #[bench]
+    fn starts_with_same_vector(b: &mut Bencher) {
+        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
+        b.iter(|| {
+            vec.as_slice().starts_with(vec.as_slice())
+        })
+    }
+
+    #[bench]
+    fn starts_with_single_element(b: &mut Bencher) {
+        let vec: Vec<uint> = vec![0];
+        b.iter(|| {
+            vec.as_slice().starts_with(vec.as_slice())
+        })
+    }
+
+    #[bench]
+    fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
+        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
+        let mut match_vec: Vec<uint> = Vec::from_fn(99, |i| i);
+        match_vec.push(0);
+        b.iter(|| {
+            vec.as_slice().starts_with(match_vec.as_slice())
+        })
+    }
+
+    #[bench]
+    fn ends_with_same_vector(b: &mut Bencher) {
+        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
+        b.iter(|| {
+            vec.as_slice().ends_with(vec.as_slice())
+        })
+    }
+
+    #[bench]
+    fn ends_with_single_element(b: &mut Bencher) {
+        let vec: Vec<uint> = vec![0];
+        b.iter(|| {
+            vec.as_slice().ends_with(vec.as_slice())
+        })
+    }
+
+    #[bench]
+    fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
+        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
+        let mut match_vec: Vec<uint> = Vec::from_fn(100, |i| i);
+        match_vec.as_mut_slice()[0] = 200;
+        b.iter(|| {
+            vec.as_slice().starts_with(match_vec.as_slice())
+        })
+    }
+
+    #[bench]
+    fn contains_last_element(b: &mut Bencher) {
+        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
+        b.iter(|| {
+            vec.contains(&99u)
+        })
+    }
+
+    #[bench]
+    fn zero_1kb_from_elem(b: &mut Bencher) {
+        b.iter(|| {
+            Vec::from_elem(1024, 0u8)
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_set_memory(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v: Vec<uint> = Vec::with_capacity(1024);
+            unsafe {
+                let vp = v.as_mut_ptr();
+                ptr::set_memory(vp, 0, 1024);
+                v.set_len(1024);
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_fixed_repeat(b: &mut Bencher) {
+        b.iter(|| {
+            box [0u8, ..1024]
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_loop_set(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v: Vec<uint> = Vec::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for i in range(0u, 1024) {
+                *v.get_mut(i) = 0;
+            }
+        });
+    }
+
+    #[bench]
+    fn zero_1kb_mut_iter(b: &mut Bencher) {
+        b.iter(|| {
+            let mut v = Vec::with_capacity(1024);
+            unsafe {
+                v.set_len(1024);
+            }
+            for x in v.mut_iter() {
+                *x = 0;
+            }
+            v
+        });
+    }
+
+    #[bench]
+    fn random_inserts(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+                let mut v = Vec::from_elem(30, (0u, 0u));
+                for _ in range(0, 100) {
+                    let l = v.len();
+                    v.insert(rng.gen::<uint>() % (l + 1),
+                             (1, 1));
+                }
+            })
+    }
+    #[bench]
+    fn random_removes(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+                let mut v = Vec::from_elem(130, (0u, 0u));
+                for _ in range(0, 100) {
+                    let l = v.len();
+                    v.remove(rng.gen::<uint>() % l);
+                }
+            })
+    }
+
+    #[bench]
+    fn sort_random_small(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<u64>().take(5).collect::<Vec<u64>>();
+            v.as_mut_slice().sort();
+        });
+        b.bytes = 5 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_medium(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<u64>().take(100).collect::<Vec<u64>>();
+            v.as_mut_slice().sort();
+        });
+        b.bytes = 100 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_random_large(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<u64>().take(10000).collect::<Vec<u64>>();
+            v.as_mut_slice().sort();
+        });
+        b.bytes = 10000 * mem::size_of::<u64>() as u64;
+    }
+
+    #[bench]
+    fn sort_sorted(b: &mut Bencher) {
+        let mut v = Vec::from_fn(10000, |i| i);
+        b.iter(|| {
+            v.sort();
+        });
+        b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
+    }
+
+    type BigSortable = (u64,u64,u64,u64);
+
+    #[bench]
+    fn sort_big_random_small(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(5)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_medium(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(100)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_random_large(b: &mut Bencher) {
+        let mut rng = weak_rng();
+        b.iter(|| {
+            let mut v = rng.gen_iter::<BigSortable>().take(10000)
+                           .collect::<Vec<BigSortable>>();
+            v.sort();
+        });
+        b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
+    }
+
+    #[bench]
+    fn sort_big_sorted(b: &mut Bencher) {
+        let mut v = Vec::from_fn(10000u, |i| (i, i, i, i));
+        b.iter(|| {
+            v.sort();
+        });
+        b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
+    }
+}
index 932011baa56f153c73447dfa40de939c83b64d32..c284a73d8bca64f374a7689f82a77d36f8cd8766 100644 (file)
 
 #![allow(missing_doc)]
 
-use std::iter::{Enumerate, FilterMap};
-use std::mem::replace;
-use std::{vec, slice};
+use core::prelude::*;
+
+use core::iter::{Enumerate, FilterMap};
+use core::mem::replace;
+
+use {vec, slice};
+use vec::Vec;
 
 #[allow(missing_doc)]
 pub struct SmallIntMap<T> {
@@ -118,7 +122,7 @@ pub fn with_capacity(capacity: uint) -> SmallIntMap<V> {
     }
 
     pub fn get<'a>(&'a self, key: &uint) -> &'a V {
-        self.find(key).expect("key not present")
+        ::expect(self.find(key), "key not present")
     }
 
     /// An iterator visiting all key-value pairs in ascending order by the keys.
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
new file mode 100644 (file)
index 0000000..144f14a
--- /dev/null
@@ -0,0 +1,2441 @@
+// Copyright 2012-2014 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.
+
+/*!
+
+Unicode string manipulation (`str` type)
+
+# Basic Usage
+
+Rust's string type is one of the core primitive types of the language. While
+represented by the name `str`, the name `str` is not actually a valid type in
+Rust. Each string must also be decorated with a pointer. `String` is used
+for an owned string, so there is only one commonly-used `str` type in Rust:
+`&str`.
+
+`&str` is the borrowed string type. This type of string can only be created
+from other strings, unless it is a static string (see below). As the word
+"borrowed" implies, this type of string is owned elsewhere, and this string
+cannot be moved out of.
+
+As an example, here's some code that uses a string.
+
+```rust
+fn main() {
+    let borrowed_string = "This string is borrowed with the 'static lifetime";
+}
+```
+
+From the example above, you can see that Rust's string literals have the
+`'static` lifetime. This is akin to C's concept of a static string.
+
+String literals are allocated statically in the rodata of the
+executable/library. The string then has the type `&'static str` meaning that
+the string is valid for the `'static` lifetime, otherwise known as the
+lifetime of the entire program. As can be inferred from the type, these static
+strings are not mutable.
+
+# Mutability
+
+Many languages have immutable strings by default, and Rust has a particular
+flavor on this idea. As with the rest of Rust types, strings are immutable by
+default. If a string is declared as `mut`, however, it may be mutated. This
+works the same way as the rest of Rust's type system in the sense that if
+there's a mutable reference to a string, there may only be one mutable reference
+to that string. With these guarantees, strings can easily transition between
+being mutable/immutable with the same benefits of having mutable strings in
+other languages.
+
+# Representation
+
+Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
+stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
+encoded UTF-8 sequences. Additionally, strings are not null-terminated
+and can contain null codepoints.
+
+The actual representation of strings have direct mappings to vectors: `&str`
+is the same as `&[u8]`.
+
+*/
+
+#![doc(primitive = "str")]
+
+use core::prelude::*;
+
+use core::char;
+use core::default::Default;
+use core::fmt;
+use core::cmp;
+use core::iter::AdditiveIterator;
+use core::mem;
+
+use hash;
+use slice::CloneableVector;
+use string::String;
+use vec::Vec;
+
+pub use core::str::{from_utf8, CharEq, Chars, CharOffsets};
+pub use core::str::{Bytes, CharSplits};
+pub use core::str::{CharSplitsN, Words, AnyLines, MatchIndices, StrSplits};
+pub use core::str::{eq_slice, is_utf8, is_utf16, Utf16Items};
+pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
+pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
+pub use core::str::{Str, StrSlice};
+
+/*
+Section: Creating a string
+*/
+
+/// Consumes a vector of bytes to create a new utf-8 string.
+///
+/// Returns `Err` with the original vector if the vector contains invalid
+/// UTF-8.
+pub fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>> {
+    String::from_utf8(vv)
+}
+
+/// Convert a byte to a UTF-8 string
+///
+/// # Failure
+///
+/// Fails if invalid UTF-8
+pub fn from_byte(b: u8) -> String {
+    assert!(b < 128u8);
+    String::from_char(1, b as char)
+}
+
+/// Convert a char to a string
+pub fn from_char(ch: char) -> String {
+    let mut buf = String::new();
+    buf.push_char(ch);
+    buf
+}
+
+/// Convert a vector of chars to a string
+pub fn from_chars(chs: &[char]) -> String {
+    chs.iter().map(|c| *c).collect()
+}
+
+/// Methods for vectors of strings
+pub trait StrVector {
+    /// Concatenate a vector of strings.
+    fn concat(&self) -> String;
+
+    /// Concatenate a vector of strings, placing a given separator between each.
+    fn connect(&self, sep: &str) -> String;
+}
+
+impl<'a, S: Str> StrVector for &'a [S] {
+    fn concat(&self) -> String {
+        if self.is_empty() {
+            return String::new();
+        }
+
+        // `len` calculation may overflow but push_str but will check boundaries
+        let len = self.iter().map(|s| s.as_slice().len()).sum();
+
+        let mut result = String::with_capacity(len);
+
+        for s in self.iter() {
+            result.push_str(s.as_slice())
+        }
+
+        result
+    }
+
+    fn connect(&self, sep: &str) -> String {
+        if self.is_empty() {
+            return String::new();
+        }
+
+        // concat is faster
+        if sep.is_empty() {
+            return self.concat();
+        }
+
+        // this is wrong without the guarantee that `self` is non-empty
+        // `len` calculation may overflow but push_str but will check boundaries
+        let len = sep.len() * (self.len() - 1)
+            + self.iter().map(|s| s.as_slice().len()).sum();
+        let mut result = String::with_capacity(len);
+        let mut first = true;
+
+        for s in self.iter() {
+            if first {
+                first = false;
+            } else {
+                result.push_str(sep);
+            }
+            result.push_str(s.as_slice());
+        }
+        result
+    }
+}
+
+impl<'a, S: Str> StrVector for Vec<S> {
+    #[inline]
+    fn concat(&self) -> String {
+        self.as_slice().concat()
+    }
+
+    #[inline]
+    fn connect(&self, sep: &str) -> String {
+        self.as_slice().connect(sep)
+    }
+}
+
+/*
+Section: Iterators
+*/
+
+// Helper functions used for Unicode normalization
+fn canonical_sort(comb: &mut [(char, u8)]) {
+    let len = comb.len();
+    for i in range(0, len) {
+        let mut swapped = false;
+        for j in range(1, len-i) {
+            let class_a = *comb[j-1].ref1();
+            let class_b = *comb[j].ref1();
+            if class_a != 0 && class_b != 0 && class_a > class_b {
+                comb.swap(j-1, j);
+                swapped = true;
+            }
+        }
+        if !swapped { break; }
+    }
+}
+
+#[deriving(Clone)]
+enum DecompositionType {
+    Canonical,
+    Compatible
+}
+
+/// External iterator for a string's decomposition's characters.
+/// Use with the `std::iter` module.
+#[deriving(Clone)]
+pub struct Decompositions<'a> {
+    kind: DecompositionType,
+    iter: Chars<'a>,
+    buffer: Vec<(char, u8)>,
+    sorted: bool
+}
+
+impl<'a> Iterator<char> for Decompositions<'a> {
+    #[inline]
+    fn next(&mut self) -> Option<char> {
+        use unicode::normalization::canonical_combining_class;
+
+        match self.buffer.as_slice().head() {
+            Some(&(c, 0)) => {
+                self.sorted = false;
+                self.buffer.shift();
+                return Some(c);
+            }
+            Some(&(c, _)) if self.sorted => {
+                self.buffer.shift();
+                return Some(c);
+            }
+            _ => self.sorted = false
+        }
+
+        let decomposer = match self.kind {
+            Canonical => char::decompose_canonical,
+            Compatible => char::decompose_compatible
+        };
+
+        if !self.sorted {
+            for ch in self.iter {
+                let buffer = &mut self.buffer;
+                let sorted = &mut self.sorted;
+                decomposer(ch, |d| {
+                    let class = canonical_combining_class(d);
+                    if class == 0 && !*sorted {
+                        canonical_sort(buffer.as_mut_slice());
+                        *sorted = true;
+                    }
+                    buffer.push((d, class));
+                });
+                if *sorted { break }
+            }
+        }
+
+        if !self.sorted {
+            canonical_sort(self.buffer.as_mut_slice());
+            self.sorted = true;
+        }
+
+        match self.buffer.shift() {
+            Some((c, 0)) => {
+                self.sorted = false;
+                Some(c)
+            }
+            Some((c, _)) => Some(c),
+            None => None
+        }
+    }
+
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        let (lower, _) = self.iter.size_hint();
+        (lower, None)
+    }
+}
+
+/// Replace all occurrences of one string with another
+///
+/// # Arguments
+///
+/// * s - The string containing substrings to replace
+/// * from - The string to replace
+/// * to - The replacement string
+///
+/// # Return value
+///
+/// The original string with all occurrences of `from` replaced with `to`
+pub fn replace(s: &str, from: &str, to: &str) -> String {
+    let mut result = String::new();
+    let mut last_end = 0;
+    for (start, end) in s.match_indices(from) {
+        result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
+        result.push_str(to);
+        last_end = end;
+    }
+    result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
+    result
+}
+
+/*
+Section: Misc
+*/
+
+/// Decode a UTF-16 encoded vector `v` into a string, returning `None`
+/// if `v` contains any invalid data.
+///
+/// # Example
+///
+/// ```rust
+/// use std::str;
+///
+/// // 𝄞music
+/// let mut v = [0xD834, 0xDD1E, 0x006d, 0x0075,
+///              0x0073, 0x0069, 0x0063];
+/// assert_eq!(str::from_utf16(v), Some("𝄞music".to_string()));
+///
+/// // 𝄞mu<invalid>ic
+/// v[4] = 0xD800;
+/// assert_eq!(str::from_utf16(v), None);
+/// ```
+pub fn from_utf16(v: &[u16]) -> Option<String> {
+    let mut s = String::with_capacity(v.len() / 2);
+    for c in utf16_items(v) {
+        match c {
+            ScalarValue(c) => s.push_char(c),
+            LoneSurrogate(_) => return None
+        }
+    }
+    Some(s)
+}
+
+/// Decode a UTF-16 encoded vector `v` into a string, replacing
+/// invalid data with the replacement character (U+FFFD).
+///
+/// # Example
+/// ```rust
+/// use std::str;
+///
+/// // 𝄞mus<invalid>ic<invalid>
+/// let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
+///          0x0073, 0xDD1E, 0x0069, 0x0063,
+///          0xD834];
+///
+/// assert_eq!(str::from_utf16_lossy(v),
+///            "𝄞mus\uFFFDic\uFFFD".to_string());
+/// ```
+pub fn from_utf16_lossy(v: &[u16]) -> String {
+    utf16_items(v).map(|c| c.to_char_lossy()).collect()
+}
+
+// Return the initial codepoint accumulator for the first byte.
+// The first byte is special, only want bottom 5 bits for width 2, 4 bits
+// for width 3, and 3 bits for width 4
+macro_rules! utf8_first_byte(
+    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
+)
+
+// return the value of $ch updated with continuation byte $byte
+macro_rules! utf8_acc_cont_byte(
+    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
+)
+
+static TAG_CONT_U8: u8 = 128u8;
+
+/// Converts a vector of bytes to a new utf-8 string.
+/// Any invalid utf-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
+///
+/// # Example
+///
+/// ```rust
+/// let input = bytes!("Hello ", 0xF0, 0x90, 0x80, "World");
+/// let output = std::str::from_utf8_lossy(input);
+/// assert_eq!(output.as_slice(), "Hello \uFFFDWorld");
+/// ```
+pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> {
+    if is_utf8(v) {
+        return Slice(unsafe { mem::transmute(v) })
+    }
+
+    static REPLACEMENT: &'static [u8] = bytes!(0xEF, 0xBF, 0xBD); // U+FFFD in UTF-8
+    let mut i = 0;
+    let total = v.len();
+    fn unsafe_get(xs: &[u8], i: uint) -> u8 {
+        unsafe { *xs.unsafe_ref(i) }
+    }
+    fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
+        if i >= total {
+            0
+        } else {
+            unsafe_get(xs, i)
+        }
+    }
+
+    let mut res = String::with_capacity(total);
+
+    if i > 0 {
+        unsafe {
+            res.push_bytes(v.slice_to(i))
+        };
+    }
+
+    // subseqidx is the index of the first byte of the subsequence we're looking at.
+    // It's used to copy a bunch of contiguous good codepoints at once instead of copying
+    // them one by one.
+    let mut subseqidx = 0;
+
+    while i < total {
+        let i_ = i;
+        let byte = unsafe_get(v, i);
+        i += 1;
+
+        macro_rules! error(() => ({
+            unsafe {
+                if subseqidx != i_ {
+                    res.push_bytes(v.slice(subseqidx, i_));
+                }
+                subseqidx = i;
+                res.push_bytes(REPLACEMENT);
+            }
+        }))
+
+        if byte < 128u8 {
+            // subseqidx handles this
+        } else {
+            let w = utf8_char_width(byte);
+
+            match w {
+                2 => {
+                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        error!();
+                        continue;
+                    }
+                    i += 1;
+                }
+                3 => {
+                    match (byte, safe_get(v, i, total)) {
+                        (0xE0        , 0xA0 .. 0xBF) => (),
+                        (0xE1 .. 0xEC, 0x80 .. 0xBF) => (),
+                        (0xED        , 0x80 .. 0x9F) => (),
+                        (0xEE .. 0xEF, 0x80 .. 0xBF) => (),
+                        _ => {
+                            error!();
+                            continue;
+                        }
+                    }
+                    i += 1;
+                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        error!();
+                        continue;
+                    }
+                    i += 1;
+                }
+                4 => {
+                    match (byte, safe_get(v, i, total)) {
+                        (0xF0        , 0x90 .. 0xBF) => (),
+                        (0xF1 .. 0xF3, 0x80 .. 0xBF) => (),
+                        (0xF4        , 0x80 .. 0x8F) => (),
+                        _ => {
+                            error!();
+                            continue;
+                        }
+                    }
+                    i += 1;
+                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        error!();
+                        continue;
+                    }
+                    i += 1;
+                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
+                        error!();
+                        continue;
+                    }
+                    i += 1;
+                }
+                _ => {
+                    error!();
+                    continue;
+                }
+            }
+        }
+    }
+    if subseqidx < total {
+        unsafe {
+            res.push_bytes(v.slice(subseqidx, total))
+        };
+    }
+    Owned(res.into_string())
+}
+
+/*
+Section: MaybeOwned
+*/
+
+/// A `MaybeOwned` is a string that can hold either a `String` or a `&str`.
+/// This can be useful as an optimization when an allocation is sometimes
+/// needed but not always.
+pub enum MaybeOwned<'a> {
+    /// A borrowed string
+    Slice(&'a str),
+    /// An owned string
+    Owned(String)
+}
+
+/// `SendStr` is a specialization of `MaybeOwned` to be sendable
+pub type SendStr = MaybeOwned<'static>;
+
+impl<'a> MaybeOwned<'a> {
+    /// Returns `true` if this `MaybeOwned` wraps an owned string
+    #[inline]
+    pub fn is_owned(&self) -> bool {
+        match *self {
+            Slice(_) => false,
+            Owned(_) => true
+        }
+    }
+
+    /// Returns `true` if this `MaybeOwned` wraps a borrowed string
+    #[inline]
+    pub fn is_slice(&self) -> bool {
+        match *self {
+            Slice(_) => true,
+            Owned(_) => false
+        }
+    }
+}
+
+/// Trait for moving into a `MaybeOwned`
+pub trait IntoMaybeOwned<'a> {
+    /// Moves self into a `MaybeOwned`
+    fn into_maybe_owned(self) -> MaybeOwned<'a>;
+}
+
+impl<'a> IntoMaybeOwned<'a> for String {
+    #[inline]
+    fn into_maybe_owned(self) -> MaybeOwned<'a> {
+        Owned(self)
+    }
+}
+
+impl<'a> IntoMaybeOwned<'a> for &'a str {
+    #[inline]
+    fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
+}
+
+impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
+    #[inline]
+    fn into_maybe_owned(self) -> MaybeOwned<'a> { self }
+}
+
+impl<'a> PartialEq for MaybeOwned<'a> {
+    #[inline]
+    fn eq(&self, other: &MaybeOwned) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+impl<'a> Eq for MaybeOwned<'a> {}
+
+impl<'a> PartialOrd for MaybeOwned<'a> {
+    #[inline]
+    fn lt(&self, other: &MaybeOwned) -> bool {
+        self.as_slice().lt(&other.as_slice())
+    }
+}
+
+impl<'a> Ord for MaybeOwned<'a> {
+    #[inline]
+    fn cmp(&self, other: &MaybeOwned) -> Ordering {
+        self.as_slice().cmp(&other.as_slice())
+    }
+}
+
+impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
+    #[inline]
+    fn equiv(&self, other: &S) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+impl<'a> Str for MaybeOwned<'a> {
+    #[inline]
+    fn as_slice<'b>(&'b self) -> &'b str {
+        match *self {
+            Slice(s) => s,
+            Owned(ref s) => s.as_slice()
+        }
+    }
+}
+
+impl<'a> StrAllocating for MaybeOwned<'a> {
+    #[inline]
+    fn into_string(self) -> String {
+        match self {
+            Slice(s) => s.to_string(),
+            Owned(s) => s
+        }
+    }
+}
+
+impl<'a> Container for MaybeOwned<'a> {
+    #[inline]
+    fn len(&self) -> uint { self.as_slice().len() }
+}
+
+impl<'a> Clone for MaybeOwned<'a> {
+    #[inline]
+    fn clone(&self) -> MaybeOwned<'a> {
+        match *self {
+            Slice(s) => Slice(s),
+            Owned(ref s) => Owned(s.to_string())
+        }
+    }
+}
+
+impl<'a> Default for MaybeOwned<'a> {
+    #[inline]
+    fn default() -> MaybeOwned<'a> { Slice("") }
+}
+
+impl<'a, H: hash::Writer> hash::Hash<H> for MaybeOwned<'a> {
+    #[inline]
+    fn hash(&self, hasher: &mut H) {
+        self.as_slice().hash(hasher)
+    }
+}
+
+impl<'a> fmt::Show for MaybeOwned<'a> {
+    #[inline]
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Slice(ref s) => s.fmt(f),
+            Owned(ref s) => s.fmt(f)
+        }
+    }
+}
+
+/// Unsafe operations
+pub mod raw {
+    use core::prelude::*;
+    use core::mem;
+    use core::raw::Slice;
+
+    use string::String;
+    use vec::Vec;
+
+    pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
+    pub use core::str::raw::{slice_unchecked};
+
+    /// Create a Rust string from a *u8 buffer of the given length
+    pub unsafe fn from_buf_len(buf: *u8, len: uint) -> String {
+        let mut result = String::new();
+        result.push_bytes(mem::transmute(Slice {
+            data: buf,
+            len: len,
+        }));
+        result
+    }
+
+    /// Create a Rust string from a null-terminated C string
+    pub unsafe fn from_c_str(c_string: *i8) -> String {
+        let mut buf = String::new();
+        let mut len = 0;
+        while *c_string.offset(len) != 0 {
+            len += 1;
+        }
+        buf.push_bytes(mem::transmute(Slice {
+            data: c_string,
+            len: len as uint,
+        }));
+        buf
+    }
+
+    /// Converts an owned vector of bytes to a new owned string. This assumes
+    /// that the utf-8-ness of the vector has already been validated
+    #[inline]
+    pub unsafe fn from_utf8_owned(v: Vec<u8>) -> String {
+        mem::transmute(v)
+    }
+
+    /// Converts a byte to a string.
+    pub unsafe fn from_byte(u: u8) -> String {
+        from_utf8_owned(vec![u])
+    }
+
+    /// Sets the length of a string
+    ///
+    /// This will explicitly set the size of the string, without actually
+    /// modifying its buffers, so it is up to the caller to ensure that
+    /// the string is actually the specified size.
+    #[test]
+    fn test_from_buf_len() {
+        use slice::ImmutableVector;
+        use str::StrAllocating;
+
+        unsafe {
+            let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
+            let b = a.as_ptr();
+            let c = from_buf_len(b, 3u);
+            assert_eq!(c, "AAA".to_string());
+        }
+    }
+}
+
+/*
+Section: Trait implementations
+*/
+
+/// Any string that can be represented as a slice
+pub trait StrAllocating: Str {
+    /// Convert `self` into a `String`, not making a copy if possible.
+    fn into_string(self) -> String;
+
+    /// Convert `self` into a `String`.
+    #[inline]
+    fn to_string(&self) -> String {
+        String::from_str(self.as_slice())
+    }
+
+    #[allow(missing_doc)]
+    #[deprecated = "replaced by .into_string()"]
+    fn into_owned(self) -> String {
+        self.into_string()
+    }
+
+    /// Escape each char in `s` with `char::escape_default`.
+    fn escape_default(&self) -> String {
+        let me = self.as_slice();
+        let mut out = String::with_capacity(me.len());
+        for c in me.chars() {
+            c.escape_default(|c| out.push_char(c));
+        }
+        out
+    }
+
+    /// Escape each char in `s` with `char::escape_unicode`.
+    fn escape_unicode(&self) -> String {
+        let me = self.as_slice();
+        let mut out = String::with_capacity(me.len());
+        for c in me.chars() {
+            c.escape_unicode(|c| out.push_char(c));
+        }
+        out
+    }
+
+    /// Replace all occurrences of one string with another.
+    ///
+    /// # Arguments
+    ///
+    /// * `from` - The string to replace
+    /// * `to` - The replacement string
+    ///
+    /// # Return value
+    ///
+    /// The original string with all occurrences of `from` replaced with `to`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let s = "Do you know the muffin man,
+    /// The muffin man, the muffin man, ...".to_string();
+    ///
+    /// assert_eq!(s.replace("muffin man", "little lamb"),
+    ///            "Do you know the little lamb,
+    /// The little lamb, the little lamb, ...".to_string());
+    ///
+    /// // not found, so no change.
+    /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
+    /// ```
+    fn replace(&self, from: &str, to: &str) -> String {
+        let me = self.as_slice();
+        let mut result = String::new();
+        let mut last_end = 0;
+        for (start, end) in me.match_indices(from) {
+            result.push_str(unsafe{raw::slice_bytes(me, last_end, start)});
+            result.push_str(to);
+            last_end = end;
+        }
+        result.push_str(unsafe{raw::slice_bytes(me, last_end, me.len())});
+        result
+    }
+
+    #[allow(missing_doc)]
+    #[deprecated = "obsolete, use `to_string`"]
+    #[inline]
+    fn to_owned(&self) -> String {
+        unsafe {
+            mem::transmute(Vec::from_slice(self.as_slice().as_bytes()))
+        }
+    }
+
+    /// Converts to a vector of `u16` encoded as UTF-16.
+    fn to_utf16(&self) -> Vec<u16> {
+        let me = self.as_slice();
+        let mut u = Vec::new();
+        for ch in me.chars() {
+            let mut buf = [0u16, ..2];
+            let n = ch.encode_utf16(buf /* as mut slice! */);
+            u.push_all(buf.slice_to(n));
+        }
+        u
+    }
+
+    /// Given a string, make a new string with repeated copies of it.
+    fn repeat(&self, nn: uint) -> String {
+        let me = self.as_slice();
+        let mut ret = String::with_capacity(nn * me.len());
+        for _ in range(0, nn) {
+            ret.push_str(me);
+        }
+        ret
+    }
+
+    /// Levenshtein Distance between two strings.
+    fn lev_distance(&self, t: &str) -> uint {
+        let me = self.as_slice();
+        let slen = me.len();
+        let tlen = t.len();
+
+        if slen == 0 { return tlen; }
+        if tlen == 0 { return slen; }
+
+        let mut dcol = Vec::from_fn(tlen + 1, |x| x);
+
+        for (i, sc) in me.chars().enumerate() {
+
+            let mut current = i;
+            *dcol.get_mut(0) = current + 1;
+
+            for (j, tc) in t.chars().enumerate() {
+
+                let next = *dcol.get(j + 1);
+
+                if sc == tc {
+                    *dcol.get_mut(j + 1) = current;
+                } else {
+                    *dcol.get_mut(j + 1) = cmp::min(current, next);
+                    *dcol.get_mut(j + 1) = cmp::min(*dcol.get(j + 1),
+                                                    *dcol.get(j)) + 1;
+                }
+
+                current = next;
+            }
+        }
+
+        return *dcol.get(tlen);
+    }
+
+    /// An Iterator over the string in Unicode Normalization Form D
+    /// (canonical decomposition).
+    #[inline]
+    fn nfd_chars<'a>(&'a self) -> Decompositions<'a> {
+        Decompositions {
+            iter: self.as_slice().chars(),
+            buffer: Vec::new(),
+            sorted: false,
+            kind: Canonical
+        }
+    }
+
+    /// An Iterator over the string in Unicode Normalization Form KD
+    /// (compatibility decomposition).
+    #[inline]
+    fn nfkd_chars<'a>(&'a self) -> Decompositions<'a> {
+        Decompositions {
+            iter: self.as_slice().chars(),
+            buffer: Vec::new(),
+            sorted: false,
+            kind: Compatible
+        }
+    }
+}
+
+impl<'a> StrAllocating for &'a str {
+    #[inline]
+    fn into_string(self) -> String {
+        self.to_string()
+    }
+}
+
+/// Methods for owned strings
+pub trait OwnedStr {
+    /// Consumes the string, returning the underlying byte buffer.
+    ///
+    /// The buffer does not have a null terminator.
+    fn into_bytes(self) -> Vec<u8>;
+
+    /// Pushes the given string onto this string, returning the concatenation of the two strings.
+    fn append(self, rhs: &str) -> String;
+}
+
+impl OwnedStr for String {
+    #[inline]
+    fn into_bytes(self) -> Vec<u8> {
+        unsafe { mem::transmute(self) }
+    }
+
+    #[inline]
+    fn append(mut self, rhs: &str) -> String {
+        self.push_str(rhs);
+        self
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use iter::AdditiveIterator;
+    use default::Default;
+    use prelude::*;
+    use str::*;
+    use string::String;
+
+    #[test]
+    fn test_eq_slice() {
+        assert!((eq_slice("foobar".slice(0, 3), "foo")));
+        assert!((eq_slice("barfoo".slice(3, 6), "foo")));
+        assert!((!eq_slice("foo1", "foo2")));
+    }
+
+    #[test]
+    fn test_le() {
+        assert!("" <= "");
+        assert!("" <= "foo");
+        assert!("foo" <= "foo");
+        assert!("foo" != "bar");
+    }
+
+    #[test]
+    fn test_len() {
+        assert_eq!("".len(), 0u);
+        assert_eq!("hello world".len(), 11u);
+        assert_eq!("\x63".len(), 1u);
+        assert_eq!("\xa2".len(), 2u);
+        assert_eq!("\u03c0".len(), 2u);
+        assert_eq!("\u2620".len(), 3u);
+        assert_eq!("\U0001d11e".len(), 4u);
+
+        assert_eq!("".char_len(), 0u);
+        assert_eq!("hello world".char_len(), 11u);
+        assert_eq!("\x63".char_len(), 1u);
+        assert_eq!("\xa2".char_len(), 1u);
+        assert_eq!("\u03c0".char_len(), 1u);
+        assert_eq!("\u2620".char_len(), 1u);
+        assert_eq!("\U0001d11e".char_len(), 1u);
+        assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
+    }
+
+    #[test]
+    fn test_find() {
+        assert_eq!("hello".find('l'), Some(2u));
+        assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
+        assert!("hello".find('x').is_none());
+        assert!("hello".find(|c:char| c == 'x').is_none());
+        assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
+        assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
+    }
+
+    #[test]
+    fn test_rfind() {
+        assert_eq!("hello".rfind('l'), Some(3u));
+        assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
+        assert!("hello".rfind('x').is_none());
+        assert!("hello".rfind(|c:char| c == 'x').is_none());
+        assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
+        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
+    }
+
+    #[test]
+    fn test_collect() {
+        let empty = "".to_string();
+        let s: String = empty.as_slice().chars().collect();
+        assert_eq!(empty, s);
+        let data = "ประเทศไทย中".to_string();
+        let s: String = data.as_slice().chars().collect();
+        assert_eq!(data, s);
+    }
+
+    #[test]
+    fn test_into_bytes() {
+        let data = "asdf".to_string();
+        let buf = data.into_bytes();
+        assert_eq!(bytes!("asdf"), buf.as_slice());
+    }
+
+    #[test]
+    fn test_find_str() {
+        // byte positions
+        assert_eq!("".find_str(""), Some(0u));
+        assert!("banana".find_str("apple pie").is_none());
+
+        let data = "abcabc";
+        assert_eq!(data.slice(0u, 6u).find_str("ab"), Some(0u));
+        assert_eq!(data.slice(2u, 6u).find_str("ab"), Some(3u - 2u));
+        assert!(data.slice(2u, 4u).find_str("ab").is_none());
+
+        let string = "ประเทศไทย中华Việt Nam";
+        let mut data = string.to_string();
+        data.push_str(string);
+        assert!(data.as_slice().find_str("ไท华").is_none());
+        assert_eq!(data.as_slice().slice(0u, 43u).find_str(""), Some(0u));
+        assert_eq!(data.as_slice().slice(6u, 43u).find_str(""), Some(6u - 6u));
+
+        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ประ"), Some( 0u));
+        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ทศไ"), Some(12u));
+        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ย中"), Some(24u));
+        assert_eq!(data.as_slice().slice(0u, 43u).find_str("iệt"), Some(34u));
+        assert_eq!(data.as_slice().slice(0u, 43u).find_str("Nam"), Some(40u));
+
+        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
+        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
+        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
+        assert_eq!(data.as_slice().slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
+        assert_eq!(data.as_slice().slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
+    }
+
+    #[test]
+    fn test_slice_chars() {
+        fn t(a: &str, b: &str, start: uint) {
+            assert_eq!(a.slice_chars(start, start + b.char_len()), b);
+        }
+        t("", "", 0);
+        t("hello", "llo", 2);
+        t("hello", "el", 1);
+        t("αβλ", "β", 1);
+        t("αβλ", "", 3);
+        assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
+    }
+
+    #[test]
+    fn test_concat() {
+        fn t(v: &[String], s: &str) {
+            assert_eq!(v.concat(), s.to_str().into_string());
+        }
+        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
+          "no".to_string(), "good".to_string()], "youknowI'mnogood");
+        let v: &[String] = [];
+        t(v, "");
+        t(["hi".to_string()], "hi");
+    }
+
+    #[test]
+    fn test_connect() {
+        fn t(v: &[String], sep: &str, s: &str) {
+            assert_eq!(v.connect(sep), s.to_str().into_string());
+        }
+        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
+           "no".to_string(), "good".to_string()],
+          " ", "you know I'm no good");
+        let v: &[String] = [];
+        t(v, " ", "");
+        t(["hi".to_string()], " ", "hi");
+    }
+
+    #[test]
+    fn test_concat_slices() {
+        fn t(v: &[&str], s: &str) {
+            assert_eq!(v.concat(), s.to_str().into_string());
+        }
+        t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
+        let v: &[&str] = [];
+        t(v, "");
+        t(["hi"], "hi");
+    }
+
+    #[test]
+    fn test_connect_slices() {
+        fn t(v: &[&str], sep: &str, s: &str) {
+            assert_eq!(v.connect(sep), s.to_str().into_string());
+        }
+        t(["you", "know", "I'm", "no", "good"],
+          " ", "you know I'm no good");
+        t([], " ", "");
+        t(["hi"], " ", "hi");
+    }
+
+    #[test]
+    fn test_repeat() {
+        assert_eq!("x".repeat(4), "xxxx".to_string());
+        assert_eq!("hi".repeat(4), "hihihihi".to_string());
+        assert_eq!("ไท华".repeat(3), "ไท华ไท华ไท华".to_string());
+        assert_eq!("".repeat(4), "".to_string());
+        assert_eq!("hi".repeat(0), "".to_string());
+    }
+
+    #[test]
+    fn test_unsafe_slice() {
+        assert_eq!("ab", unsafe {raw::slice_bytes("abc", 0, 2)});
+        assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
+        assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
+        fn a_million_letter_a() -> String {
+            let mut i = 0;
+            let mut rs = String::new();
+            while i < 100000 {
+                rs.push_str("aaaaaaaaaa");
+                i += 1;
+            }
+            rs
+        }
+        fn half_a_million_letter_a() -> String {
+            let mut i = 0;
+            let mut rs = String::new();
+            while i < 100000 {
+                rs.push_str("aaaaa");
+                i += 1;
+            }
+            rs
+        }
+        let letters = a_million_letter_a();
+        assert!(half_a_million_letter_a() ==
+            unsafe {raw::slice_bytes(letters.as_slice(),
+                                     0u,
+                                     500000)}.to_owned());
+    }
+
+    #[test]
+    fn test_starts_with() {
+        assert!(("".starts_with("")));
+        assert!(("abc".starts_with("")));
+        assert!(("abc".starts_with("a")));
+        assert!((!"a".starts_with("abc")));
+        assert!((!"".starts_with("abc")));
+        assert!((!"ödd".starts_with("-")));
+        assert!(("ödd".starts_with("öd")));
+    }
+
+    #[test]
+    fn test_ends_with() {
+        assert!(("".ends_with("")));
+        assert!(("abc".ends_with("")));
+        assert!(("abc".ends_with("c")));
+        assert!((!"a".ends_with("abc")));
+        assert!((!"".ends_with("abc")));
+        assert!((!"ddö".ends_with("-")));
+        assert!(("ddö".ends_with("dö")));
+    }
+
+    #[test]
+    fn test_is_empty() {
+        assert!("".is_empty());
+        assert!(!"a".is_empty());
+    }
+
+    #[test]
+    fn test_replace() {
+        let a = "a";
+        assert_eq!("".replace(a, "b"), "".to_string());
+        assert_eq!("a".replace(a, "b"), "b".to_string());
+        assert_eq!("ab".replace(a, "b"), "bb".to_string());
+        let test = "test";
+        assert!(" test test ".replace(test, "toast") ==
+            " toast toast ".to_string());
+        assert_eq!(" test test ".replace(test, ""), "   ".to_string());
+    }
+
+    #[test]
+    fn test_replace_2a() {
+        let data = "ประเทศไทย中华";
+        let repl = "دولة الكويت";
+
+        let a = "ประเ";
+        let a2 = "دولة الكويتทศไทย中华";
+        assert_eq!(data.replace(a, repl).as_slice(), a2);
+    }
+
+    #[test]
+    fn test_replace_2b() {
+        let data = "ประเทศไทย中华";
+        let repl = "دولة الكويت";
+
+        let b = "ะเ";
+        let b2 = "ปรدولة الكويتทศไทย中华";
+        assert_eq!(data.replace(b, repl).as_slice(), b2);
+    }
+
+    #[test]
+    fn test_replace_2c() {
+        let data = "ประเทศไทย中华";
+        let repl = "دولة الكويت";
+
+        let c = "中华";
+        let c2 = "ประเทศไทยدولة الكويت";
+        assert_eq!(data.replace(c, repl).as_slice(), c2);
+    }
+
+    #[test]
+    fn test_replace_2d() {
+        let data = "ประเทศไทย中华";
+        let repl = "دولة الكويت";
+
+        let d = "ไท华";
+        assert_eq!(data.replace(d, repl).as_slice(), data);
+    }
+
+    #[test]
+    fn test_slice() {
+        assert_eq!("ab", "abc".slice(0, 2));
+        assert_eq!("bc", "abc".slice(1, 3));
+        assert_eq!("", "abc".slice(1, 1));
+        assert_eq!("\u65e5", "\u65e5\u672c".slice(0, 3));
+
+        let data = "ประเทศไทย中华";
+        assert_eq!("ป", data.slice(0, 3));
+        assert_eq!("ร", data.slice(3, 6));
+        assert_eq!("", data.slice(3, 3));
+        assert_eq!("华", data.slice(30, 33));
+
+        fn a_million_letter_X() -> String {
+            let mut i = 0;
+            let mut rs = String::new();
+            while i < 100000 {
+                rs.push_str("华华华华华华华华华华");
+                i += 1;
+            }
+            rs
+        }
+        fn half_a_million_letter_X() -> String {
+            let mut i = 0;
+            let mut rs = String::new();
+            while i < 100000 {
+                rs.push_str("华华华华华");
+                i += 1;
+            }
+            rs
+        }
+        let letters = a_million_letter_X();
+        assert!(half_a_million_letter_X() ==
+            letters.as_slice().slice(0u, 3u * 500000u).to_owned());
+    }
+
+    #[test]
+    fn test_slice_2() {
+        let ss = "中华Việt Nam";
+
+        assert_eq!("华", ss.slice(3u, 6u));
+        assert_eq!("Việt Nam", ss.slice(6u, 16u));
+
+        assert_eq!("ab", "abc".slice(0u, 2u));
+        assert_eq!("bc", "abc".slice(1u, 3u));
+        assert_eq!("", "abc".slice(1u, 1u));
+
+        assert_eq!("中", ss.slice(0u, 3u));
+        assert_eq!("华V", ss.slice(3u, 7u));
+        assert_eq!("", ss.slice(3u, 3u));
+        /*0: 中
+          3: 华
+          6: V
+          7: i
+          8: ệ
+         11: t
+         12:
+         13: N
+         14: a
+         15: m */
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_slice_fail() {
+        "中华Việt Nam".slice(0u, 2u);
+    }
+
+    #[test]
+    fn test_slice_from() {
+        assert_eq!("abcd".slice_from(0), "abcd");
+        assert_eq!("abcd".slice_from(2), "cd");
+        assert_eq!("abcd".slice_from(4), "");
+    }
+    #[test]
+    fn test_slice_to() {
+        assert_eq!("abcd".slice_to(0), "");
+        assert_eq!("abcd".slice_to(2), "ab");
+        assert_eq!("abcd".slice_to(4), "abcd");
+    }
+
+    #[test]
+    fn test_trim_left_chars() {
+        let v: &[char] = &[];
+        assert_eq!(" *** foo *** ".trim_left_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
+        assert_eq!(" ***  *** ".trim_left_chars(&['*', ' ']), "");
+        assert_eq!("foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
+
+        assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
+        assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12");
+        assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123");
+    }
+
+    #[test]
+    fn test_trim_right_chars() {
+        let v: &[char] = &[];
+        assert_eq!(" *** foo *** ".trim_right_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_right_chars(&['*', ' ']), " *** foo");
+        assert_eq!(" ***  *** ".trim_right_chars(&['*', ' ']), "");
+        assert_eq!(" *** foo".trim_right_chars(&['*', ' ']), " *** foo");
+
+        assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
+        assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar");
+        assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar");
+    }
+
+    #[test]
+    fn test_trim_chars() {
+        let v: &[char] = &[];
+        assert_eq!(" *** foo *** ".trim_chars(v), " *** foo *** ");
+        assert_eq!(" *** foo *** ".trim_chars(&['*', ' ']), "foo");
+        assert_eq!(" ***  *** ".trim_chars(&['*', ' ']), "");
+        assert_eq!("foo".trim_chars(&['*', ' ']), "foo");
+
+        assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
+        assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar");
+        assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar");
+    }
+
+    #[test]
+    fn test_trim_left() {
+        assert_eq!("".trim_left(), "");
+        assert_eq!("a".trim_left(), "a");
+        assert_eq!("    ".trim_left(), "");
+        assert_eq!("     blah".trim_left(), "blah");
+        assert_eq!("   \u3000  wut".trim_left(), "wut");
+        assert_eq!("hey ".trim_left(), "hey ");
+    }
+
+    #[test]
+    fn test_trim_right() {
+        assert_eq!("".trim_right(), "");
+        assert_eq!("a".trim_right(), "a");
+        assert_eq!("    ".trim_right(), "");
+        assert_eq!("blah     ".trim_right(), "blah");
+        assert_eq!("wut   \u3000  ".trim_right(), "wut");
+        assert_eq!(" hey".trim_right(), " hey");
+    }
+
+    #[test]
+    fn test_trim() {
+        assert_eq!("".trim(), "");
+        assert_eq!("a".trim(), "a");
+        assert_eq!("    ".trim(), "");
+        assert_eq!("    blah     ".trim(), "blah");
+        assert_eq!("\nwut   \u3000  ".trim(), "wut");
+        assert_eq!(" hey dude ".trim(), "hey dude");
+    }
+
+    #[test]
+    fn test_is_whitespace() {
+        assert!("".is_whitespace());
+        assert!(" ".is_whitespace());
+        assert!("\u2009".is_whitespace()); // Thin space
+        assert!("  \n\t   ".is_whitespace());
+        assert!(!"   _   ".is_whitespace());
+    }
+
+    #[test]
+    fn test_slice_shift_char() {
+        let data = "ประเทศไทย中";
+        assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中"));
+    }
+
+    #[test]
+    fn test_slice_shift_char_2() {
+        let empty = "";
+        assert_eq!(empty.slice_shift_char(), (None, ""));
+    }
+
+    #[test]
+    fn test_is_utf8() {
+        // deny overlong encodings
+        assert!(!is_utf8([0xc0, 0x80]));
+        assert!(!is_utf8([0xc0, 0xae]));
+        assert!(!is_utf8([0xe0, 0x80, 0x80]));
+        assert!(!is_utf8([0xe0, 0x80, 0xaf]));
+        assert!(!is_utf8([0xe0, 0x81, 0x81]));
+        assert!(!is_utf8([0xf0, 0x82, 0x82, 0xac]));
+        assert!(!is_utf8([0xf4, 0x90, 0x80, 0x80]));
+
+        // deny surrogates
+        assert!(!is_utf8([0xED, 0xA0, 0x80]));
+        assert!(!is_utf8([0xED, 0xBF, 0xBF]));
+
+        assert!(is_utf8([0xC2, 0x80]));
+        assert!(is_utf8([0xDF, 0xBF]));
+        assert!(is_utf8([0xE0, 0xA0, 0x80]));
+        assert!(is_utf8([0xED, 0x9F, 0xBF]));
+        assert!(is_utf8([0xEE, 0x80, 0x80]));
+        assert!(is_utf8([0xEF, 0xBF, 0xBF]));
+        assert!(is_utf8([0xF0, 0x90, 0x80, 0x80]));
+        assert!(is_utf8([0xF4, 0x8F, 0xBF, 0xBF]));
+    }
+
+    #[test]
+    fn test_is_utf16() {
+        macro_rules! pos ( ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } });
+
+        // non-surrogates
+        pos!([0x0000],
+             [0x0001, 0x0002],
+             [0xD7FF],
+             [0xE000]);
+
+        // surrogate pairs (randomly generated with Python 3's
+        // .encode('utf-16be'))
+        pos!([0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
+             [0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
+             [0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
+
+        // mixtures (also random)
+        pos!([0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
+             [0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
+             [0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
+
+        // negative tests
+        macro_rules! neg ( ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } });
+
+        neg!(
+            // surrogate + regular unit
+            [0xdb45, 0x0000],
+            // surrogate + lead surrogate
+            [0xd900, 0xd900],
+            // unterminated surrogate
+            [0xd8ff],
+            // trail surrogate without a lead
+            [0xddb7]);
+
+        // random byte sequences that Python 3's .decode('utf-16be')
+        // failed on
+        neg!([0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
+             [0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
+             [0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
+             [0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
+             [0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
+             [0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
+             [0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
+             [0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
+             [0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
+             [0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
+             [0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
+             [0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
+             [0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
+             [0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
+             [0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
+             [0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
+             [0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
+             [0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
+             [0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
+             [0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
+             [0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
+    }
+
+    #[test]
+    fn test_raw_from_c_str() {
+        unsafe {
+            let a = box [65, 65, 65, 65, 65, 65, 65, 0];
+            let b = a.as_ptr();
+            let c = raw::from_c_str(b);
+            assert_eq!(c, "AAAAAAA".to_string());
+        }
+    }
+
+    #[test]
+    fn test_as_bytes() {
+        // no null
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109
+        ];
+        assert_eq!("".as_bytes(), &[]);
+        assert_eq!("abc".as_bytes(), &['a' as u8, 'b' as u8, 'c' as u8]);
+        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v.as_slice());
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_as_bytes_fail() {
+        // Don't double free. (I'm not sure if this exercises the
+        // original problem code path anymore.)
+        let s = "".to_string();
+        let _bytes = s.as_bytes();
+        fail!();
+    }
+
+    #[test]
+    fn test_as_ptr() {
+        let buf = "hello".as_ptr();
+        unsafe {
+            assert_eq!(*buf.offset(0), 'h' as u8);
+            assert_eq!(*buf.offset(1), 'e' as u8);
+            assert_eq!(*buf.offset(2), 'l' as u8);
+            assert_eq!(*buf.offset(3), 'l' as u8);
+            assert_eq!(*buf.offset(4), 'o' as u8);
+        }
+    }
+
+    #[test]
+    fn test_subslice_offset() {
+        let a = "kernelsprite";
+        let b = a.slice(7, a.len());
+        let c = a.slice(0, a.len() - 6);
+        assert_eq!(a.subslice_offset(b), 7);
+        assert_eq!(a.subslice_offset(c), 0);
+
+        let string = "a\nb\nc";
+        let lines: Vec<&str> = string.lines().collect();
+        let lines = lines.as_slice();
+        assert_eq!(string.subslice_offset(lines[0]), 0);
+        assert_eq!(string.subslice_offset(lines[1]), 2);
+        assert_eq!(string.subslice_offset(lines[2]), 4);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_subslice_offset_2() {
+        let a = "alchemiter";
+        let b = "cruxtruder";
+        a.subslice_offset(b);
+    }
+
+    #[test]
+    fn vec_str_conversions() {
+        let s1: String = "All mimsy were the borogoves".to_string();
+
+        let v: Vec<u8> = Vec::from_slice(s1.as_bytes());
+        let s2: String = from_utf8(v.as_slice()).unwrap().to_string();
+        let mut i: uint = 0u;
+        let n1: uint = s1.len();
+        let n2: uint = v.len();
+        assert_eq!(n1, n2);
+        while i < n1 {
+            let a: u8 = s1.as_slice()[i];
+            let b: u8 = s2.as_slice()[i];
+            debug!("{}", a);
+            debug!("{}", b);
+            assert_eq!(a, b);
+            i += 1u;
+        }
+    }
+
+    #[test]
+    fn test_contains() {
+        assert!("abcde".contains("bcd"));
+        assert!("abcde".contains("abcd"));
+        assert!("abcde".contains("bcde"));
+        assert!("abcde".contains(""));
+        assert!("".contains(""));
+        assert!(!"abcde".contains("def"));
+        assert!(!"".contains("a"));
+
+        let data = "ประเทศไทย中华Việt Nam";
+        assert!(data.contains("ประเ"));
+        assert!(data.contains("ะเ"));
+        assert!(data.contains("中华"));
+        assert!(!data.contains("ไท华"));
+    }
+
+    #[test]
+    fn test_contains_char() {
+        assert!("abc".contains_char('b'));
+        assert!("a".contains_char('a'));
+        assert!(!"abc".contains_char('d'));
+        assert!(!"".contains_char('a'));
+    }
+
+    #[test]
+    fn test_utf16() {
+        let pairs =
+            [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_string(),
+              vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
+                0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
+                0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
+                0xd800_u16, 0xdf30_u16, 0x000a_u16]),
+
+             ("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n".to_string(),
+              vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
+                0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
+                0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
+                0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
+                0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
+                0x000a_u16]),
+
+             ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_string(),
+              vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
+                0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
+                0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
+                0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
+                0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
+                0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
+                0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
+
+             ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_string(),
+              vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
+                0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
+                0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
+                0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
+                0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
+                0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
+                0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
+                0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
+                0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
+                0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
+                0x000a_u16 ]),
+             // Issue #12318, even-numbered non-BMP planes
+             ("\U00020000".to_string(),
+              vec![0xD840, 0xDC00])];
+
+        for p in pairs.iter() {
+            let (s, u) = (*p).clone();
+            assert!(is_utf16(u.as_slice()));
+            assert_eq!(s.to_utf16(), u);
+
+            assert_eq!(from_utf16(u.as_slice()).unwrap(), s);
+            assert_eq!(from_utf16_lossy(u.as_slice()), s);
+
+            assert_eq!(from_utf16(s.to_utf16().as_slice()).unwrap(), s);
+            assert_eq!(from_utf16(u.as_slice()).unwrap().to_utf16(), u);
+        }
+    }
+
+    #[test]
+    fn test_utf16_invalid() {
+        // completely positive cases tested above.
+        // lead + eof
+        assert_eq!(from_utf16([0xD800]), None);
+        // lead + lead
+        assert_eq!(from_utf16([0xD800, 0xD800]), None);
+
+        // isolated trail
+        assert_eq!(from_utf16([0x0061, 0xDC00]), None);
+
+        // general
+        assert_eq!(from_utf16([0xD800, 0xd801, 0xdc8b, 0xD800]), None);
+    }
+
+    #[test]
+    fn test_utf16_lossy() {
+        // completely positive cases tested above.
+        // lead + eof
+        assert_eq!(from_utf16_lossy([0xD800]), "\uFFFD".to_string());
+        // lead + lead
+        assert_eq!(from_utf16_lossy([0xD800, 0xD800]), "\uFFFD\uFFFD".to_string());
+
+        // isolated trail
+        assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), "a\uFFFD".to_string());
+
+        // general
+        assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]),
+                   "\uFFFD𐒋\uFFFD".to_string());
+    }
+
+    #[test]
+    fn test_truncate_utf16_at_nul() {
+        let v = [];
+        assert_eq!(truncate_utf16_at_nul(v), &[]);
+
+        let v = [0, 2, 3];
+        assert_eq!(truncate_utf16_at_nul(v), &[]);
+
+        let v = [1, 0, 3];
+        assert_eq!(truncate_utf16_at_nul(v), &[1]);
+
+        let v = [1, 2, 0];
+        assert_eq!(truncate_utf16_at_nul(v), &[1, 2]);
+
+        let v = [1, 2, 3];
+        assert_eq!(truncate_utf16_at_nul(v), &[1, 2, 3]);
+    }
+
+    #[test]
+    fn test_char_at() {
+        let s = "ศไทย中华Việt Nam";
+        let v = box ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+        let mut pos = 0;
+        for ch in v.iter() {
+            assert!(s.char_at(pos) == *ch);
+            pos += from_char(*ch).len();
+        }
+    }
+
+    #[test]
+    fn test_char_at_reverse() {
+        let s = "ศไทย中华Việt Nam";
+        let v = box ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+        let mut pos = s.len();
+        for ch in v.iter().rev() {
+            assert!(s.char_at_reverse(pos) == *ch);
+            pos -= from_char(*ch).len();
+        }
+    }
+
+    #[test]
+    fn test_escape_unicode() {
+        assert_eq!("abc".escape_unicode(), "\\x61\\x62\\x63".to_string());
+        assert_eq!("a c".escape_unicode(), "\\x61\\x20\\x63".to_string());
+        assert_eq!("\r\n\t".escape_unicode(), "\\x0d\\x0a\\x09".to_string());
+        assert_eq!("'\"\\".escape_unicode(), "\\x27\\x22\\x5c".to_string());
+        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), "\\x00\\x01\\xfe\\xff".to_string());
+        assert_eq!("\u0100\uffff".escape_unicode(), "\\u0100\\uffff".to_string());
+        assert_eq!("\U00010000\U0010ffff".escape_unicode(), "\\U00010000\\U0010ffff".to_string());
+        assert_eq!("ab\ufb00".escape_unicode(), "\\x61\\x62\\ufb00".to_string());
+        assert_eq!("\U0001d4ea\r".escape_unicode(), "\\U0001d4ea\\x0d".to_string());
+    }
+
+    #[test]
+    fn test_escape_default() {
+        assert_eq!("abc".escape_default(), "abc".to_string());
+        assert_eq!("a c".escape_default(), "a c".to_string());
+        assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t".to_string());
+        assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\".to_string());
+        assert_eq!("\u0100\uffff".escape_default(), "\\u0100\\uffff".to_string());
+        assert_eq!("\U00010000\U0010ffff".escape_default(), "\\U00010000\\U0010ffff".to_string());
+        assert_eq!("ab\ufb00".escape_default(), "ab\\ufb00".to_string());
+        assert_eq!("\U0001d4ea\r".escape_default(), "\\U0001d4ea\\r".to_string());
+    }
+
+    #[test]
+    fn test_total_ord() {
+        "1234".cmp(&("123")) == Greater;
+        "123".cmp(&("1234")) == Less;
+        "1234".cmp(&("1234")) == Equal;
+        "12345555".cmp(&("123456")) == Less;
+        "22".cmp(&("1234")) == Greater;
+    }
+
+    #[test]
+    fn test_char_range_at() {
+        let data = "b¢€𤭢𤭢€¢b";
+        assert_eq!('b', data.char_range_at(0).ch);
+        assert_eq!('¢', data.char_range_at(1).ch);
+        assert_eq!('€', data.char_range_at(3).ch);
+        assert_eq!('𤭢', data.char_range_at(6).ch);
+        assert_eq!('𤭢', data.char_range_at(10).ch);
+        assert_eq!('€', data.char_range_at(14).ch);
+        assert_eq!('¢', data.char_range_at(17).ch);
+        assert_eq!('b', data.char_range_at(19).ch);
+    }
+
+    #[test]
+    fn test_char_range_at_reverse_underflow() {
+        assert_eq!("abc".char_range_at_reverse(0).next, 0);
+    }
+
+    #[test]
+    fn test_iterator() {
+        use iter::*;
+        let s = "ศไทย中华Việt Nam";
+        let v = box ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
+        let mut pos = 0;
+        let mut it = s.chars();
+
+        for c in it {
+            assert_eq!(c, v[pos]);
+            pos += 1;
+        }
+        assert_eq!(pos, v.len());
+    }
+
+    #[test]
+    fn test_rev_iterator() {
+        use iter::*;
+        let s = "ศไทย中华Việt Nam";
+        let v = box ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+        let mut pos = 0;
+        let mut it = s.chars().rev();
+
+        for c in it {
+            assert_eq!(c, v[pos]);
+            pos += 1;
+        }
+        assert_eq!(pos, v.len());
+    }
+
+    #[test]
+    fn test_iterator_clone() {
+        let s = "ศไทย中华Việt Nam";
+        let mut it = s.chars();
+        it.next();
+        assert!(it.zip(it.clone()).all(|(x,y)| x == y));
+    }
+
+    #[test]
+    fn test_bytesator() {
+        let s = "ศไทย中华Việt Nam";
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109
+        ];
+        let mut pos = 0;
+
+        for b in s.bytes() {
+            assert_eq!(b, v[pos]);
+            pos += 1;
+        }
+    }
+
+    #[test]
+    fn test_bytes_revator() {
+        let s = "ศไทย中华Việt Nam";
+        let v = [
+            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
+            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
+            109
+        ];
+        let mut pos = v.len();
+
+        for b in s.bytes().rev() {
+            pos -= 1;
+            assert_eq!(b, v[pos]);
+        }
+    }
+
+    #[test]
+    fn test_char_indicesator() {
+        use iter::*;
+        let s = "ศไทย中华Việt Nam";
+        let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
+        let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
+
+        let mut pos = 0;
+        let mut it = s.char_indices();
+
+        for c in it {
+            assert_eq!(c, (p[pos], v[pos]));
+            pos += 1;
+        }
+        assert_eq!(pos, v.len());
+        assert_eq!(pos, p.len());
+    }
+
+    #[test]
+    fn test_char_indices_revator() {
+        use iter::*;
+        let s = "ศไทย中华Việt Nam";
+        let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
+        let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
+
+        let mut pos = 0;
+        let mut it = s.char_indices().rev();
+
+        for c in it {
+            assert_eq!(c, (p[pos], v[pos]));
+            pos += 1;
+        }
+        assert_eq!(pos, v.len());
+        assert_eq!(pos, p.len());
+    }
+
+    #[test]
+    fn test_split_char_iterator() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+        let split: Vec<&str> = data.split(' ').collect();
+        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+        let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
+        rsplit.reverse();
+        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+        let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
+        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+        let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
+        rsplit.reverse();
+        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
+
+        // Unicode
+        let split: Vec<&str> = data.split('ä').collect();
+        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+
+        let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
+        rsplit.reverse();
+        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+
+        let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
+        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+
+        let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
+        rsplit.reverse();
+        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
+    }
+
+    #[test]
+    fn test_splitn_char_iterator() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+        let split: Vec<&str> = data.splitn(' ', 3).collect();
+        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+        let split: Vec<&str> = data.splitn(|c: char| c == ' ', 3).collect();
+        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
+
+        // Unicode
+        let split: Vec<&str> = data.splitn('ä', 3).collect();
+        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+
+        let split: Vec<&str> = data.splitn(|c: char| c == 'ä', 3).collect();
+        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
+    }
+
+    #[test]
+    fn test_rsplitn_char_iterator() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+        let mut split: Vec<&str> = data.rsplitn(' ', 3).collect();
+        split.reverse();
+        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+
+        let mut split: Vec<&str> = data.rsplitn(|c: char| c == ' ', 3).collect();
+        split.reverse();
+        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
+
+        // Unicode
+        let mut split: Vec<&str> = data.rsplitn('ä', 3).collect();
+        split.reverse();
+        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+
+        let mut split: Vec<&str> = data.rsplitn(|c: char| c == 'ä', 3).collect();
+        split.reverse();
+        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
+    }
+
+    #[test]
+    fn test_split_char_iterator_no_trailing() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+        let split: Vec<&str> = data.split('\n').collect();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
+
+        let split: Vec<&str> = data.split_terminator('\n').collect();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
+    }
+
+    #[test]
+    fn test_rev_split_char_iterator_no_trailing() {
+        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
+
+        let mut split: Vec<&str> = data.split('\n').rev().collect();
+        split.reverse();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
+
+        let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
+        split.reverse();
+        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
+    }
+
+    #[test]
+    fn test_words() {
+        let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
+        let words: Vec<&str> = data.words().collect();
+        assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
+    }
+
+    #[test]
+    fn test_nfd_chars() {
+        assert_eq!("abc".nfd_chars().collect::<String>(), "abc".to_string());
+        assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(), "d\u0307\u01c4".to_string());
+        assert_eq!("\u2026".nfd_chars().collect::<String>(), "\u2026".to_string());
+        assert_eq!("\u2126".nfd_chars().collect::<String>(), "\u03a9".to_string());
+        assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
+        assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
+        assert_eq!("a\u0301".nfd_chars().collect::<String>(), "a\u0301".to_string());
+        assert_eq!("\u0301a".nfd_chars().collect::<String>(), "\u0301a".to_string());
+        assert_eq!("\ud4db".nfd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
+        assert_eq!("\uac1c".nfd_chars().collect::<String>(), "\u1100\u1162".to_string());
+    }
+
+    #[test]
+    fn test_nfkd_chars() {
+        assert_eq!("abc".nfkd_chars().collect::<String>(), "abc".to_string());
+        assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(), "d\u0307DZ\u030c".to_string());
+        assert_eq!("\u2026".nfkd_chars().collect::<String>(), "...".to_string());
+        assert_eq!("\u2126".nfkd_chars().collect::<String>(), "\u03a9".to_string());
+        assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
+        assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
+        assert_eq!("a\u0301".nfkd_chars().collect::<String>(), "a\u0301".to_string());
+        assert_eq!("\u0301a".nfkd_chars().collect::<String>(), "\u0301a".to_string());
+        assert_eq!("\ud4db".nfkd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
+        assert_eq!("\uac1c".nfkd_chars().collect::<String>(), "\u1100\u1162".to_string());
+    }
+
+    #[test]
+    fn test_lines() {
+        let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
+        let lines: Vec<&str> = data.lines().collect();
+        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
+
+        let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
+        let lines: Vec<&str> = data.lines().collect();
+        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
+    }
+
+    #[test]
+    fn test_split_strator() {
+        fn t(s: &str, sep: &str, u: &[&str]) {
+            let v: Vec<&str> = s.split_str(sep).collect();
+            assert_eq!(v.as_slice(), u.as_slice());
+        }
+        t("--1233345--", "12345", ["--1233345--"]);
+        t("abc::hello::there", "::", ["abc", "hello", "there"]);
+        t("::hello::there", "::", ["", "hello", "there"]);
+        t("hello::there::", "::", ["hello", "there", ""]);
+        t("::hello::there::", "::", ["", "hello", "there", ""]);
+        t("ประเทศไทย中华Việt Nam", "中华", ["ประเทศไทย", "Việt Nam"]);
+        t("zzXXXzzYYYzz", "zz", ["", "XXX", "YYY", ""]);
+        t("zzXXXzYYYz", "XXX", ["zz", "zYYYz"]);
+        t(".XXX.YYY.", ".", ["", "XXX", "YYY", ""]);
+        t("", ".", [""]);
+        t("zz", "zz", ["",""]);
+        t("ok", "z", ["ok"]);
+        t("zzz", "zz", ["","z"]);
+        t("zzzzz", "zz", ["","","z"]);
+    }
+
+    #[test]
+    fn test_str_default() {
+        use default::Default;
+        fn t<S: Default + Str>() {
+            let s: S = Default::default();
+            assert_eq!(s.as_slice(), "");
+        }
+
+        t::<&str>();
+        t::<String>();
+    }
+
+    #[test]
+    fn test_str_container() {
+        fn sum_len<S: Container>(v: &[S]) -> uint {
+            v.iter().map(|x| x.len()).sum()
+        }
+
+        let s = "01234".to_string();
+        assert_eq!(5, sum_len(["012", "", "34"]));
+        assert_eq!(5, sum_len(["01".to_string(), "2".to_string(),
+                               "34".to_string(), "".to_string()]));
+        assert_eq!(5, sum_len([s.as_slice()]));
+    }
+
+    #[test]
+    fn test_str_from_utf8() {
+        let xs = bytes!("hello");
+        assert_eq!(from_utf8(xs), Some("hello"));
+
+        let xs = bytes!("ศไทย中华Việt Nam");
+        assert_eq!(from_utf8(xs), Some("ศไทย中华Việt Nam"));
+
+        let xs = bytes!("hello", 0xff);
+        assert_eq!(from_utf8(xs), None);
+    }
+
+    #[test]
+    fn test_str_from_utf8_owned() {
+        let xs = Vec::from_slice(bytes!("hello"));
+        assert_eq!(from_utf8_owned(xs), Ok("hello".to_string()));
+
+        let xs = Vec::from_slice(bytes!("ศไทย中华Việt Nam"));
+        assert_eq!(from_utf8_owned(xs), Ok("ศไทย中华Việt Nam".to_string()));
+
+        let xs = Vec::from_slice(bytes!("hello", 0xff));
+        assert_eq!(from_utf8_owned(xs),
+                   Err(Vec::from_slice(bytes!("hello", 0xff))));
+    }
+
+    #[test]
+    fn test_str_from_utf8_lossy() {
+        let xs = bytes!("hello");
+        assert_eq!(from_utf8_lossy(xs), Slice("hello"));
+
+        let xs = bytes!("ศไทย中华Việt Nam");
+        assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
+
+        let xs = bytes!("Hello", 0xC2, " There", 0xFF, " Goodbye");
+        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD There\uFFFD Goodbye".to_string()));
+
+        let xs = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
+        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD\uFFFD There\uFFFD Goodbye".to_string()));
+
+        let xs = bytes!(0xF5, "foo", 0xF5, 0x80, "bar");
+        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFD\uFFFDbar".to_string()));
+
+        let xs = bytes!(0xF1, "foo", 0xF1, 0x80, "bar", 0xF1, 0x80, 0x80, "baz");
+        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFDbaz".to_string()));
+
+        let xs = bytes!(0xF4, "foo", 0xF4, 0x80, "bar", 0xF4, 0xBF, "baz");
+        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz".to_string()));
+
+        let xs = bytes!(0xF0, 0x80, 0x80, 0x80, "foo", 0xF0, 0x90, 0x80, 0x80, "bar");
+        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFD\uFFFD\
+                                               foo\U00010000bar".to_string()));
+
+        // surrogates
+        let xs = bytes!(0xED, 0xA0, 0x80, "foo", 0xED, 0xBF, 0xBF, "bar");
+        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFDfoo\
+                                               \uFFFD\uFFFD\uFFFDbar".to_string()));
+    }
+
+    #[test]
+    fn test_from_str() {
+      let owned: Option<String> = from_str("string");
+      assert_eq!(owned, Some("string".to_string()));
+    }
+
+    #[test]
+    fn test_maybe_owned_traits() {
+        let s = Slice("abcde");
+        assert_eq!(s.len(), 5);
+        assert_eq!(s.as_slice(), "abcde");
+        assert_eq!(s.to_str(), "abcde".to_string());
+        assert_eq!(format!("{}", s), "abcde".to_string());
+        assert!(s.lt(&Owned("bcdef".to_string())));
+        assert_eq!(Slice(""), Default::default());
+
+        let o = Owned("abcde".to_string());
+        assert_eq!(o.len(), 5);
+        assert_eq!(o.as_slice(), "abcde");
+        assert_eq!(o.to_str(), "abcde".to_string());
+        assert_eq!(format!("{}", o), "abcde".to_string());
+        assert!(o.lt(&Slice("bcdef")));
+        assert_eq!(Owned("".to_string()), Default::default());
+
+        assert!(s.cmp(&o) == Equal);
+        assert!(s.equiv(&o));
+
+        assert!(o.cmp(&s) == Equal);
+        assert!(o.equiv(&s));
+    }
+
+    #[test]
+    fn test_maybe_owned_methods() {
+        let s = Slice("abcde");
+        assert!(s.is_slice());
+        assert!(!s.is_owned());
+
+        let o = Owned("abcde".to_string());
+        assert!(!o.is_slice());
+        assert!(o.is_owned());
+    }
+
+    #[test]
+    fn test_maybe_owned_clone() {
+        assert_eq!(Owned("abcde".to_string()), Slice("abcde").clone());
+        assert_eq!(Owned("abcde".to_string()), Owned("abcde".to_string()).clone());
+        assert_eq!(Slice("abcde"), Slice("abcde").clone());
+        assert_eq!(Slice("abcde"), Owned("abcde".to_string()).clone());
+    }
+
+    #[test]
+    fn test_maybe_owned_into_string() {
+        assert_eq!(Slice("abcde").into_string(), "abcde".to_string());
+        assert_eq!(Owned("abcde".to_string()).into_string(), "abcde".to_string());
+    }
+
+    #[test]
+    fn test_into_maybe_owned() {
+        assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
+        assert_eq!(("abcde".to_string()).into_maybe_owned(), Slice("abcde"));
+        assert_eq!("abcde".into_maybe_owned(), Owned("abcde".to_string()));
+        assert_eq!(("abcde".to_string()).into_maybe_owned(), Owned("abcde".to_string()));
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::Bencher;
+    use super::*;
+    use prelude::*;
+
+    #[bench]
+    fn char_iterator(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        b.iter(|| assert_eq!(s.chars().len(), len));
+    }
+
+    #[bench]
+    fn char_iterator_ascii(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb
+        Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        b.iter(|| assert_eq!(s.chars().len(), len));
+    }
+
+    #[bench]
+    fn char_iterator_rev(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        b.iter(|| assert_eq!(s.chars().rev().len(), len));
+    }
+
+    #[bench]
+    fn char_indicesator(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        b.iter(|| assert_eq!(s.char_indices().len(), len));
+    }
+
+    #[bench]
+    fn char_indicesator_rev(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let len = s.char_len();
+
+        b.iter(|| assert_eq!(s.char_indices().rev().len(), len));
+    }
+
+    #[bench]
+    fn split_unicode_ascii(b: &mut Bencher) {
+        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
+
+        b.iter(|| assert_eq!(s.split('V').len(), 3));
+    }
+
+    #[bench]
+    fn split_unicode_not_ascii(b: &mut Bencher) {
+        struct NotAscii(char);
+        impl CharEq for NotAscii {
+            fn matches(&mut self, c: char) -> bool {
+                let NotAscii(cc) = *self;
+                cc == c
+            }
+            fn only_ascii(&self) -> bool { false }
+        }
+        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
+
+        b.iter(|| assert_eq!(s.split(NotAscii('V')).len(), 3));
+    }
+
+
+    #[bench]
+    fn split_ascii(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').len();
+
+        b.iter(|| assert_eq!(s.split(' ').len(), len));
+    }
+
+    #[bench]
+    fn split_not_ascii(b: &mut Bencher) {
+        struct NotAscii(char);
+        impl CharEq for NotAscii {
+            #[inline]
+            fn matches(&mut self, c: char) -> bool {
+                let NotAscii(cc) = *self;
+                cc == c
+            }
+            fn only_ascii(&self) -> bool { false }
+        }
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').len();
+
+        b.iter(|| assert_eq!(s.split(NotAscii(' ')).len(), len));
+    }
+
+    #[bench]
+    fn split_extern_fn(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').len();
+        fn pred(c: char) -> bool { c == ' ' }
+
+        b.iter(|| assert_eq!(s.split(pred).len(), len));
+    }
+
+    #[bench]
+    fn split_closure(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').len();
+
+        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').len(), len));
+    }
+
+    #[bench]
+    fn split_slice(b: &mut Bencher) {
+        let s = "Mary had a little lamb, Little lamb, little-lamb.";
+        let len = s.split(' ').len();
+
+        b.iter(|| assert_eq!(s.split(&[' ']).len(), len));
+    }
+
+    #[bench]
+    fn is_utf8_100_ascii(b: &mut Bencher) {
+
+        let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
+                        Lorem ipsum dolor sit amet, consectetur. ");
+
+        assert_eq!(100, s.len());
+        b.iter(|| {
+            is_utf8(s)
+        });
+    }
+
+    #[bench]
+    fn is_utf8_100_multibyte(b: &mut Bencher) {
+        let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
+        assert_eq!(100, s.len());
+        b.iter(|| {
+            is_utf8(s)
+        });
+    }
+
+    #[bench]
+    fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
+        let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
+                        Lorem ipsum dolor sit amet, consectetur. ");
+
+        assert_eq!(100, s.len());
+        b.iter(|| {
+            let _ = from_utf8_lossy(s);
+        });
+    }
+
+    #[bench]
+    fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
+        let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
+        assert_eq!(100, s.len());
+        b.iter(|| {
+            let _ = from_utf8_lossy(s);
+        });
+    }
+
+    #[bench]
+    fn from_utf8_lossy_invalid(b: &mut Bencher) {
+        let s = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
+        b.iter(|| {
+            let _ = from_utf8_lossy(s);
+        });
+    }
+
+    #[bench]
+    fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
+        let s = Vec::from_elem(100, 0xF5u8);
+        b.iter(|| {
+            let _ = from_utf8_lossy(s.as_slice());
+        });
+    }
+
+    #[bench]
+    fn bench_connect(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        let sep = "→";
+        let v = [s, s, s, s, s, s, s, s, s, s];
+        b.iter(|| {
+            assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
+        })
+    }
+
+    #[bench]
+    fn bench_contains_short_short(b: &mut Bencher) {
+        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+        let needle = "sit";
+
+        b.iter(|| {
+            assert!(haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_short_long(b: &mut Bencher) {
+        let haystack = "\
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
+ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
+eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
+sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
+tempus vel, gravida nec quam.
+
+In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
+sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
+diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
+lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
+eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
+interdum. Curabitur ut nisi justo.
+
+Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
+mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
+lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
+est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
+felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
+ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
+feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
+Aliquam sit amet placerat lorem.
+
+Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
+mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
+Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
+lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
+suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
+cursus accumsan.
+
+Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
+feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
+vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
+leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
+malesuada sollicitudin quam eu fermentum.";
+        let needle = "english";
+
+        b.iter(|| {
+            assert!(!haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_bad_naive(b: &mut Bencher) {
+        let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
+        let needle = "aaaaaaaab";
+
+        b.iter(|| {
+            assert!(!haystack.contains(needle));
+        })
+    }
+
+    #[bench]
+    fn bench_contains_equal(b: &mut Bencher) {
+        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+        let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
+
+        b.iter(|| {
+            assert!(haystack.contains(needle));
+        })
+    }
+}
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
new file mode 100644 (file)
index 0000000..764811e
--- /dev/null
@@ -0,0 +1,470 @@
+// Copyright 2014 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.
+
+//! An owned, growable string that enforces that its contents are valid UTF-8.
+
+use core::prelude::*;
+
+use core::default::Default;
+use core::fmt;
+use core::mem;
+use core::ptr;
+use core::raw::Slice;
+
+use hash;
+use str;
+use str::{CharRange, StrAllocating};
+use vec::Vec;
+
+/// A growable string stored as a UTF-8 encoded buffer.
+#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
+pub struct String {
+    vec: Vec<u8>,
+}
+
+impl String {
+    /// Creates a new string buffer initialized with the empty string.
+    #[inline]
+    pub fn new() -> String {
+        String {
+            vec: Vec::new(),
+        }
+    }
+
+    /// Creates a new string buffer with the given capacity.
+    #[inline]
+    pub fn with_capacity(capacity: uint) -> String {
+        String {
+            vec: Vec::with_capacity(capacity),
+        }
+    }
+
+    /// Creates a new string buffer from length, capacity, and a pointer.
+    #[inline]
+    pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
+        String {
+            vec: Vec::from_raw_parts(length, capacity, ptr),
+        }
+    }
+
+    /// Creates a new string buffer from the given string.
+    #[inline]
+    pub fn from_str(string: &str) -> String {
+        String {
+            vec: Vec::from_slice(string.as_bytes())
+        }
+    }
+
+    #[allow(missing_doc)]
+    #[deprecated = "obsoleted by the removal of ~str"]
+    #[inline]
+    pub fn from_owned_str(string: String) -> String {
+        string
+    }
+
+    /// Returns the vector as a string buffer, if possible, taking care not to
+    /// copy it.
+    ///
+    /// Returns `Err` with the original vector if the vector contains invalid
+    /// UTF-8.
+    #[inline]
+    pub fn from_utf8(vec: Vec<u8>) -> Result<String, Vec<u8>> {
+        if str::is_utf8(vec.as_slice()) {
+            Ok(String { vec: vec })
+        } else {
+            Err(vec)
+        }
+    }
+
+    /// Return the underlying byte buffer, encoded as UTF-8.
+    #[inline]
+    pub fn into_bytes(self) -> Vec<u8> {
+        self.vec
+    }
+
+    /// Pushes the given string onto this buffer; then, returns `self` so that it can be used
+    /// again.
+    #[inline]
+    pub fn append(mut self, second: &str) -> String {
+        self.push_str(second);
+        self
+    }
+
+    /// Creates a string buffer by repeating a character `length` times.
+    #[inline]
+    pub fn from_char(length: uint, ch: char) -> String {
+        if length == 0 {
+            return String::new()
+        }
+
+        let mut buf = String::new();
+        buf.push_char(ch);
+        let size = buf.len() * length;
+        buf.reserve(size);
+        for _ in range(1, length) {
+            buf.push_char(ch)
+        }
+        buf
+    }
+
+    /// Pushes the given string onto this string buffer.
+    #[inline]
+    pub fn push_str(&mut self, string: &str) {
+        self.vec.push_all(string.as_bytes())
+    }
+
+    /// Push `ch` onto the given string `count` times.
+    #[inline]
+    pub fn grow(&mut self, count: uint, ch: char) {
+        for _ in range(0, count) {
+            self.push_char(ch)
+        }
+    }
+
+    /// Returns the number of bytes that this string buffer can hold without reallocating.
+    #[inline]
+    pub fn byte_capacity(&self) -> uint {
+        self.vec.capacity()
+    }
+
+    /// Reserves capacity for at least `extra` additional bytes in this string buffer.
+    #[inline]
+    pub fn reserve_additional(&mut self, extra: uint) {
+        self.vec.reserve_additional(extra)
+    }
+
+    /// Reserves capacity for at least `capacity` bytes in this string buffer.
+    #[inline]
+    pub fn reserve(&mut self, capacity: uint) {
+        self.vec.reserve(capacity)
+    }
+
+    /// Reserves capacity for exactly `capacity` bytes in this string buffer.
+    #[inline]
+    pub fn reserve_exact(&mut self, capacity: uint) {
+        self.vec.reserve_exact(capacity)
+    }
+
+    /// Shrinks the capacity of this string buffer to match its length.
+    #[inline]
+    pub fn shrink_to_fit(&mut self) {
+        self.vec.shrink_to_fit()
+    }
+
+    /// Adds the given character to the end of the string.
+    #[inline]
+    pub fn push_char(&mut self, ch: char) {
+        let cur_len = self.len();
+        // This may use up to 4 bytes.
+        self.vec.reserve_additional(4);
+
+        unsafe {
+            // Attempt to not use an intermediate buffer by just pushing bytes
+            // directly onto this string.
+            let slice = Slice {
+                data: self.vec.as_ptr().offset(cur_len as int),
+                len: 4,
+            };
+            let used = ch.encode_utf8(mem::transmute(slice));
+            self.vec.set_len(cur_len + used);
+        }
+    }
+
+    /// Pushes the given bytes onto this string buffer. This is unsafe because it does not check
+    /// to ensure that the resulting string will be valid UTF-8.
+    #[inline]
+    pub unsafe fn push_bytes(&mut self, bytes: &[u8]) {
+        self.vec.push_all(bytes)
+    }
+
+    /// Works with the underlying buffer as a byte slice.
+    #[inline]
+    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
+        self.vec.as_slice()
+    }
+
+    /// Works with the underlying buffer as a mutable byte slice. Unsafe
+    /// because this can be used to violate the UTF-8 property.
+    #[inline]
+    pub unsafe fn as_mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
+        self.vec.as_mut_slice()
+    }
+
+    /// Shorten a string to the specified length (which must be <= the current length)
+    #[inline]
+    pub fn truncate(&mut self, len: uint) {
+        assert!(self.as_slice().is_char_boundary(len));
+        self.vec.truncate(len)
+    }
+
+    /// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
+    #[inline]
+    pub unsafe fn push_byte(&mut self, byte: u8) {
+        self.push_bytes([byte])
+    }
+
+    /// Removes the last byte from the string buffer and returns it. Returns `None` if this string
+    /// buffer is empty.
+    ///
+    /// The caller must preserve the valid UTF-8 property.
+    #[inline]
+    pub unsafe fn pop_byte(&mut self) -> Option<u8> {
+        let len = self.len();
+        if len == 0 {
+            return None
+        }
+
+        let byte = self.as_slice()[len - 1];
+        self.vec.set_len(len - 1);
+        Some(byte)
+    }
+
+    /// Removes the last character from the string buffer and returns it. Returns `None` if this
+    /// string buffer is empty.
+    #[inline]
+    pub fn pop_char(&mut self) -> Option<char> {
+        let len = self.len();
+        if len == 0 {
+            return None
+        }
+
+        let CharRange {ch, next} = self.as_slice().char_range_at_reverse(len);
+        unsafe {
+            self.vec.set_len(next);
+        }
+        Some(ch)
+    }
+
+    /// Removes the first byte from the string buffer and returns it. Returns `None` if this string
+    /// buffer is empty.
+    ///
+    /// The caller must preserve the valid UTF-8 property.
+    pub unsafe fn shift_byte(&mut self) -> Option<u8> {
+        self.vec.shift()
+    }
+
+    /// Removes the first character from the string buffer and returns it. Returns `None` if this
+    /// string buffer is empty.
+    ///
+    /// # Warning
+    ///
+    /// This is a O(n) operation as it requires copying every element in the buffer.
+    pub fn shift_char (&mut self) -> Option<char> {
+        let len = self.len();
+        if len == 0 {
+            return None
+        }
+
+        let CharRange {ch, next} = self.as_slice().char_range_at(0);
+        let new_len = len - next;
+        unsafe {
+            ptr::copy_memory(self.vec.as_mut_ptr(), self.vec.as_ptr().offset(next as int), new_len);
+            self.vec.set_len(new_len);
+        }
+        Some(ch)
+    }
+
+    /// Views the string buffer as a mutable sequence of bytes.
+    ///
+    /// Callers must preserve the valid UTF-8 property.
+    pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
+        &mut self.vec
+    }
+}
+
+impl Container for String {
+    #[inline]
+    fn len(&self) -> uint {
+        self.vec.len()
+    }
+}
+
+impl Mutable for String {
+    #[inline]
+    fn clear(&mut self) {
+        self.vec.clear()
+    }
+}
+
+impl FromIterator<char> for String {
+    fn from_iter<I:Iterator<char>>(iterator: I) -> String {
+        let mut buf = String::new();
+        buf.extend(iterator);
+        buf
+    }
+}
+
+impl Extendable<char> for String {
+    fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
+        for ch in iterator {
+            self.push_char(ch)
+        }
+    }
+}
+
+impl Str for String {
+    #[inline]
+    fn as_slice<'a>(&'a self) -> &'a str {
+        unsafe {
+            mem::transmute(self.vec.as_slice())
+        }
+    }
+}
+
+impl StrAllocating for String {
+    #[inline]
+    fn into_string(self) -> String {
+        self
+    }
+}
+
+impl Default for String {
+    fn default() -> String {
+        String::new()
+    }
+}
+
+impl fmt::Show for String {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.as_slice().fmt(f)
+    }
+}
+
+impl<H: hash::Writer> hash::Hash<H> for String {
+    #[inline]
+    fn hash(&self, hasher: &mut H) {
+        self.as_slice().hash(hasher)
+    }
+}
+
+impl<'a, S: Str> Equiv<S> for String {
+    #[inline]
+    fn equiv(&self, other: &S) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    extern crate test;
+    use container::{Container, Mutable};
+    use self::test::Bencher;
+    use str::{Str, StrSlice};
+    use super::String;
+
+    #[bench]
+    fn bench_with_capacity(b: &mut Bencher) {
+        b.iter(|| {
+            String::with_capacity(100)
+        });
+    }
+
+    #[bench]
+    fn bench_push_str(b: &mut Bencher) {
+        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
+        b.iter(|| {
+            let mut r = String::new();
+            r.push_str(s);
+        });
+    }
+
+    #[test]
+    fn test_push_bytes() {
+        let mut s = String::from_str("ABC");
+        unsafe {
+            s.push_bytes([ 'D' as u8 ]);
+        }
+        assert_eq!(s.as_slice(), "ABCD");
+    }
+
+    #[test]
+    fn test_push_str() {
+        let mut s = String::new();
+        s.push_str("");
+        assert_eq!(s.as_slice().slice_from(0), "");
+        s.push_str("abc");
+        assert_eq!(s.as_slice().slice_from(0), "abc");
+        s.push_str("ประเทศไทย中华Việt Nam");
+        assert_eq!(s.as_slice().slice_from(0), "abcประเทศไทย中华Việt Nam");
+    }
+
+    #[test]
+    fn test_push_char() {
+        let mut data = String::from_str("ประเทศไทย中");
+        data.push_char('华');
+        data.push_char('b'); // 1 byte
+        data.push_char('¢'); // 2 byte
+        data.push_char('€'); // 3 byte
+        data.push_char('𤭢'); // 4 byte
+        assert_eq!(data.as_slice(), "ประเทศไทย中华b¢€𤭢");
+    }
+
+    #[test]
+    fn test_pop_char() {
+        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
+        assert_eq!(data.pop_char().unwrap(), '𤭢'); // 4 bytes
+        assert_eq!(data.pop_char().unwrap(), '€'); // 3 bytes
+        assert_eq!(data.pop_char().unwrap(), '¢'); // 2 bytes
+        assert_eq!(data.pop_char().unwrap(), 'b'); // 1 bytes
+        assert_eq!(data.pop_char().unwrap(), '华');
+        assert_eq!(data.as_slice(), "ประเทศไทย中");
+    }
+
+    #[test]
+    fn test_shift_char() {
+        let mut data = String::from_str("𤭢€¢b华ประเทศไทย中");
+        assert_eq!(data.shift_char().unwrap(), '𤭢'); // 4 bytes
+        assert_eq!(data.shift_char().unwrap(), '€'); // 3 bytes
+        assert_eq!(data.shift_char().unwrap(), '¢'); // 2 bytes
+        assert_eq!(data.shift_char().unwrap(), 'b'); // 1 bytes
+        assert_eq!(data.shift_char().unwrap(), '华');
+        assert_eq!(data.as_slice(), "ประเทศไทย中");
+    }
+
+    #[test]
+    fn test_str_truncate() {
+        let mut s = String::from_str("12345");
+        s.truncate(5);
+        assert_eq!(s.as_slice(), "12345");
+        s.truncate(3);
+        assert_eq!(s.as_slice(), "123");
+        s.truncate(0);
+        assert_eq!(s.as_slice(), "");
+
+        let mut s = String::from_str("12345");
+        let p = s.as_slice().as_ptr();
+        s.truncate(3);
+        s.push_str("6");
+        let p_ = s.as_slice().as_ptr();
+        assert_eq!(p_, p);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_str_truncate_invalid_len() {
+        let mut s = String::from_str("12345");
+        s.truncate(6);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_str_truncate_split_codepoint() {
+        let mut s = String::from_str("\u00FC"); // ü
+        s.truncate(1);
+    }
+
+    #[test]
+    fn test_str_clear() {
+        let mut s = String::from_str("12345");
+        s.clear();
+        assert_eq!(s.len(), 0);
+        assert_eq!(s.as_slice(), "");
+    }
+}
index 1184c9b7b52bb6a41e9c46d2bde4b989f631c9bd..1fd9fce20898da59027dbe0745a83957f452c5ae 100644 (file)
 //! trees. The only requirement for the types is that the key implements
 //! `Ord`.
 
-use std::cmp::Ordering;
-use std::fmt::Show;
-use std::fmt;
-use std::iter::Peekable;
-use std::iter;
-use std::mem::{replace, swap};
-use std::ptr;
+use core::prelude::*;
+
+use alloc::owned::Box;
+use core::fmt;
+use core::fmt::Show;
+use core::iter::Peekable;
+use core::iter;
+use core::mem::{replace, swap};
+use core::ptr;
+
+use vec::Vec;
 
 // This is implemented as an AA tree, which is a simplified variation of
 // a red-black tree where red (horizontal) nodes can only be added
index e6df4fd87e12e976b9054823b8c09389ce3e975d..a70b466623f54865bd7827a8f8d6662a59a996d6 100644 (file)
 
 //! Ordered containers with integer keys, implemented as radix tries (`TrieSet` and `TrieMap` types)
 
-use std::mem::zeroed;
-use std::mem;
-use std::slice::{Items, MutItems};
-use std::slice;
-use std::uint;
+use core::prelude::*;
+
+use alloc::owned::Box;
+use core::mem::zeroed;
+use core::mem;
+use core::uint;
+
+use slice::{Items, MutItems};
+use slice;
 
 // FIXME: #5244: need to manually update the TrieNode constructor
 static SHIFT: uint = 4;
@@ -457,7 +461,7 @@ fn insert<T>(count: &mut uint, child: &mut Child<T>, key: uint, value: T,
             *child = Internal(new);
             return ret;
         }
-        _ => unreachable!()
+        _ => fail!("unreachable code"),
     }
 }
 
diff --git a/src/libcollections/unicode.rs b/src/libcollections/unicode.rs
new file mode 100644 (file)
index 0000000..4402901
--- /dev/null
@@ -0,0 +1,183 @@
+// Copyright 2012-2014 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.
+
+// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
+
+#![allow(missing_doc, non_uppercase_statics)]
+
+pub mod normalization {
+    use core::prelude::*;
+
+    fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
+        match r.bsearch(|&(lo, hi, _)| {
+            if lo <= c && c <= hi { Equal }
+            else if hi < c { Less }
+            else { Greater }
+        }) {
+            Some(idx) => {
+                let (_, _, result) = r[idx];
+                result
+            }
+            None => 0
+        }
+    }
+
+
+    static combining_class_table : &'static [(char, char, u8)] = &[
+        ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232),
+        ('\u0316', '\u0319', 220), ('\u031a', '\u031a', 232),
+        ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220),
+        ('\u0321', '\u0322', 202), ('\u0323', '\u0326', 220),
+        ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
+        ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220),
+        ('\u033d', '\u0344', 230), ('\u0345', '\u0345', 240),
+        ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220),
+        ('\u034a', '\u034c', 230), ('\u034d', '\u034e', 220),
+        ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
+        ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232),
+        ('\u0359', '\u035a', 220), ('\u035b', '\u035b', 230),
+        ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234),
+        ('\u035f', '\u035f', 233), ('\u0360', '\u0361', 234),
+        ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
+        ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220),
+        ('\u0592', '\u0595', 230), ('\u0596', '\u0596', 220),
+        ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222),
+        ('\u059b', '\u059b', 220), ('\u059c', '\u05a1', 230),
+        ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
+        ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230),
+        ('\u05ad', '\u05ad', 222), ('\u05ae', '\u05ae', 228),
+        ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10),
+        ('\u05b1', '\u05b1', 11), ('\u05b2', '\u05b2', 12),
+        ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
+        ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16),
+        ('\u05b7', '\u05b7', 17), ('\u05b8', '\u05b8', 18),
+        ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20),
+        ('\u05bc', '\u05bc', 21), ('\u05bd', '\u05bd', 22),
+        ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24),
+        ('\u05c2', '\u05c2', 25), ('\u05c4', '\u05c4', 230),
+        ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7', 18),
+        ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30),
+        ('\u0619', '\u0619', 31), ('\u061a', '\u061a', 32),
+        ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28),
+        ('\u064d', '\u064d', 29), ('\u064e', '\u064e', 30),
+        ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
+        ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34),
+        ('\u0653', '\u0654', 230), ('\u0655', '\u0656', 220),
+        ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220),
+        ('\u065d', '\u065e', 230), ('\u065f', '\u065f', 220),
+        ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
+        ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220),
+        ('\u06e4', '\u06e4', 230), ('\u06e7', '\u06e8', 230),
+        ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230),
+        ('\u06ed', '\u06ed', 220), ('\u0711', '\u0711', 36),
+        ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
+        ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220),
+        ('\u0735', '\u0736', 230), ('\u0737', '\u0739', 220),
+        ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220),
+        ('\u073d', '\u073d', 230), ('\u073e', '\u073e', 220),
+        ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
+        ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220),
+        ('\u0745', '\u0745', 230), ('\u0746', '\u0746', 220),
+        ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220),
+        ('\u0749', '\u074a', 230), ('\u07eb', '\u07f1', 230),
+        ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
+        ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230),
+        ('\u0825', '\u0827', 230), ('\u0829', '\u082d', 230),
+        ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230),
+        ('\u08e6', '\u08e6', 220), ('\u08e7', '\u08e8', 230),
+        ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
+        ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27),
+        ('\u08f1', '\u08f1', 28), ('\u08f2', '\u08f2', 29),
+        ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220),
+        ('\u08f7', '\u08f8', 230), ('\u08f9', '\u08fa', 220),
+        ('\u08fb', '\u08fe', 230), ('\u093c', '\u093c', 7),
+        ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230),
+        ('\u0952', '\u0952', 220), ('\u0953', '\u0954', 230),
+        ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9),
+        ('\u0a3c', '\u0a3c', 7), ('\u0a4d', '\u0a4d', 9),
+        ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9),
+        ('\u0b3c', '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9),
+        ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
+        ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91),
+        ('\u0cbc', '\u0cbc', 7), ('\u0ccd', '\u0ccd', 9),
+        ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9),
+        ('\u0e38', '\u0e39', 103), ('\u0e3a', '\u0e3a', 9),
+        ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118),
+        ('\u0ec8', '\u0ecb', 122), ('\u0f18', '\u0f19', 220),
+        ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37', 220),
+        ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129),
+        ('\u0f72', '\u0f72', 130), ('\u0f74', '\u0f74', 132),
+        ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130),
+        ('\u0f82', '\u0f83', 230), ('\u0f84', '\u0f84', 9),
+        ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6', 220),
+        ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9),
+        ('\u108d', '\u108d', 220), ('\u135d', '\u135f', 230),
+        ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9),
+        ('\u17d2', '\u17d2', 9), ('\u17dd', '\u17dd', 230),
+        ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939', 222),
+        ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220),
+        ('\u1a17', '\u1a17', 230), ('\u1a18', '\u1a18', 220),
+        ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230),
+        ('\u1a7f', '\u1a7f', 220), ('\u1b34', '\u1b34', 7),
+        ('\u1b44', '\u1b44', 9), ('\u1b6b', '\u1b6b', 230),
+        ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230),
+        ('\u1baa', '\u1bab', 9), ('\u1be6', '\u1be6', 7),
+        ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
+        ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1),
+        ('\u1cd5', '\u1cd9', 220), ('\u1cda', '\u1cdb', 230),
+        ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230),
+        ('\u1ce2', '\u1ce8', 1), ('\u1ced', '\u1ced', 220),
+        ('\u1cf4', '\u1cf4', 230), ('\u1dc0', '\u1dc1', 230),
+        ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230),
+        ('\u1dca', '\u1dca', 220), ('\u1dcb', '\u1dcc', 230),
+        ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce', 214),
+        ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202),
+        ('\u1dd1', '\u1de6', 230), ('\u1dfc', '\u1dfc', 233),
+        ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230),
+        ('\u1dff', '\u1dff', 220), ('\u20d0', '\u20d1', 230),
+        ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7', 230),
+        ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230),
+        ('\u20e1', '\u20e1', 230), ('\u20e5', '\u20e6', 1),
+        ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220),
+        ('\u20e9', '\u20e9', 230), ('\u20ea', '\u20eb', 1),
+        ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0', 230),
+        ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9),
+        ('\u2de0', '\u2dff', 230), ('\u302a', '\u302a', 218),
+        ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232),
+        ('\u302d', '\u302d', 222), ('\u302e', '\u302f', 224),
+        ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f', 230),
+        ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230),
+        ('\ua6f0', '\ua6f1', 230), ('\ua806', '\ua806', 9),
+        ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230),
+        ('\ua92b', '\ua92d', 220), ('\ua953', '\ua953', 9),
+        ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
+        ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230),
+        ('\uaab4', '\uaab4', 220), ('\uaab7', '\uaab8', 230),
+        ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230),
+        ('\uaaf6', '\uaaf6', 9), ('\uabed', '\uabed', 9),
+        ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230),
+        ('\U000101fd', '\U000101fd', 220), ('\U00010a0d', '\U00010a0d', 220),
+        ('\U00010a0f', '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230),
+        ('\U00010a39', '\U00010a39', 1), ('\U00010a3a', '\U00010a3a', 220),
+        ('\U00010a3f', '\U00010a3f', 9), ('\U00011046', '\U00011046', 9),
+        ('\U000110b9', '\U000110b9', 9), ('\U000110ba', '\U000110ba', 7),
+        ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
+        ('\U000111c0', '\U000111c0', 9), ('\U000116b6', '\U000116b6', 9),
+        ('\U000116b7', '\U000116b7', 7), ('\U0001d165', '\U0001d166', 216),
+        ('\U0001d167', '\U0001d169', 1), ('\U0001d16d', '\U0001d16d', 226),
+        ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
+        ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220),
+        ('\U0001d1aa', '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230)
+    ];
+
+    pub fn canonical_combining_class(c: char) -> u8 {
+        bsearch_range_value_table(c, combining_class_table)
+    }
+}
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
new file mode 100644 (file)
index 0000000..faa9db7
--- /dev/null
@@ -0,0 +1,1900 @@
+// Copyright 2014 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.
+
+//! An owned, growable vector.
+
+use core::prelude::*;
+
+use alloc::heap::{allocate, reallocate, deallocate};
+use RawVec = core::raw::Vec;
+use core::raw::Slice;
+use core::cmp::max;
+use core::default::Default;
+use core::fmt;
+use core::mem;
+use core::num::{CheckedMul, CheckedAdd};
+use core::num;
+use core::ptr;
+use core::uint;
+
+use slice::{MutableTotalOrdVector, OwnedVector, MutableVectorAllocating};
+use slice::{Items, MutItems};
+
+/// An owned, growable vector.
+///
+/// # Examples
+///
+/// ```rust
+/// # use std::vec::Vec;
+/// let mut vec = Vec::new();
+/// vec.push(1);
+/// vec.push(2);
+///
+/// assert_eq!(vec.len(), 2);
+/// assert_eq!(vec.get(0), &1);
+///
+/// assert_eq!(vec.pop(), Some(2));
+/// assert_eq!(vec.len(), 1);
+/// ```
+///
+/// The `vec!` macro is provided to make initialization more convenient:
+///
+/// ```rust
+/// let mut vec = vec!(1, 2, 3);
+/// vec.push(4);
+/// assert_eq!(vec, vec!(1, 2, 3, 4));
+/// ```
+#[unsafe_no_drop_flag]
+pub struct Vec<T> {
+    len: uint,
+    cap: uint,
+    ptr: *mut T
+}
+
+impl<T> Vec<T> {
+    /// Constructs a new, empty `Vec`.
+    ///
+    /// The vector will not allocate until elements are pushed onto it.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let mut vec: Vec<int> = Vec::new();
+    /// ```
+    #[inline]
+    pub fn new() -> Vec<T> {
+        Vec { len: 0, cap: 0, ptr: 0 as *mut T }
+    }
+
+    /// Constructs a new, empty `Vec` with the specified capacity.
+    ///
+    /// The vector will be able to hold exactly `capacity` elements without
+    /// reallocating. If `capacity` is 0, the vector will not allocate.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec: Vec<int> = Vec::with_capacity(10);
+    /// ```
+    pub fn with_capacity(capacity: uint) -> Vec<T> {
+        if mem::size_of::<T>() == 0 {
+            Vec { len: 0, cap: uint::MAX, ptr: 0 as *mut T }
+        } else if capacity == 0 {
+            Vec::new()
+        } else {
+            let size = ::expect(capacity.checked_mul(&mem::size_of::<T>()),
+                                "capacity overflow");
+            let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
+            Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
+        }
+    }
+
+    /// Creates and initializes a `Vec`.
+    ///
+    /// Creates a `Vec` of size `length` and initializes the elements to the
+    /// value returned by the closure `op`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec = Vec::from_fn(3, |idx| idx * 2);
+    /// assert_eq!(vec, vec!(0, 2, 4));
+    /// ```
+    pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
+        unsafe {
+            let mut xs = Vec::with_capacity(length);
+            while xs.len < length {
+                mem::overwrite(xs.as_mut_slice().unsafe_mut_ref(xs.len),
+                                   op(xs.len));
+                xs.len += 1;
+            }
+            xs
+        }
+    }
+
+    /// Create a `Vec<T>` directly from the raw constituents.
+    ///
+    /// This is highly unsafe:
+    ///
+    /// - if `ptr` is null, then `length` and `capacity` should be 0
+    /// - `ptr` must point to an allocation of size `capacity`
+    /// - there must be `length` valid instances of type `T` at the
+    ///   beginning of that allocation
+    /// - `ptr` must be allocated by the default `Vec` allocator
+    pub unsafe fn from_raw_parts(length: uint, capacity: uint,
+                                 ptr: *mut T) -> Vec<T> {
+        Vec { len: length, cap: capacity, ptr: ptr }
+    }
+
+    /// Consumes the `Vec`, partitioning it based on a predicate.
+    ///
+    /// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
+    /// satisfy `f` and all elements of `B` do not. The order of elements is
+    /// preserved.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// let (even, odd) = vec.partition(|&n| n % 2 == 0);
+    /// assert_eq!(even, vec!(2, 4));
+    /// assert_eq!(odd, vec!(1, 3));
+    /// ```
+    #[inline]
+    pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+        let mut lefts  = Vec::new();
+        let mut rights = Vec::new();
+
+        for elt in self.move_iter() {
+            if f(&elt) {
+                lefts.push(elt);
+            } else {
+                rights.push(elt);
+            }
+        }
+
+        (lefts, rights)
+    }
+}
+
+impl<T: Clone> Vec<T> {
+    /// Iterates over the `second` vector, copying each element and appending it to
+    /// the `first`. Afterwards, the `first` is then returned for use again.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2);
+    /// let vec = vec.append([3, 4]);
+    /// assert_eq!(vec, vec!(1, 2, 3, 4));
+    /// ```
+    #[inline]
+    pub fn append(mut self, second: &[T]) -> Vec<T> {
+        self.push_all(second);
+        self
+    }
+
+    /// Constructs a `Vec` by cloning elements of a slice.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let slice = [1, 2, 3];
+    /// let vec = Vec::from_slice(slice);
+    /// ```
+    pub fn from_slice(values: &[T]) -> Vec<T> {
+        values.iter().map(|x| x.clone()).collect()
+    }
+
+    /// Constructs a `Vec` with copies of a value.
+    ///
+    /// Creates a `Vec` with `length` copies of `value`.
+    ///
+    /// # Example
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec = Vec::from_elem(3, "hi");
+    /// println!("{}", vec); // prints [hi, hi, hi]
+    /// ```
+    pub fn from_elem(length: uint, value: T) -> Vec<T> {
+        unsafe {
+            let mut xs = Vec::with_capacity(length);
+            while xs.len < length {
+                mem::overwrite(xs.as_mut_slice().unsafe_mut_ref(xs.len),
+                                   value.clone());
+                xs.len += 1;
+            }
+            xs
+        }
+    }
+
+    /// Appends all elements in a slice to the `Vec`.
+    ///
+    /// Iterates over the slice `other`, clones each element, and then appends
+    /// it to this `Vec`. The `other` vector is traversed in-order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1);
+    /// vec.push_all([2, 3, 4]);
+    /// assert_eq!(vec, vec!(1, 2, 3, 4));
+    /// ```
+    #[inline]
+    pub fn push_all(&mut self, other: &[T]) {
+        self.extend(other.iter().map(|e| e.clone()));
+    }
+
+    /// Grows the `Vec` in-place.
+    ///
+    /// Adds `n` copies of `value` to the `Vec`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!("hello");
+    /// vec.grow(2, &("world"));
+    /// assert_eq!(vec, vec!("hello", "world", "world"));
+    /// ```
+    pub fn grow(&mut self, n: uint, value: &T) {
+        let new_len = self.len() + n;
+        self.reserve(new_len);
+        let mut i: uint = 0u;
+
+        while i < n {
+            self.push((*value).clone());
+            i += 1u;
+        }
+    }
+
+    /// Sets the value of a vector element at a given index, growing the vector
+    /// as needed.
+    ///
+    /// Sets the element at position `index` to `value`. If `index` is past the
+    /// end of the vector, expands the vector by replicating `initval` to fill
+    /// the intervening space.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!("a", "b", "c");
+    /// vec.grow_set(1, &("fill"), "d");
+    /// vec.grow_set(4, &("fill"), "e");
+    /// assert_eq!(vec, vec!("a", "d", "c", "fill", "e"));
+    /// ```
+    pub fn grow_set(&mut self, index: uint, initval: &T, value: T) {
+        let l = self.len();
+        if index >= l {
+            self.grow(index - l + 1u, initval);
+        }
+        *self.get_mut(index) = value;
+    }
+
+    /// Partitions a vector based on a predicate.
+    ///
+    /// Clones the elements of the vector, partitioning them into two `Vec`s
+    /// `(A,B)`, where all elements of `A` satisfy `f` and all elements of `B`
+    /// do not. The order of elements is preserved.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// let (even, odd) = vec.partitioned(|&n| n % 2 == 0);
+    /// assert_eq!(even, vec!(2, 4));
+    /// assert_eq!(odd, vec!(1, 3));
+    /// ```
+    pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
+        let mut lefts = Vec::new();
+        let mut rights = Vec::new();
+
+        for elt in self.iter() {
+            if f(elt) {
+                lefts.push(elt.clone());
+            } else {
+                rights.push(elt.clone());
+            }
+        }
+
+        (lefts, rights)
+    }
+}
+
+impl<T:Clone> Clone for Vec<T> {
+    fn clone(&self) -> Vec<T> {
+        let len = self.len;
+        let mut vector = Vec::with_capacity(len);
+        // Unsafe code so this can be optimised to a memcpy (or something
+        // similarly fast) when T is Copy. LLVM is easily confused, so any
+        // extra operations during the loop can prevent this optimisation
+        {
+            let this_slice = self.as_slice();
+            while vector.len < len {
+                unsafe {
+                    mem::overwrite(
+                        vector.as_mut_slice().unsafe_mut_ref(vector.len),
+                        this_slice.unsafe_ref(vector.len).clone());
+                }
+                vector.len += 1;
+            }
+        }
+        vector
+    }
+
+    fn clone_from(&mut self, other: &Vec<T>) {
+        // drop anything in self that will not be overwritten
+        if self.len() > other.len() {
+            self.truncate(other.len())
+        }
+
+        // reuse the contained values' allocations/resources.
+        for (place, thing) in self.mut_iter().zip(other.iter()) {
+            place.clone_from(thing)
+        }
+
+        // self.len <= other.len due to the truncate above, so the
+        // slice here is always in-bounds.
+        let len = self.len();
+        self.extend(other.slice_from(len).iter().map(|x| x.clone()));
+    }
+}
+
+impl<T> FromIterator<T> for Vec<T> {
+    fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
+        let (lower, _) = iterator.size_hint();
+        let mut vector = Vec::with_capacity(lower);
+        for element in iterator {
+            vector.push(element)
+        }
+        vector
+    }
+}
+
+impl<T> Extendable<T> for Vec<T> {
+    fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
+        let (lower, _) = iterator.size_hint();
+        self.reserve_additional(lower);
+        for element in iterator {
+            self.push(element)
+        }
+    }
+}
+
+impl<T: PartialEq> PartialEq for Vec<T> {
+    #[inline]
+    fn eq(&self, other: &Vec<T>) -> bool {
+        self.as_slice() == other.as_slice()
+    }
+}
+
+impl<T: PartialOrd> PartialOrd for Vec<T> {
+    #[inline]
+    fn lt(&self, other: &Vec<T>) -> bool {
+        self.as_slice() < other.as_slice()
+    }
+}
+
+impl<T: Eq> Eq for Vec<T> {}
+
+impl<T: Ord> Ord for Vec<T> {
+    #[inline]
+    fn cmp(&self, other: &Vec<T>) -> Ordering {
+        self.as_slice().cmp(&other.as_slice())
+    }
+}
+
+impl<T> Container for Vec<T> {
+    #[inline]
+    fn len(&self) -> uint {
+        self.len
+    }
+}
+
+// FIXME: #13996: need a way to mark the return value as `noalias`
+#[inline(never)]
+unsafe fn alloc_or_realloc<T>(ptr: *mut T, size: uint, old_size: uint) -> *mut T {
+    if old_size == 0 {
+        allocate(size, mem::min_align_of::<T>()) as *mut T
+    } else {
+        reallocate(ptr as *mut u8, size,
+                   mem::min_align_of::<T>(), old_size) as *mut T
+    }
+}
+
+#[inline]
+unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
+    if mem::size_of::<T>() != 0 {
+        deallocate(ptr as *mut u8,
+                   len * mem::size_of::<T>(),
+                   mem::min_align_of::<T>())
+    }
+}
+
+impl<T> Vec<T> {
+    /// Returns the number of elements the vector can hold without
+    /// reallocating.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let vec: Vec<int> = Vec::with_capacity(10);
+    /// assert_eq!(vec.capacity(), 10);
+    /// ```
+    #[inline]
+    pub fn capacity(&self) -> uint {
+        self.cap
+    }
+
+     /// Reserves capacity for at least `n` additional elements in the given
+     /// vector.
+     ///
+     /// # Failure
+     ///
+     /// Fails if the new capacity overflows `uint`.
+     ///
+     /// # Example
+     ///
+     /// ```rust
+     /// # use std::vec::Vec;
+     /// let mut vec: Vec<int> = vec!(1);
+     /// vec.reserve_additional(10);
+     /// assert!(vec.capacity() >= 11);
+     /// ```
+    pub fn reserve_additional(&mut self, extra: uint) {
+        if self.cap - self.len < extra {
+            match self.len.checked_add(&extra) {
+                None => fail!("Vec::reserve_additional: `uint` overflow"),
+                Some(new_cap) => self.reserve(new_cap)
+            }
+        }
+    }
+
+    /// Reserves capacity for at least `n` elements in the given vector.
+    ///
+    /// This function will over-allocate in order to amortize the allocation
+    /// costs in scenarios where the caller may need to repeatedly reserve
+    /// additional space.
+    ///
+    /// If the capacity for `self` is already equal to or greater than the
+    /// requested capacity, then no action is taken.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.reserve(10);
+    /// assert!(vec.capacity() >= 10);
+    /// ```
+    pub fn reserve(&mut self, capacity: uint) {
+        if capacity >= self.len {
+            self.reserve_exact(num::next_power_of_two(capacity))
+        }
+    }
+
+    /// Reserves capacity for exactly `capacity` elements in the given vector.
+    ///
+    /// If the capacity for `self` is already equal to or greater than the
+    /// requested capacity, then no action is taken.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// # use std::vec::Vec;
+    /// let mut vec: Vec<int> = Vec::with_capacity(10);
+    /// vec.reserve_exact(11);
+    /// assert_eq!(vec.capacity(), 11);
+    /// ```
+    pub fn reserve_exact(&mut self, capacity: uint) {
+        if mem::size_of::<T>() == 0 { return }
+
+        if capacity > self.cap {
+            let size = ::expect(capacity.checked_mul(&mem::size_of::<T>()),
+                                "capacity overflow");
+            unsafe {
+                self.ptr = alloc_or_realloc(self.ptr, size,
+                                            self.cap * mem::size_of::<T>());
+            }
+            self.cap = capacity;
+        }
+    }
+
+    /// Shrink the capacity of the vector as much as possible
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.shrink_to_fit();
+    /// ```
+    pub fn shrink_to_fit(&mut self) {
+        if mem::size_of::<T>() == 0 { return }
+
+        if self.len == 0 {
+            if self.cap != 0 {
+                unsafe {
+                    dealloc(self.ptr, self.cap)
+                }
+                self.cap = 0;
+            }
+        } else {
+            unsafe {
+                // Overflow check is unnecessary as the vector is already at
+                // least this large.
+                self.ptr = reallocate(self.ptr as *mut u8,
+                                      self.len * mem::size_of::<T>(),
+                                      mem::min_align_of::<T>(),
+                                      self.cap * mem::size_of::<T>()) as *mut T;
+            }
+            self.cap = self.len;
+        }
+    }
+
+    /// Remove the last element from a vector and return it, or `None` if it is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// assert_eq!(vec.pop(), Some(3));
+    /// assert_eq!(vec, vec!(1, 2));
+    /// ```
+    #[inline]
+    pub fn pop(&mut self) -> Option<T> {
+        if self.len == 0 {
+            None
+        } else {
+            unsafe {
+                self.len -= 1;
+                Some(ptr::read(self.as_slice().unsafe_ref(self.len())))
+            }
+        }
+    }
+
+    /// Append an element to a vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the number of elements in the vector overflows a `uint`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2);
+    /// vec.push(3);
+    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// ```
+    #[inline]
+    pub fn push(&mut self, value: T) {
+        if mem::size_of::<T>() == 0 {
+            // zero-size types consume no memory, so we can't rely on the address space running out
+            self.len = ::expect(self.len.checked_add(&1), "length overflow");
+            unsafe { mem::forget(value); }
+            return
+        }
+        if self.len == self.cap {
+            let old_size = self.cap * mem::size_of::<T>();
+            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
+            if old_size > size { fail!("capacity overflow") }
+            unsafe {
+                self.ptr = alloc_or_realloc(self.ptr, size,
+                                            self.cap * mem::size_of::<T>());
+            }
+            self.cap = max(self.cap, 2) * 2;
+        }
+
+        unsafe {
+            let end = (self.ptr as *T).offset(self.len as int) as *mut T;
+            mem::overwrite(&mut *end, value);
+            self.len += 1;
+        }
+    }
+
+    /// Appends one element to the vector provided. The vector itself is then
+    /// returned for use again.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2);
+    /// let vec = vec.append_one(3);
+    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// ```
+    #[inline]
+    pub fn append_one(mut self, x: T) -> Vec<T> {
+        self.push(x);
+        self
+    }
+
+    /// Shorten a vector, dropping excess elements.
+    ///
+    /// If `len` is greater than the vector's current length, this has no
+    /// effect.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4);
+    /// vec.truncate(2);
+    /// assert_eq!(vec, vec!(1, 2));
+    /// ```
+    pub fn truncate(&mut self, len: uint) {
+        unsafe {
+            // drop any extra elements
+            while len < self.len {
+                // decrement len before the read(), so a failure on Drop doesn't
+                // re-drop the just-failed value.
+                self.len -= 1;
+                ptr::read(self.as_slice().unsafe_ref(self.len));
+            }
+        }
+    }
+
+    /// Work with `self` as a mutable slice.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// fn foo(slice: &mut [int]) {}
+    ///
+    /// let mut vec = vec!(1, 2);
+    /// foo(vec.as_mut_slice());
+    /// ```
+    #[inline]
+    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
+        unsafe {
+            mem::transmute(Slice { data: self.as_mut_ptr() as *T, len: self.len })
+        }
+    }
+
+    /// Creates a consuming iterator, that is, one that moves each
+    /// value out of the vector (from start to end). The vector cannot
+    /// be used after calling this.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let v = vec!("a".to_string(), "b".to_string());
+    /// for s in v.move_iter() {
+    ///     // s has type String, not &String
+    ///     println!("{}", s);
+    /// }
+    /// ```
+    #[inline]
+    pub fn move_iter(self) -> MoveItems<T> {
+        unsafe {
+            let iter = mem::transmute(self.as_slice().iter());
+            let ptr = self.ptr;
+            let cap = self.cap;
+            mem::forget(self);
+            MoveItems { allocation: ptr, cap: cap, iter: iter }
+        }
+    }
+
+
+    /// Sets the length of a vector.
+    ///
+    /// This will explicitly set the size of the vector, without actually
+    /// modifying its buffers, so it is up to the caller to ensure that the
+    /// vector is actually the specified size.
+    #[inline]
+    pub unsafe fn set_len(&mut self, len: uint) {
+        self.len = len;
+    }
+
+    /// Returns a reference to the value at index `index`.
+    ///
+    /// # Failure
+    ///
+    /// Fails if `index` is out of bounds
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.get(1) == &2);
+    /// ```
+    #[inline]
+    pub fn get<'a>(&'a self, index: uint) -> &'a T {
+        &self.as_slice()[index]
+    }
+
+    /// Returns a mutable reference to the value at index `index`.
+    ///
+    /// # Failure
+    ///
+    /// Fails if `index` is out of bounds
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// *vec.get_mut(1) = 4;
+    /// assert_eq!(vec, vec!(1, 4, 3));
+    /// ```
+    #[inline]
+    pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T {
+        &mut self.as_mut_slice()[index]
+    }
+
+    /// Returns an iterator over references to the elements of the vector in
+    /// order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// for num in vec.iter() {
+    ///     println!("{}", *num);
+    /// }
+    /// ```
+    #[inline]
+    pub fn iter<'a>(&'a self) -> Items<'a,T> {
+        self.as_slice().iter()
+    }
+
+
+    /// Returns an iterator over mutable references to the elements of the
+    /// vector in order.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// for num in vec.mut_iter() {
+    ///     *num = 0;
+    /// }
+    /// ```
+    #[inline]
+    pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a,T> {
+        self.as_mut_slice().mut_iter()
+    }
+
+    /// Sort the vector, in place, using `compare` to compare elements.
+    ///
+    /// This sort is `O(n log n)` worst-case and stable, but allocates
+    /// approximately `2 * n`, where `n` is the length of `self`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = vec!(5i, 4, 1, 3, 2);
+    /// v.sort_by(|a, b| a.cmp(b));
+    /// assert_eq!(v, vec!(1, 2, 3, 4, 5));
+    ///
+    /// // reverse sorting
+    /// v.sort_by(|a, b| b.cmp(a));
+    /// assert_eq!(v, vec!(5, 4, 3, 2, 1));
+    /// ```
+    #[inline]
+    pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
+        self.as_mut_slice().sort_by(compare)
+    }
+
+    /// Returns a slice of `self` between `start` and `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` or `end` point outside the bounds of `self`, or when
+    /// `start` > `end`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.slice(0, 2) == [1, 2]);
+    /// ```
+    #[inline]
+    pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] {
+        self.as_slice().slice(start, end)
+    }
+
+    /// Returns a slice containing all but the first element of the vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails when the vector is empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.tail() == [2, 3]);
+    /// ```
+    #[inline]
+    pub fn tail<'a>(&'a self) -> &'a [T] {
+        self.as_slice().tail()
+    }
+
+    /// Returns all but the first `n' elements of a vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails when there are fewer than `n` elements in the vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.tailn(2) == [3, 4]);
+    /// ```
+    #[inline]
+    pub fn tailn<'a>(&'a self, n: uint) -> &'a [T] {
+        self.as_slice().tailn(n)
+    }
+
+    /// Returns a reference to the last element of a vector, or `None` if it is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.last() == Some(&3));
+    /// ```
+    #[inline]
+    pub fn last<'a>(&'a self) -> Option<&'a T> {
+        self.as_slice().last()
+    }
+
+    /// Returns a mutable reference to the last element of a vector, or `None`
+    /// if it is empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// *vec.mut_last().unwrap() = 4;
+    /// assert_eq!(vec, vec!(1, 2, 4));
+    /// ```
+    #[inline]
+    pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> {
+        self.as_mut_slice().mut_last()
+    }
+
+    /// Remove an element from anywhere in the vector and return it, replacing
+    /// it with the last element. This does not preserve ordering, but is O(1).
+    ///
+    /// Returns `None` if `index` is out of bounds.
+    ///
+    /// # Example
+    /// ```rust
+    /// let mut v = vec!("foo".to_string(), "bar".to_string(),
+    ///                  "baz".to_string(), "qux".to_string());
+    ///
+    /// assert_eq!(v.swap_remove(1), Some("bar".to_string()));
+    /// assert_eq!(v, vec!("foo".to_string(), "qux".to_string(), "baz".to_string()));
+    ///
+    /// assert_eq!(v.swap_remove(0), Some("foo".to_string()));
+    /// assert_eq!(v, vec!("baz".to_string(), "qux".to_string()));
+    ///
+    /// assert_eq!(v.swap_remove(2), None);
+    /// ```
+    #[inline]
+    pub fn swap_remove(&mut self, index: uint) -> Option<T> {
+        let length = self.len();
+        if index < length - 1 {
+            self.as_mut_slice().swap(index, length - 1);
+        } else if index >= length {
+            return None
+        }
+        self.pop()
+    }
+
+    /// Prepend an element to the vector.
+    ///
+    /// # Warning
+    ///
+    /// This is an O(n) operation as it requires copying every element in the
+    /// vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.unshift(4);
+    /// assert_eq!(vec, vec!(4, 1, 2, 3));
+    /// ```
+    #[inline]
+    pub fn unshift(&mut self, element: T) {
+        self.insert(0, element)
+    }
+
+    /// Removes the first element from a vector and returns it, or `None` if
+    /// the vector is empty.
+    ///
+    /// # Warning
+    ///
+    /// This is an O(n) operation as it requires copying every element in the
+    /// vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// assert!(vec.shift() == Some(1));
+    /// assert_eq!(vec, vec!(2, 3));
+    /// ```
+    #[inline]
+    pub fn shift(&mut self) -> Option<T> {
+        self.remove(0)
+    }
+
+    /// Insert an element at position `index` within the vector, shifting all
+    /// elements after position i one position to the right.
+    ///
+    /// # Failure
+    ///
+    /// Fails if `index` is out of bounds of the vector.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3);
+    /// vec.insert(1, 4);
+    /// assert_eq!(vec, vec!(1, 4, 2, 3));
+    /// ```
+    pub fn insert(&mut self, index: uint, element: T) {
+        let len = self.len();
+        assert!(index <= len);
+        // space for the new element
+        self.reserve(len + 1);
+
+        unsafe { // infallible
+            // The spot to put the new value
+            {
+                let p = self.as_mut_ptr().offset(index as int);
+                // Shift everything over to make space. (Duplicating the
+                // `index`th element into two consecutive places.)
+                ptr::copy_memory(p.offset(1), &*p, len - index);
+                // Write it in, overwriting the first copy of the `index`th
+                // element.
+                mem::overwrite(&mut *p, element);
+            }
+            self.set_len(len + 1);
+        }
+    }
+
+    /// Remove and return the element at position `index` within the vector,
+    /// shifting all elements after position `index` one position to the left.
+    /// Returns `None` if `i` is out of bounds.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = vec!(1, 2, 3);
+    /// assert_eq!(v.remove(1), Some(2));
+    /// assert_eq!(v, vec!(1, 3));
+    ///
+    /// assert_eq!(v.remove(4), None);
+    /// // v is unchanged:
+    /// assert_eq!(v, vec!(1, 3));
+    /// ```
+    pub fn remove(&mut self, index: uint) -> Option<T> {
+        let len = self.len();
+        if index < len {
+            unsafe { // infallible
+                let ret;
+                {
+                    // the place we are taking from.
+                    let ptr = self.as_mut_ptr().offset(index as int);
+                    // copy it out, unsafely having a copy of the value on
+                    // the stack and in the vector at the same time.
+                    ret = Some(ptr::read(ptr as *T));
+
+                    // Shift everything down to fill in that spot.
+                    ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
+                }
+                self.set_len(len - 1);
+                ret
+            }
+        } else {
+            None
+        }
+    }
+
+    /// Takes ownership of the vector `other`, moving all elements into
+    /// the current vector. This does not copy any elements, and it is
+    /// illegal to use the `other` vector after calling this method
+    /// (because it is moved here).
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(box 1);
+    /// vec.push_all_move(vec!(box 2, box 3, box 4));
+    /// assert_eq!(vec, vec!(box 1, box 2, box 3, box 4));
+    /// ```
+    pub fn push_all_move(&mut self, other: Vec<T>) {
+        self.extend(other.move_iter());
+    }
+
+    /// Returns a mutable slice of `self` between `start` and `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` or `end` point outside the bounds of `self`, or when
+    /// `start` > `end`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.mut_slice(0, 2) == [1, 2]);
+    /// ```
+    #[inline]
+    pub fn mut_slice<'a>(&'a mut self, start: uint, end: uint)
+                         -> &'a mut [T] {
+        self.as_mut_slice().mut_slice(start, end)
+    }
+
+    /// Returns a mutable slice of self from `start` to the end of the vec.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` points outside the bounds of self.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.mut_slice_from(2) == [3, 4]);
+    /// ```
+    #[inline]
+    pub fn mut_slice_from<'a>(&'a mut self, start: uint) -> &'a mut [T] {
+        self.as_mut_slice().mut_slice_from(start)
+    }
+
+    /// Returns a mutable slice of self from the start of the vec to `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `end` points outside the bounds of self.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4);
+    /// assert!(vec.mut_slice_to(2) == [1, 2]);
+    /// ```
+    #[inline]
+    pub fn mut_slice_to<'a>(&'a mut self, end: uint) -> &'a mut [T] {
+        self.as_mut_slice().mut_slice_to(end)
+    }
+
+    /// Returns a pair of mutable slices that divides the vec at an index.
+    ///
+    /// The first will contain all indices from `[0, mid)` (excluding
+    /// the index `mid` itself) and the second will contain all
+    /// indices from `[mid, len)` (excluding the index `len` itself).
+    ///
+    /// # Failure
+    ///
+    /// Fails if `mid > len`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 3, 4, 5, 6);
+    ///
+    /// // scoped to restrict the lifetime of the borrows
+    /// {
+    ///    let (left, right) = vec.mut_split_at(0);
+    ///    assert!(left == &mut []);
+    ///    assert!(right == &mut [1, 2, 3, 4, 5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = vec.mut_split_at(2);
+    ///     assert!(left == &mut [1, 2]);
+    ///     assert!(right == &mut [3, 4, 5, 6]);
+    /// }
+    ///
+    /// {
+    ///     let (left, right) = vec.mut_split_at(6);
+    ///     assert!(left == &mut [1, 2, 3, 4, 5, 6]);
+    ///     assert!(right == &mut []);
+    /// }
+    /// ```
+    #[inline]
+    pub fn mut_split_at<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
+        self.as_mut_slice().mut_split_at(mid)
+    }
+
+    /// Reverse the order of elements in a vector, in place.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut v = vec!(1, 2, 3);
+    /// v.reverse();
+    /// assert_eq!(v, vec!(3, 2, 1));
+    /// ```
+    #[inline]
+    pub fn reverse(&mut self) {
+        self.as_mut_slice().reverse()
+    }
+
+    /// Returns a slice of `self` from `start` to the end of the vec.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `start` points outside the bounds of self.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.slice_from(1) == [2, 3]);
+    /// ```
+    #[inline]
+    pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] {
+        self.as_slice().slice_from(start)
+    }
+
+    /// Returns a slice of self from the start of the vec to `end`.
+    ///
+    /// # Failure
+    ///
+    /// Fails when `end` points outside the bounds of self.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.slice_to(2) == [1, 2]);
+    /// ```
+    #[inline]
+    pub fn slice_to<'a>(&'a self, end: uint) -> &'a [T] {
+        self.as_slice().slice_to(end)
+    }
+
+    /// Returns a slice containing all but the last element of the vector.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the vector is empty
+    #[inline]
+    pub fn init<'a>(&'a self) -> &'a [T] {
+        self.slice(0, self.len() - 1)
+    }
+
+
+    /// Returns an unsafe pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the vector may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
+    #[inline]
+    pub fn as_ptr(&self) -> *T {
+        // If we have a 0-sized vector, then the base pointer should not be NULL
+        // because an iterator over the slice will attempt to yield the base
+        // pointer as the first element in the vector, but this will end up
+        // being Some(NULL) which is optimized to None.
+        if mem::size_of::<T>() == 0 {
+            1 as *T
+        } else {
+            self.ptr as *T
+        }
+    }
+
+    /// Returns a mutable unsafe pointer to the vector's buffer.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up pointing to garbage.
+    ///
+    /// Modifying the vector may cause its buffer to be reallocated, which
+    /// would also make any pointers to it invalid.
+    #[inline]
+    pub fn as_mut_ptr(&mut self) -> *mut T {
+        // see above for the 0-size check
+        if mem::size_of::<T>() == 0 {
+            1 as *mut T
+        } else {
+            self.ptr
+        }
+    }
+
+    /// Retains only the elements specified by the predicate.
+    ///
+    /// In other words, remove all elements `e` such that `f(&e)` returns false.
+    /// This method operates in place and preserves the order the retained elements.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1i, 2, 3, 4);
+    /// vec.retain(|x| x%2 == 0);
+    /// assert_eq!(vec, vec!(2, 4));
+    /// ```
+    pub fn retain(&mut self, f: |&T| -> bool) {
+        let len = self.len();
+        let mut del = 0u;
+        {
+            let v = self.as_mut_slice();
+
+            for i in range(0u, len) {
+                if !f(&v[i]) {
+                    del += 1;
+                } else if del > 0 {
+                    v.swap(i-del, i);
+                }
+            }
+        }
+        if del > 0 {
+            self.truncate(len - del);
+        }
+    }
+
+    /// Expands a vector in place, initializing the new elements to the result of a function.
+    ///
+    /// The vector is grown by `n` elements. The i-th new element are initialized to the value
+    /// returned by `f(i)` where `i` is in the range [0, n).
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(0u, 1);
+    /// vec.grow_fn(3, |i| i);
+    /// assert_eq!(vec, vec!(0, 1, 0, 1, 2));
+    /// ```
+    pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) {
+        self.reserve_additional(n);
+        for i in range(0u, n) {
+            self.push(f(i));
+        }
+    }
+}
+
+impl<T:Ord> Vec<T> {
+    /// Sorts the vector in place.
+    ///
+    /// This sort is `O(n log n)` worst-case and stable, but allocates
+    /// approximately `2 * n`, where `n` is the length of `self`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(3i, 1, 2);
+    /// vec.sort();
+    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// ```
+    pub fn sort(&mut self) {
+        self.as_mut_slice().sort()
+    }
+}
+
+impl<T> Mutable for Vec<T> {
+    #[inline]
+    fn clear(&mut self) {
+        self.truncate(0)
+    }
+}
+
+impl<T:PartialEq> Vec<T> {
+    /// Return true if a vector contains an element with the given value
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let vec = vec!(1, 2, 3);
+    /// assert!(vec.contains(&1));
+    /// ```
+    pub fn contains(&self, x: &T) -> bool {
+        self.as_slice().contains(x)
+    }
+
+    /// Remove consecutive repeated elements in the vector.
+    ///
+    /// If the vector is sorted, this removes all duplicates.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1, 2, 2, 3, 2);
+    /// vec.dedup();
+    /// assert_eq!(vec, vec!(1, 2, 3, 2));
+    /// ```
+    pub fn dedup(&mut self) {
+        unsafe {
+            // Although we have a mutable reference to `self`, we cannot make
+            // *arbitrary* changes. The `PartialEq` comparisons could fail, so we
+            // must ensure that the vector is in a valid state at all time.
+            //
+            // The way that we handle this is by using swaps; we iterate
+            // over all the elements, swapping as we go so that at the end
+            // the elements we wish to keep are in the front, and those we
+            // wish to reject are at the back. We can then truncate the
+            // vector. This operation is still O(n).
+            //
+            // Example: We start in this state, where `r` represents "next
+            // read" and `w` represents "next_write`.
+            //
+            //           r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 1 | 2 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //           w
+            //
+            // Comparing self[r] against self[w-1], this is not a duplicate, so
+            // we swap self[r] and self[w] (no effect as r==w) and then increment both
+            // r and w, leaving us with:
+            //
+            //               r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 1 | 2 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //               w
+            //
+            // Comparing self[r] against self[w-1], this value is a duplicate,
+            // so we increment `r` but leave everything else unchanged:
+            //
+            //                   r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 1 | 2 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //               w
+            //
+            // Comparing self[r] against self[w-1], this is not a duplicate,
+            // so swap self[r] and self[w] and advance r and w:
+            //
+            //                       r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 2 | 1 | 3 | 3 |
+            //     +---+---+---+---+---+---+
+            //                   w
+            //
+            // Not a duplicate, repeat:
+            //
+            //                           r
+            //     +---+---+---+---+---+---+
+            //     | 0 | 1 | 2 | 3 | 1 | 3 |
+            //     +---+---+---+---+---+---+
+            //                       w
+            //
+            // Duplicate, advance r. End of vec. Truncate to w.
+
+            let ln = self.len();
+            if ln < 1 { return; }
+
+            // Avoid bounds checks by using unsafe pointers.
+            let p = self.as_mut_slice().as_mut_ptr();
+            let mut r = 1;
+            let mut w = 1;
+
+            while r < ln {
+                let p_r = p.offset(r as int);
+                let p_wm1 = p.offset((w - 1) as int);
+                if *p_r != *p_wm1 {
+                    if r != w {
+                        let p_w = p_wm1.offset(1);
+                        mem::swap(&mut *p_r, &mut *p_w);
+                    }
+                    w += 1;
+                }
+                r += 1;
+            }
+
+            self.truncate(w);
+        }
+    }
+}
+
+impl<T> Vector<T> for Vec<T> {
+    /// Work with `self` as a slice.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// fn foo(slice: &[int]) {}
+    ///
+    /// let vec = vec!(1, 2);
+    /// foo(vec.as_slice());
+    /// ```
+    #[inline]
+    fn as_slice<'a>(&'a self) -> &'a [T] {
+        unsafe { mem::transmute(Slice { data: self.as_ptr(), len: self.len }) }
+    }
+}
+
+impl<T: Clone, V: Vector<T>> Add<V, Vec<T>> for Vec<T> {
+    #[inline]
+    fn add(&self, rhs: &V) -> Vec<T> {
+        let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
+        res.push_all(self.as_slice());
+        res.push_all(rhs.as_slice());
+        res
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for Vec<T> {
+    fn drop(&mut self) {
+        // This is (and should always remain) a no-op if the fields are
+        // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
+        if self.cap != 0 {
+            unsafe {
+                for x in self.as_mut_slice().iter() {
+                    ptr::read(x);
+                }
+                dealloc(self.ptr, self.cap)
+            }
+        }
+    }
+}
+
+impl<T> Default for Vec<T> {
+    fn default() -> Vec<T> {
+        Vec::new()
+    }
+}
+
+impl<T:fmt::Show> fmt::Show for Vec<T> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        self.as_slice().fmt(f)
+    }
+}
+
+/// An iterator that moves out of a vector.
+pub struct MoveItems<T> {
+    allocation: *mut T, // the block of memory allocated for the vector
+    cap: uint, // the capacity of the vector
+    iter: Items<'static, T>
+}
+
+impl<T> Iterator<T> for MoveItems<T> {
+    #[inline]
+    fn next(&mut self) -> Option<T> {
+        unsafe {
+            self.iter.next().map(|x| ptr::read(x))
+        }
+    }
+
+    #[inline]
+    fn size_hint(&self) -> (uint, Option<uint>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<T> DoubleEndedIterator<T> for MoveItems<T> {
+    #[inline]
+    fn next_back(&mut self) -> Option<T> {
+        unsafe {
+            self.iter.next_back().map(|x| ptr::read(x))
+        }
+    }
+}
+
+#[unsafe_destructor]
+impl<T> Drop for MoveItems<T> {
+    fn drop(&mut self) {
+        // destroy the remaining elements
+        if self.cap != 0 {
+            for _x in *self {}
+            unsafe {
+                dealloc(self.allocation, self.cap);
+            }
+        }
+    }
+}
+
+/**
+ * Convert an iterator of pairs into a pair of vectors.
+ *
+ * Returns a tuple containing two vectors where the i-th element of the first
+ * vector contains the first element of the i-th tuple of the input iterator,
+ * and the i-th element of the second vector contains the second element
+ * of the i-th tuple of the input iterator.
+ */
+pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
+    let (lo, _) = iter.size_hint();
+    let mut ts = Vec::with_capacity(lo);
+    let mut us = Vec::with_capacity(lo);
+    for (t, u) in iter {
+        ts.push(t);
+        us.push(u);
+    }
+    (ts, us)
+}
+
+/// Mechanism to convert from a `Vec<T>` to a `[T]`.
+///
+/// In a post-DST world this will be used to convert to any `Ptr<[T]>`.
+///
+/// This could be implemented on more types than just pointers to vectors, but
+/// the recommended approach for those types is to implement `FromIterator`.
+// FIXME(#12938): Update doc comment when DST lands
+pub trait FromVec<T> {
+    /// Convert a `Vec<T>` into the receiver type.
+    fn from_vec(v: Vec<T>) -> Self;
+}
+
+impl<T> FromVec<T> for ~[T] {
+    fn from_vec(mut v: Vec<T>) -> ~[T] {
+        let len = v.len();
+        let data_size = len.checked_mul(&mem::size_of::<T>());
+        let data_size = ::expect(data_size, "overflow in from_vec()");
+        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
+        let size = ::expect(size, "overflow in from_vec()");
+
+        // In a post-DST world, we can attempt to reuse the Vec allocation by calling
+        // shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no
+        // diffrent than what we're doing manually here.
+
+        let vp = v.as_mut_ptr();
+
+        unsafe {
+            let ret = allocate(size, 8) as *mut RawVec<()>;
+
+            let a_size = mem::size_of::<T>();
+            let a_size = if a_size == 0 {1} else {a_size};
+            (*ret).fill = len * a_size;
+            (*ret).alloc = len * a_size;
+
+            ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
+                                            vp as *u8, data_size);
+
+            // we've transferred ownership of the contents from v, but we can't drop it
+            // as it still needs to free its own allocation.
+            v.set_len(0);
+
+            mem::transmute(ret)
+        }
+    }
+}
+
+/// Unsafe operations
+pub mod raw {
+    use super::Vec;
+    use core::ptr;
+
+    /// Constructs a vector from an unsafe pointer to a buffer.
+    ///
+    /// The elements of the buffer are copied into the vector without cloning,
+    /// as if `ptr::read()` were called on them.
+    #[inline]
+    pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> Vec<T> {
+        let mut dst = Vec::with_capacity(elts);
+        dst.set_len(elts);
+        ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
+        dst
+    }
+}
+
+
+#[cfg(test)]
+mod tests {
+    use prelude::*;
+    use mem::size_of;
+    use kinds::marker;
+    use super::{unzip, raw, FromVec};
+
+    #[test]
+    fn test_small_vec_struct() {
+        assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
+    }
+
+    #[test]
+    fn test_double_drop() {
+        struct TwoVec<T> {
+            x: Vec<T>,
+            y: Vec<T>
+        }
+
+        struct DropCounter<'a> {
+            count: &'a mut int
+        }
+
+        #[unsafe_destructor]
+        impl<'a> Drop for DropCounter<'a> {
+            fn drop(&mut self) {
+                *self.count += 1;
+            }
+        }
+
+        let mut count_x @ mut count_y = 0;
+        {
+            let mut tv = TwoVec {
+                x: Vec::new(),
+                y: Vec::new()
+            };
+            tv.x.push(DropCounter {count: &mut count_x});
+            tv.y.push(DropCounter {count: &mut count_y});
+
+            // If Vec had a drop flag, here is where it would be zeroed.
+            // Instead, it should rely on its internal state to prevent
+            // doing anything significant when dropped multiple times.
+            drop(tv.x);
+
+            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
+        }
+
+        assert_eq!(count_x, 1);
+        assert_eq!(count_y, 1);
+    }
+
+    #[test]
+    fn test_reserve_additional() {
+        let mut v = Vec::new();
+        assert_eq!(v.capacity(), 0);
+
+        v.reserve_additional(2);
+        assert!(v.capacity() >= 2);
+
+        for i in range(0, 16) {
+            v.push(i);
+        }
+
+        assert!(v.capacity() >= 16);
+        v.reserve_additional(16);
+        assert!(v.capacity() >= 32);
+
+        v.push(16);
+
+        v.reserve_additional(16);
+        assert!(v.capacity() >= 33)
+    }
+
+    #[test]
+    fn test_extend() {
+        let mut v = Vec::new();
+        let mut w = Vec::new();
+
+        v.extend(range(0, 3));
+        for i in range(0, 3) { w.push(i) }
+
+        assert_eq!(v, w);
+
+        v.extend(range(3, 10));
+        for i in range(3, 10) { w.push(i) }
+
+        assert_eq!(v, w);
+    }
+
+    #[test]
+    fn test_mut_slice_from() {
+        let mut values = Vec::from_slice([1u8,2,3,4,5]);
+        {
+            let slice = values.mut_slice_from(2);
+            assert!(slice == [3, 4, 5]);
+            for p in slice.mut_iter() {
+                *p += 2;
+            }
+        }
+
+        assert!(values.as_slice() == [1, 2, 5, 6, 7]);
+    }
+
+    #[test]
+    fn test_mut_slice_to() {
+        let mut values = Vec::from_slice([1u8,2,3,4,5]);
+        {
+            let slice = values.mut_slice_to(2);
+            assert!(slice == [1, 2]);
+            for p in slice.mut_iter() {
+                *p += 1;
+            }
+        }
+
+        assert!(values.as_slice() == [2, 3, 3, 4, 5]);
+    }
+
+    #[test]
+    fn test_mut_split_at() {
+        let mut values = Vec::from_slice([1u8,2,3,4,5]);
+        {
+            let (left, right) = values.mut_split_at(2);
+            assert!(left.slice(0, left.len()) == [1, 2]);
+            for p in left.mut_iter() {
+                *p += 1;
+            }
+
+            assert!(right.slice(0, right.len()) == [3, 4, 5]);
+            for p in right.mut_iter() {
+                *p += 2;
+            }
+        }
+
+        assert!(values == Vec::from_slice([2u8, 3, 5, 6, 7]));
+    }
+
+    #[test]
+    fn test_clone() {
+        let v: Vec<int> = vec!();
+        let w = vec!(1, 2, 3);
+
+        assert_eq!(v, v.clone());
+
+        let z = w.clone();
+        assert_eq!(w, z);
+        // they should be disjoint in memory.
+        assert!(w.as_ptr() != z.as_ptr())
+    }
+
+    #[test]
+    fn test_clone_from() {
+        let mut v = vec!();
+        let three = vec!(box 1, box 2, box 3);
+        let two = vec!(box 4, box 5);
+        // zero, long
+        v.clone_from(&three);
+        assert_eq!(v, three);
+
+        // equal
+        v.clone_from(&three);
+        assert_eq!(v, three);
+
+        // long, short
+        v.clone_from(&two);
+        assert_eq!(v, two);
+
+        // short, long
+        v.clone_from(&three);
+        assert_eq!(v, three)
+    }
+
+    #[test]
+    fn test_grow_fn() {
+        let mut v = Vec::from_slice([0u, 1]);
+        v.grow_fn(3, |i| i);
+        assert!(v == Vec::from_slice([0u, 1, 0, 1, 2]));
+    }
+
+    #[test]
+    fn test_retain() {
+        let mut vec = Vec::from_slice([1u, 2, 3, 4]);
+        vec.retain(|x| x%2 == 0);
+        assert!(vec == Vec::from_slice([2u, 4]));
+    }
+
+    #[test]
+    fn zero_sized_values() {
+        let mut v = Vec::new();
+        assert_eq!(v.len(), 0);
+        v.push(());
+        assert_eq!(v.len(), 1);
+        v.push(());
+        assert_eq!(v.len(), 2);
+        assert_eq!(v.pop(), Some(()));
+        assert_eq!(v.pop(), Some(()));
+        assert_eq!(v.pop(), None);
+
+        assert_eq!(v.iter().len(), 0);
+        v.push(());
+        assert_eq!(v.iter().len(), 1);
+        v.push(());
+        assert_eq!(v.iter().len(), 2);
+
+        for &() in v.iter() {}
+
+        assert_eq!(v.mut_iter().len(), 2);
+        v.push(());
+        assert_eq!(v.mut_iter().len(), 3);
+        v.push(());
+        assert_eq!(v.mut_iter().len(), 4);
+
+        for &() in v.mut_iter() {}
+        unsafe { v.set_len(0); }
+        assert_eq!(v.mut_iter().len(), 0);
+    }
+
+    #[test]
+    fn test_partition() {
+        assert_eq!(vec![].partition(|x: &int| *x < 3), (vec![], vec![]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_partitioned() {
+        assert_eq!(vec![].partitioned(|x: &int| *x < 3), (vec![], vec![]))
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
+        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
+    }
+
+    #[test]
+    fn test_zip_unzip() {
+        let z1 = vec![(1, 4), (2, 5), (3, 6)];
+
+        let (left, right) = unzip(z1.iter().map(|&x| x));
+
+        let (left, right) = (left.as_slice(), right.as_slice());
+        assert_eq!((1, 4), (left[0], right[0]));
+        assert_eq!((2, 5), (left[1], right[1]));
+        assert_eq!((3, 6), (left[2], right[2]));
+    }
+
+    #[test]
+    fn test_unsafe_ptrs() {
+        unsafe {
+            // Test on-stack copy-from-buf.
+            let a = [1, 2, 3];
+            let ptr = a.as_ptr();
+            let b = raw::from_buf(ptr, 3u);
+            assert_eq!(b, vec![1, 2, 3]);
+
+            // Test on-heap copy-from-buf.
+            let c = box [1, 2, 3, 4, 5];
+            let ptr = c.as_ptr();
+            let d = raw::from_buf(ptr, 5u);
+            assert_eq!(d, vec![1, 2, 3, 4, 5]);
+        }
+    }
+
+    #[test]
+    fn test_from_vec() {
+        let a = vec![1u, 2, 3];
+        let b: ~[uint] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &[1u, 2, 3]);
+
+        let a = vec![];
+        let b: ~[u8] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &[]);
+
+        let a = vec!["one".to_string(), "two".to_string()];
+        let b: ~[String] = FromVec::from_vec(a);
+        assert_eq!(b.as_slice(), &["one".to_string(), "two".to_string()]);
+
+        struct Foo {
+            x: uint,
+            nocopy: marker::NoCopy
+        }
+
+        let a = vec![Foo{x: 42, nocopy: marker::NoCopy}, Foo{x: 84, nocopy: marker::NoCopy}];
+        let b: ~[Foo] = FromVec::from_vec(a);
+        assert_eq!(b.len(), 2);
+        assert_eq!(b[0].x, 42);
+        assert_eq!(b[1].x, 84);
+    }
+
+    #[test]
+    fn test_vec_truncate_drop() {
+        static mut drops: uint = 0;
+        struct Elem(int);
+        impl Drop for Elem {
+            fn drop(&mut self) {
+                unsafe { drops += 1; }
+            }
+        }
+
+        let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
+        assert_eq!(unsafe { drops }, 0);
+        v.truncate(3);
+        assert_eq!(unsafe { drops }, 2);
+        v.truncate(0);
+        assert_eq!(unsafe { drops }, 5);
+    }
+
+    #[test]
+    #[should_fail]
+    fn test_vec_truncate_fail() {
+        struct BadElem(int);
+        impl Drop for BadElem {
+            fn drop(&mut self) {
+                let BadElem(ref mut x) = *self;
+                if *x == 0xbadbeef {
+                    fail!("BadElem failure: 0xbadbeef")
+                }
+            }
+        }
+
+        let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
+        v.truncate(0);
+    }
+}
index f6c438698b488a43f2b847d422477e9ec71836c3..eef133181e1298352407f9da53ecbba7ad93c006 100644 (file)
@@ -61,9 +61,7 @@
 //! types to reintroduce mutability:
 //!
 //! ```
-//! extern crate collections;
-//!
-//! use collections::HashMap;
+//! use std::collections::HashMap;
 //! use std::cell::RefCell;
 //! use std::rc::Rc;
 //!
@@ -86,8 +84,6 @@
 //! to take `&self`.
 //!
 //! ```
-//! extern crate collections;
-//!
 //! use std::cell::RefCell;
 //!
 //! struct Graph {
index f41efdbc1db6f131390a5dd296170d74b19bcbc2..2cce68d5f60f2c33198b153fbbfeff78f425eeef 100644 (file)
 pub use self::num::Radix;
 pub use self::num::RadixFmt;
 
-macro_rules! write(
-    ($dst:expr, $($arg:tt)*) => ({
-        format_args!(|args| { $dst.write_fmt(args) }, $($arg)*)
-    })
-)
-
 mod num;
 mod float;
 pub mod rt;
index 6474c5e37a44b46cb6930a35fef275ee3f085526..94901aff001c00b46d8d4af54b4adb77156408d0 100644 (file)
@@ -54,7 +54,18 @@ macro_rules! assert(
     );
 )
 
+/// Runtime assertion, only without `--cfg ndebug`
+#[macro_export]
+macro_rules! debug_assert(
+    ($(a:tt)*) => ({
+        if cfg!(not(ndebug)) {
+            assert!($($a)*);
+        }
+    })
+)
+
 /// Runtime assertion for equality, for details see std::macros
+#[macro_export]
 macro_rules! assert_eq(
     ($cond1:expr, $cond2:expr) => ({
         let c1 = $cond1;
@@ -65,6 +76,16 @@ macro_rules! assert_eq(
     })
 )
 
+/// Runtime assertion for equality, only without `--cfg ndebug`
+#[macro_export]
+macro_rules! debug_assert_eq(
+    ($($a:tt)*) => ({
+        if cfg!(not(ndebug)) {
+            assert_eq!($($a)*);
+        }
+    })
+)
+
 /// Runtime assertion, disableable at compile time
 #[macro_export]
 macro_rules! debug_assert(
@@ -86,3 +107,13 @@ macro_rules! vec( ($($e:expr),*) => ({
 
 #[cfg(test)]
 macro_rules! format( ($($arg:tt)*) => (format_args!(::fmt::format, $($arg)*)) )
+
+/// Write some formatted data into a stream.
+///
+/// Identical to the macro in `std::macros`
+#[macro_export]
+macro_rules! write(
+    ($dst:expr, $($arg:tt)*) => ({
+        format_args_method!($dst, write_fmt, $($arg)*)
+    })
+)
diff --git a/src/libstd/collections/hashmap.rs b/src/libstd/collections/hashmap.rs
new file mode 100644 (file)
index 0000000..bcf6d13
--- /dev/null
@@ -0,0 +1,2507 @@
+// Copyright 2014 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.
+
+//! Unordered containers, implemented as hash-tables (`HashSet` and `HashMap` types)
+
+use clone::Clone;
+use cmp::{max, Eq, Equiv, PartialEq};
+use container::{Container, Mutable, Set, MutableSet, Map, MutableMap};
+use default::Default;
+use fmt::Show;
+use fmt;
+use hash::{Hash, Hasher, sip};
+use iter::{Iterator, FilterMap, Chain, Repeat, Zip, Extendable};
+use iter::{range, range_inclusive, FromIterator};
+use iter;
+use mem::replace;
+use num;
+use option::{Some, None, Option};
+use rand::Rng;
+use rand;
+use result::{Ok, Err};
+
+mod table {
+    use clone::Clone;
+    use cmp;
+    use hash::{Hash, Hasher};
+    use iter::range_step_inclusive;
+    use iter::{Iterator, range};
+    use kinds::marker;
+    use mem::{min_align_of, size_of};
+    use mem::{overwrite, transmute};
+    use num::{CheckedMul, is_power_of_two};
+    use ops::Drop;
+    use option::{Some, None, Option, Expect};
+    use ptr::RawPtr;
+    use ptr::set_memory;
+    use ptr;
+    use rt::heap::{allocate, deallocate};
+
+    static EMPTY_BUCKET: u64 = 0u64;
+
+    /// The raw hashtable, providing safe-ish access to the unzipped and highly
+    /// optimized arrays of hashes, keys, and values.
+    ///
+    /// This design uses less memory and is a lot faster than the naive
+    /// `Vec<Option<u64, K, V>>`, because we don't pay for the overhead of an
+    /// option on every element, and we get a generally more cache-aware design.
+    ///
+    /// Key invariants of this structure:
+    ///
+    ///   - if hashes[i] == EMPTY_BUCKET, then keys[i] and vals[i] have
+    ///     'undefined' contents. Don't read from them. This invariant is
+    ///     enforced outside this module with the `EmptyIndex`, `FullIndex`,
+    ///     and `SafeHash` types.
+    ///
+    ///   - An `EmptyIndex` is only constructed for a bucket at an index with
+    ///     a hash of EMPTY_BUCKET.
+    ///
+    ///   - A `FullIndex` is only constructed for a bucket at an index with a
+    ///     non-EMPTY_BUCKET hash.
+    ///
+    ///   - A `SafeHash` is only constructed for non-`EMPTY_BUCKET` hash. We get
+    ///     around hashes of zero by changing them to 0x8000_0000_0000_0000,
+    ///     which will likely map to the same bucket, while not being confused
+    ///     with "empty".
+    ///
+    ///   - All three "arrays represented by pointers" are the same length:
+    ///     `capacity`. This is set at creation and never changes. The arrays
+    ///     are unzipped to save space (we don't have to pay for the padding
+    ///     between odd sized elements, such as in a map from u64 to u8), and
+    ///     be more cache aware (scanning through 8 hashes brings in 2 cache
+    ///     lines, since they're all right beside each other).
+    ///
+    /// You can kind of think of this module/data structure as a safe wrapper
+    /// around just the "table" part of the hashtable. It enforces some
+    /// invariants at the type level and employs some performance trickery,
+    /// but in general is just a tricked out `Vec<Option<u64, K, V>>`.
+    ///
+    /// FIXME(cgaebel):
+    ///
+    /// Feb 11, 2014: This hashtable was just implemented, and, hard as I tried,
+    /// isn't yet totally safe. There's a "known exploit" that you can create
+    /// multiple FullIndexes for a bucket, `take` one, and then still `take`
+    /// the other causing undefined behavior. Currently, there's no story
+    /// for how to protect against this statically. Therefore, there are asserts
+    /// on `take`, `get`, `get_mut`, and `put` which check the bucket state.
+    /// With time, and when we're confident this works correctly, they should
+    /// be removed. Also, the bounds check in `peek` is especially painful,
+    /// as that's called in the innermost loops of the hashtable and has the
+    /// potential to be a major performance drain. Remove this too.
+    ///
+    /// Or, better than remove, only enable these checks for debug builds.
+    /// There's currently no "debug-only" asserts in rust, so if you're reading
+    /// this and going "what? of course there are debug-only asserts!", then
+    /// please make this use them!
+    #[unsafe_no_drop_flag]
+    pub struct RawTable<K, V> {
+        capacity: uint,
+        size:     uint,
+        hashes:   *mut u64,
+        keys:     *mut K,
+        vals:     *mut V,
+    }
+
+    /// Represents an index into a `RawTable` with no key or value in it.
+    pub struct EmptyIndex {
+        idx:    int,
+        nocopy: marker::NoCopy,
+    }
+
+    /// Represents an index into a `RawTable` with a key, value, and hash
+    /// in it.
+    pub struct FullIndex {
+        idx:    int,
+        hash:   SafeHash,
+        nocopy: marker::NoCopy,
+    }
+
+    impl FullIndex {
+        /// Since we get the hash for free whenever we check the bucket state,
+        /// this function is provided for fast access, letting us avoid
+        /// redundant trips back to the hashtable.
+        #[inline(always)]
+        pub fn hash(&self) -> SafeHash { self.hash }
+
+        /// Same comment as with `hash`.
+        #[inline(always)]
+        pub fn raw_index(&self) -> uint { self.idx as uint }
+    }
+
+    /// Represents the state of a bucket: it can either have a key/value
+    /// pair (be full) or not (be empty). You cannot `take` empty buckets,
+    /// and you cannot `put` into full buckets.
+    pub enum BucketState {
+        Empty(EmptyIndex),
+        Full(FullIndex),
+    }
+
+    /// A hash that is not zero, since we use a hash of zero to represent empty
+    /// buckets.
+    #[deriving(PartialEq)]
+    pub struct SafeHash {
+        hash: u64,
+    }
+
+    impl SafeHash {
+        /// Peek at the hash value, which is guaranteed to be non-zero.
+        #[inline(always)]
+        pub fn inspect(&self) -> u64 { self.hash }
+    }
+
+    /// We need to remove hashes of 0. That's reserved for empty buckets.
+    /// This function wraps up `hash_keyed` to be the only way outside this
+    /// module to generate a SafeHash.
+    pub fn make_hash<T: Hash<S>, S, H: Hasher<S>>(hasher: &H, t: &T) -> SafeHash {
+        match hasher.hash(t) {
+            // This constant is exceedingly likely to hash to the same
+            // bucket, but it won't be counted as empty!
+            EMPTY_BUCKET => SafeHash { hash: 0x8000_0000_0000_0000 },
+            h            => SafeHash { hash: h },
+        }
+    }
+
+    fn round_up_to_next(unrounded: uint, target_alignment: uint) -> uint {
+        assert!(is_power_of_two(target_alignment));
+        (unrounded + target_alignment - 1) & !(target_alignment - 1)
+    }
+
+    #[test]
+    fn test_rounding() {
+        assert_eq!(round_up_to_next(0, 4), 0);
+        assert_eq!(round_up_to_next(1, 4), 4);
+        assert_eq!(round_up_to_next(2, 4), 4);
+        assert_eq!(round_up_to_next(3, 4), 4);
+        assert_eq!(round_up_to_next(4, 4), 4);
+        assert_eq!(round_up_to_next(5, 4), 8);
+    }
+
+    // Returns a tuple of (minimum required malloc alignment, hash_offset,
+    // key_offset, val_offset, array_size), from the start of a mallocated array.
+    fn calculate_offsets(
+        hash_size: uint, hash_align: uint,
+        keys_size: uint, keys_align: uint,
+        vals_size: uint, vals_align: uint) -> (uint, uint, uint, uint, uint) {
+
+        let hash_offset   = 0;
+        let end_of_hashes = hash_offset + hash_size;
+
+        let keys_offset   = round_up_to_next(end_of_hashes, keys_align);
+        let end_of_keys   = keys_offset + keys_size;
+
+        let vals_offset   = round_up_to_next(end_of_keys, vals_align);
+        let end_of_vals   = vals_offset + vals_size;
+
+        let min_align = cmp::max(hash_align, cmp::max(keys_align, vals_align));
+
+        (min_align, hash_offset, keys_offset, vals_offset, end_of_vals)
+    }
+
+    #[test]
+    fn test_offset_calculation() {
+        assert_eq!(calculate_offsets(128, 8, 15, 1, 4, 4 ), (8, 0, 128, 144, 148));
+        assert_eq!(calculate_offsets(3,   1, 2,  1, 1, 1 ), (1, 0, 3,   5,   6));
+        assert_eq!(calculate_offsets(6,   2, 12, 4, 24, 8), (8, 0, 8,   24,  48));
+    }
+
+    impl<K, V> RawTable<K, V> {
+
+        /// Does not initialize the buckets. The caller should ensure they,
+        /// at the very least, set every hash to EMPTY_BUCKET.
+        unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
+            let hashes_size = capacity.checked_mul(&size_of::<u64>())
+                                      .expect("capacity overflow");
+            let keys_size = capacity.checked_mul(&size_of::< K >())
+                                    .expect("capacity overflow");
+            let vals_size = capacity.checked_mul(&size_of::< V >())
+                                    .expect("capacity overflow");
+
+            // Allocating hashmaps is a little tricky. We need to allocate three
+            // arrays, but since we know their sizes and alignments up front,
+            // we just allocate a single array, and then have the subarrays
+            // point into it.
+            //
+            // This is great in theory, but in practice getting the alignment
+            // right is a little subtle. Therefore, calculating offsets has been
+            // factored out into a different function.
+            let (malloc_alignment, hash_offset, keys_offset, vals_offset, size) =
+                calculate_offsets(
+                    hashes_size, min_align_of::<u64>(),
+                    keys_size,   min_align_of::< K >(),
+                    vals_size,   min_align_of::< V >());
+
+            let buffer = allocate(size, malloc_alignment);
+
+            let hashes = buffer.offset(hash_offset as int) as *mut u64;
+            let keys   = buffer.offset(keys_offset as int) as *mut K;
+            let vals   = buffer.offset(vals_offset as int) as *mut V;
+
+            RawTable {
+                capacity: capacity,
+                size:     0,
+                hashes:   hashes,
+                keys:     keys,
+                vals:     vals,
+            }
+        }
+
+        /// Creates a new raw table from a given capacity. All buckets are
+        /// initially empty.
+        pub fn new(capacity: uint) -> RawTable<K, V> {
+            unsafe {
+                let ret = RawTable::new_uninitialized(capacity);
+                set_memory(ret.hashes, 0u8, capacity);
+                ret
+            }
+        }
+
+        /// Reads a bucket at a given index, returning an enum indicating whether
+        /// there's anything there or not. You need to match on this enum to get
+        /// the appropriate types to pass on to most of the other functions in
+        /// this module.
+        pub fn peek(&self, index: uint) -> BucketState {
+            debug_assert!(index < self.capacity);
+
+            let idx  = index as int;
+            let hash = unsafe { *self.hashes.offset(idx) };
+
+            let nocopy = marker::NoCopy;
+
+            match hash {
+                EMPTY_BUCKET =>
+                    Empty(EmptyIndex {
+                        idx:    idx,
+                        nocopy: nocopy
+                    }),
+                full_hash =>
+                    Full(FullIndex {
+                        idx:    idx,
+                        hash:   SafeHash { hash: full_hash },
+                        nocopy: nocopy,
+                    })
+            }
+        }
+
+        /// Gets references to the key and value at a given index.
+        pub fn read<'a>(&'a self, index: &FullIndex) -> (&'a K, &'a V) {
+            let idx = index.idx;
+
+            unsafe {
+                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
+                (&'a *self.keys.offset(idx),
+                 &'a *self.vals.offset(idx))
+            }
+        }
+
+        /// Gets references to the key and value at a given index, with the
+        /// value's reference being mutable.
+        pub fn read_mut<'a>(&'a mut self, index: &FullIndex) -> (&'a K, &'a mut V) {
+            let idx = index.idx;
+
+            unsafe {
+                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
+                (&'a     *self.keys.offset(idx),
+                 &'a mut *self.vals.offset(idx))
+            }
+        }
+
+        /// Read everything, mutably.
+        pub fn read_all_mut<'a>(&'a mut self, index: &FullIndex)
+            -> (&'a mut SafeHash, &'a mut K, &'a mut V) {
+            let idx = index.idx;
+
+            unsafe {
+                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
+                (transmute(self.hashes.offset(idx)),
+                 &'a mut *self.keys.offset(idx),
+                 &'a mut *self.vals.offset(idx))
+            }
+        }
+
+        /// Puts a key and value pair, along with the key's hash, into a given
+        /// index in the hashtable. Note how the `EmptyIndex` is 'moved' into this
+        /// function, because that slot will no longer be empty when we return!
+        /// A FullIndex is returned for later use, pointing to the newly-filled
+        /// slot in the hashtable.
+        ///
+        /// Use `make_hash` to construct a `SafeHash` to pass to this function.
+        pub fn put(&mut self, index: EmptyIndex, hash: SafeHash, k: K, v: V) -> FullIndex {
+            let idx = index.idx;
+
+            unsafe {
+                debug_assert_eq!(*self.hashes.offset(idx), EMPTY_BUCKET);
+                *self.hashes.offset(idx) = hash.inspect();
+                overwrite(&mut *self.keys.offset(idx), k);
+                overwrite(&mut *self.vals.offset(idx), v);
+            }
+
+            self.size += 1;
+
+            FullIndex { idx: idx, hash: hash, nocopy: marker::NoCopy }
+        }
+
+        /// Removes a key and value from the hashtable.
+        ///
+        /// This works similarly to `put`, building an `EmptyIndex` out of the
+        /// taken FullIndex.
+        pub fn take(&mut self, index: FullIndex) -> (EmptyIndex, K, V) {
+            let idx  = index.idx;
+
+            unsafe {
+                debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
+
+                *self.hashes.offset(idx) = EMPTY_BUCKET;
+
+                // Drop the mutable constraint.
+                let keys = self.keys as *K;
+                let vals = self.vals as *V;
+
+                let k = ptr::read(keys.offset(idx));
+                let v = ptr::read(vals.offset(idx));
+
+                self.size -= 1;
+
+                (EmptyIndex { idx: idx, nocopy: marker::NoCopy }, k, v)
+            }
+        }
+
+        /// The hashtable's capacity, similar to a vector's.
+        pub fn capacity(&self) -> uint {
+            self.capacity
+        }
+
+        /// The number of elements ever `put` in the hashtable, minus the number
+        /// of elements ever `take`n.
+        pub fn size(&self) -> uint {
+            self.size
+        }
+
+        pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
+            Entries { table: self, idx: 0, elems_seen: 0 }
+        }
+
+        pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
+            MutEntries { table: self, idx: 0, elems_seen: 0 }
+        }
+
+        pub fn move_iter(self) -> MoveEntries<K, V> {
+            MoveEntries { table: self, idx: 0, elems_seen: 0 }
+        }
+    }
+
+    // `read_all_mut` casts a `*u64` to a `*SafeHash`. Since we statically
+    // ensure that a `FullIndex` points to an index with a non-zero hash,
+    // and a `SafeHash` is just a `u64` with a different name, this is
+    // safe.
+    //
+    // This test ensures that a `SafeHash` really IS the same size as a
+    // `u64`. If you need to change the size of `SafeHash` (and
+    // consequently made this test fail), `read_all_mut` needs to be
+    // modified to no longer assume this.
+    #[test]
+    fn can_alias_safehash_as_u64() {
+        assert_eq!(size_of::<SafeHash>(), size_of::<u64>())
+    }
+
+    pub struct Entries<'a, K, V> {
+        table: &'a RawTable<K, V>,
+        idx: uint,
+        elems_seen: uint,
+    }
+
+    pub struct MutEntries<'a, K, V> {
+        table: &'a mut RawTable<K, V>,
+        idx: uint,
+        elems_seen: uint,
+    }
+
+    pub struct MoveEntries<K, V> {
+        table: RawTable<K, V>,
+        idx: uint,
+        elems_seen: uint,
+    }
+
+    impl<'a, K, V> Iterator<(&'a K, &'a V)> for Entries<'a, K, V> {
+        fn next(&mut self) -> Option<(&'a K, &'a V)> {
+            while self.idx < self.table.capacity() {
+                let i = self.idx;
+                self.idx += 1;
+
+                match self.table.peek(i) {
+                    Empty(_)  => {},
+                    Full(idx) => {
+                        self.elems_seen += 1;
+                        return Some(self.table.read(&idx));
+                    }
+                }
+            }
+
+            None
+        }
+
+        fn size_hint(&self) -> (uint, Option<uint>) {
+            let size = self.table.size() - self.elems_seen;
+            (size, Some(size))
+        }
+    }
+
+    impl<'a, K, V> Iterator<(&'a K, &'a mut V)> for MutEntries<'a, K, V> {
+        fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
+            while self.idx < self.table.capacity() {
+                let i = self.idx;
+                self.idx += 1;
+
+                match self.table.peek(i) {
+                    Empty(_)  => {},
+                    // the transmute here fixes:
+                    // error: lifetime of `self` is too short to guarantee its contents
+                    //        can be safely reborrowed
+                    Full(idx) => unsafe {
+                        self.elems_seen += 1;
+                        return Some(transmute(self.table.read_mut(&idx)));
+                    }
+                }
+            }
+
+            None
+        }
+
+        fn size_hint(&self) -> (uint, Option<uint>) {
+            let size = self.table.size() - self.elems_seen;
+            (size, Some(size))
+        }
+    }
+
+    impl<K, V> Iterator<(SafeHash, K, V)> for MoveEntries<K, V> {
+        fn next(&mut self) -> Option<(SafeHash, K, V)> {
+            while self.idx < self.table.capacity() {
+                let i = self.idx;
+                self.idx += 1;
+
+                match self.table.peek(i) {
+                    Empty(_) => {},
+                    Full(idx) => {
+                        let h = idx.hash();
+                        let (_, k, v) = self.table.take(idx);
+                        return Some((h, k, v));
+                    }
+                }
+            }
+
+            None
+        }
+
+        fn size_hint(&self) -> (uint, Option<uint>) {
+            let size = self.table.size();
+            (size, Some(size))
+        }
+    }
+
+    impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
+        fn clone(&self) -> RawTable<K, V> {
+            unsafe {
+                let mut new_ht = RawTable::new_uninitialized(self.capacity());
+
+                for i in range(0, self.capacity()) {
+                    match self.peek(i) {
+                        Empty(_)  => {
+                            *new_ht.hashes.offset(i as int) = EMPTY_BUCKET;
+                        },
+                        Full(idx) => {
+                            let hash = idx.hash().inspect();
+                            let (k, v) = self.read(&idx);
+                            *new_ht.hashes.offset(i as int) = hash;
+                            overwrite(&mut *new_ht.keys.offset(i as int), (*k).clone());
+                            overwrite(&mut *new_ht.vals.offset(i as int), (*v).clone());
+                        }
+                    }
+                }
+
+                new_ht.size = self.size();
+
+                new_ht
+            }
+        }
+    }
+
+    #[unsafe_destructor]
+    impl<K, V> Drop for RawTable<K, V> {
+        fn drop(&mut self) {
+            // This is in reverse because we're likely to have partially taken
+            // some elements out with `.move_iter()` from the front.
+            for i in range_step_inclusive(self.capacity as int - 1, 0, -1) {
+                // Check if the size is 0, so we don't do a useless scan when
+                // dropping empty tables such as on resize.
+                if self.size == 0 { break }
+
+                match self.peek(i as uint) {
+                    Empty(_)  => {},
+                    Full(idx) => { self.take(idx); }
+                }
+            }
+
+            assert_eq!(self.size, 0);
+
+            if self.hashes.is_not_null() {
+                let hashes_size = self.capacity * size_of::<u64>();
+                let keys_size = self.capacity * size_of::<K>();
+                let vals_size = self.capacity * size_of::<V>();
+                let (align, _, _, _, size) = calculate_offsets(hashes_size, min_align_of::<u64>(),
+                                                               keys_size, min_align_of::<K>(),
+                                                               vals_size, min_align_of::<V>());
+
+                unsafe {
+                    deallocate(self.hashes as *mut u8, size, align);
+                    // Remember how everything was allocated out of one buffer
+                    // during initialization? We only need one call to free here.
+                }
+
+                self.hashes = RawPtr::null();
+            }
+        }
+    }
+}
+
+static INITIAL_LOG2_CAP: uint = 5;
+static INITIAL_CAPACITY: uint = 1 << INITIAL_LOG2_CAP; // 2^5
+
+/// The default behavior of HashMap implements a load factor of 90.9%.
+/// This behavior is characterized by the following conditions:
+///
+/// - if `size * 1.1 < cap < size * 4` then shouldn't resize
+/// - if `cap < minimum_capacity * 2` then shouldn't shrink
+#[deriving(Clone)]
+struct DefaultResizePolicy {
+    /// Doubled minimal capacity. The capacity must never drop below
+    /// the minimum capacity. (The check happens before the capacity
+    /// is potentially halved.)
+    minimum_capacity2: uint
+}
+
+impl DefaultResizePolicy {
+    fn new(new_capacity: uint) -> DefaultResizePolicy {
+        DefaultResizePolicy {
+            minimum_capacity2: new_capacity << 1
+        }
+    }
+
+    #[inline]
+    fn capacity_range(&self, new_size: uint) -> (uint, uint) {
+        ((new_size * 11) / 10, max(new_size << 3, self.minimum_capacity2))
+    }
+
+    #[inline]
+    fn reserve(&mut self, new_capacity: uint) {
+        self.minimum_capacity2 = new_capacity << 1;
+    }
+}
+
+// The main performance trick in this hashmap is called Robin Hood Hashing.
+// It gains its excellent performance from one key invariant:
+//
+//    If an insertion collides with an existing element, and that elements
+//    "probe distance" (how far away the element is from its ideal location)
+//    is higher than how far we've already probed, swap the elements.
+//
+// This massively lowers variance in probe distance, and allows us to get very
+// high load factors with good performance. The 90% load factor I use is rather
+// conservative.
+//
+// > Why a load factor of approximately 90%?
+//
+// In general, all the distances to initial buckets will converge on the mean.
+// At a load factor of α, the odds of finding the target bucket after k
+// probes is approximately 1-α^k. If we set this equal to 50% (since we converge
+// on the mean) and set k=8 (64-byte cache line / 8-byte hash), α=0.92. I round
+// this down to make the math easier on the CPU and avoid its FPU.
+// Since on average we start the probing in the middle of a cache line, this
+// strategy pulls in two cache lines of hashes on every lookup. I think that's
+// pretty good, but if you want to trade off some space, it could go down to one
+// cache line on average with an α of 0.84.
+//
+// > Wait, what? Where did you get 1-α^k from?
+//
+// On the first probe, your odds of a collision with an existing element is α.
+// The odds of doing this twice in a row is approximately α^2. For three times,
+// α^3, etc. Therefore, the odds of colliding k times is α^k. The odds of NOT
+// colliding after k tries is 1-α^k.
+//
+// Future Improvements (FIXME!)
+// ============================
+//
+// Allow the load factor to be changed dynamically and/or at initialization.
+//
+// Also, would it be possible for us to reuse storage when growing the
+// underlying table? This is exactly the use case for 'realloc', and may
+// be worth exploring.
+//
+// Future Optimizations (FIXME!)
+// =============================
+//
+// The paper cited below mentions an implementation which keeps track of the
+// distance-to-initial-bucket histogram. I'm suspicious of this approach because
+// it requires maintaining an internal map. If this map were replaced with a
+// hashmap, it would be faster, but now our data structure is self-referential
+// and blows up. Also, this allows very good first guesses, but array accesses
+// are no longer linear and in one direction, as we have now. There is also
+// memory and cache pressure that this map would entail that would be very
+// difficult to properly see in a microbenchmark.
+//
+// Another possible design choice that I made without any real reason is
+// parameterizing the raw table over keys and values. Technically, all we need
+// is the size and alignment of keys and values, and the code should be just as
+// efficient (well, we might need one for power-of-two size and one for not...).
+// This has the potential to reduce code bloat in rust executables, without
+// really losing anything except 4 words (key size, key alignment, val size,
+// val alignment) which can be passed in to every call of a `RawTable` function.
+// This would definitely be an avenue worth exploring if people start complaining
+// about the size of rust executables.
+//
+// There's also an "optimization" that has been omitted regarding how the
+// hashtable allocates. The vector type has set the expectation that a hashtable
+// which never has an element inserted should not allocate. I'm suspicious of
+// implementing this for hashtables, because supporting it has no performance
+// benefit over using an `Option<HashMap<K, V>>`, and is significantly more
+// complicated.
+
+/// A hash map implementation which uses linear probing with Robin
+/// Hood bucket stealing.
+///
+/// The hashes are all keyed by the task-local random number generator
+/// on creation by default, this means the ordering of the keys is
+/// randomized, but makes the tables more resistant to
+/// denial-of-service attacks (Hash DoS). This behaviour can be
+/// overridden with one of the constructors.
+///
+/// It is required that the keys implement the `PartialEq` and `Hash` traits, although
+/// this can frequently be achieved by using `#[deriving(PartialEq, Hash)]`.
+///
+/// Relevant papers/articles:
+///
+/// 1. Pedro Celis. ["Robin Hood Hashing"](https://cs.uwaterloo.ca/research/tr/1986/CS-86-14.pdf)
+/// 2. Emmanuel Goossaert. ["Robin Hood
+///    hashing"](http://codecapsule.com/2013/11/11/robin-hood-hashing/)
+/// 3. Emmanuel Goossaert. ["Robin Hood hashing: backward shift
+///    deletion"](http://codecapsule.com/2013/11/17/robin-hood-hashing-backward-shift-deletion/)
+///
+/// # Example
+///
+/// ```rust
+/// use collections::HashMap;
+///
+/// // type inference lets us omit an explicit type signature (which
+/// // would be `HashMap<&str, &str>` in this example).
+/// let mut book_reviews = HashMap::new();
+///
+/// // review some books.
+/// book_reviews.insert("Adventures of Huckleberry Finn",    "My favorite book.");
+/// book_reviews.insert("Grimms' Fairy Tales",               "Masterpiece.");
+/// book_reviews.insert("Pride and Prejudice",               "Very enjoyable.");
+/// book_reviews.insert("The Adventures of Sherlock Holmes", "Eye lyked it alot.");
+///
+/// // check for a specific one.
+/// if !book_reviews.contains_key(&("Les Misérables")) {
+///     println!("We've got {} reviews, but Les Misérables ain't one.",
+///              book_reviews.len());
+/// }
+///
+/// // oops, this review has a lot of spelling mistakes, let's delete it.
+/// book_reviews.remove(&("The Adventures of Sherlock Holmes"));
+///
+/// // look up the values associated with some keys.
+/// let to_find = ["Pride and Prejudice", "Alice's Adventure in Wonderland"];
+/// for book in to_find.iter() {
+///     match book_reviews.find(book) {
+///         Some(review) => println!("{}: {}", *book, *review),
+///         None => println!("{} is unreviewed.", *book)
+///     }
+/// }
+///
+/// // iterate over everything.
+/// for (book, review) in book_reviews.iter() {
+///     println!("{}: \"{}\"", *book, *review);
+/// }
+/// ```
+#[deriving(Clone)]
+pub struct HashMap<K, V, H = sip::SipHasher> {
+    // All hashes are keyed on these values, to prevent hash collision attacks.
+    hasher: H,
+
+    table: table::RawTable<K, V>,
+
+    // We keep this at the end since it might as well have tail padding.
+    resize_policy: DefaultResizePolicy,
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
+    // Probe the `idx`th bucket for a given hash, returning the index of the
+    // target bucket.
+    //
+    // This exploits the power-of-two size of the hashtable. As long as this
+    // is always true, we can use a bitmask of cap-1 to do modular arithmetic.
+    //
+    // Prefer using this with increasing values of `idx` rather than repeatedly
+    // calling `probe_next`. This reduces data-dependencies between loops, which
+    // can help the optimizer, and certainly won't hurt it. `probe_next` is
+    // simply for convenience, and is no more efficient than `probe`.
+    fn probe(&self, hash: &table::SafeHash, idx: uint) -> uint {
+        let hash_mask = self.table.capacity() - 1;
+
+        // So I heard a rumor that unsigned overflow is safe in rust..
+        ((hash.inspect() as uint) + idx) & hash_mask
+    }
+
+    // Generate the next probe in a sequence. Prefer using 'probe' by itself,
+    // but this can sometimes be useful.
+    fn probe_next(&self, probe: uint) -> uint {
+        let hash_mask = self.table.capacity() - 1;
+        (probe + 1) & hash_mask
+    }
+
+    fn make_hash<X: Hash<S>>(&self, x: &X) -> table::SafeHash {
+        table::make_hash(&self.hasher, x)
+    }
+
+    /// Get the distance of the bucket at the given index that it lies
+    /// from its 'ideal' location.
+    ///
+    /// In the cited blog posts above, this is called the "distance to
+    /// initial bucket", or DIB.
+    fn bucket_distance(&self, index_of_elem: &table::FullIndex) -> uint {
+        // where the hash of the element that happens to reside at
+        // `index_of_elem` tried to place itself first.
+        let first_probe_index = self.probe(&index_of_elem.hash(), 0);
+
+        let raw_index = index_of_elem.raw_index();
+
+        if first_probe_index <= raw_index {
+             // probe just went forward
+            raw_index - first_probe_index
+        } else {
+            // probe wrapped around the hashtable
+            raw_index + (self.table.capacity() - first_probe_index)
+        }
+    }
+
+    /// Search for a pre-hashed key.
+    fn search_hashed_generic(&self, hash: &table::SafeHash, is_match: |&K| -> bool)
+        -> Option<table::FullIndex> {
+        for num_probes in range(0u, self.table.size()) {
+            let probe = self.probe(hash, num_probes);
+
+            let idx = match self.table.peek(probe) {
+                table::Empty(_)  => return None, // hit an empty bucket
+                table::Full(idx) => idx
+            };
+
+            // We can finish the search early if we hit any bucket
+            // with a lower distance to initial bucket than we've probed.
+            if self.bucket_distance(&idx) < num_probes { return None }
+
+            // If the hash doesn't match, it can't be this one..
+            if *hash != idx.hash() { continue }
+
+            let (k, _) = self.table.read(&idx);
+
+            // If the key doesn't match, it can't be this one..
+            if !is_match(k) { continue }
+
+            return Some(idx);
+        }
+
+        return None
+    }
+
+    fn search_hashed(&self, hash: &table::SafeHash, k: &K) -> Option<table::FullIndex> {
+        self.search_hashed_generic(hash, |k_| *k == *k_)
+    }
+
+    fn search_equiv<Q: Hash<S> + Equiv<K>>(&self, q: &Q) -> Option<table::FullIndex> {
+        self.search_hashed_generic(&self.make_hash(q), |k| q.equiv(k))
+    }
+
+    /// Search for a key, yielding the index if it's found in the hashtable.
+    /// If you already have the hash for the key lying around, use
+    /// search_hashed.
+    fn search(&self, k: &K) -> Option<table::FullIndex> {
+        self.search_hashed(&self.make_hash(k), k)
+    }
+
+    fn pop_internal(&mut self, starting_index: table::FullIndex) -> Option<V> {
+        let starting_probe = starting_index.raw_index();
+
+        let ending_probe = {
+            let mut probe = self.probe_next(starting_probe);
+            for _ in range(0u, self.table.size()) {
+                match self.table.peek(probe) {
+                    table::Empty(_) => {}, // empty bucket. this is the end of our shifting.
+                    table::Full(idx) => {
+                        // Bucket that isn't us, which has a non-zero probe distance.
+                        // This isn't the ending index, so keep searching.
+                        if self.bucket_distance(&idx) != 0 {
+                            probe = self.probe_next(probe);
+                            continue;
+                        }
+
+                        // if we do have a bucket_distance of zero, we're at the end
+                        // of what we need to shift.
+                    }
+                }
+                break;
+            }
+
+            probe
+        };
+
+        let (_, _, retval) = self.table.take(starting_index);
+
+        let mut      probe = starting_probe;
+        let mut next_probe = self.probe_next(probe);
+
+        // backwards-shift all the elements after our newly-deleted one.
+        while next_probe != ending_probe {
+            match self.table.peek(next_probe) {
+                table::Empty(_) => {
+                    // nothing to shift in. just empty it out.
+                    match self.table.peek(probe) {
+                        table::Empty(_) => {},
+                        table::Full(idx) => { self.table.take(idx); }
+                    }
+                },
+                table::Full(next_idx) => {
+                    // something to shift. move it over!
+                    let next_hash = next_idx.hash();
+                    let (_, next_key, next_val) = self.table.take(next_idx);
+                    match self.table.peek(probe) {
+                        table::Empty(idx) => {
+                            self.table.put(idx, next_hash, next_key, next_val);
+                        },
+                        table::Full(idx) => {
+                            let (emptyidx, _, _) = self.table.take(idx);
+                            self.table.put(emptyidx, next_hash, next_key, next_val);
+                        }
+                    }
+                }
+            }
+
+            probe = next_probe;
+            next_probe = self.probe_next(next_probe);
+        }
+
+        // Done the backwards shift, but there's still an element left!
+        // Empty it out.
+        match self.table.peek(probe) {
+            table::Empty(_) => {},
+            table::Full(idx) => { self.table.take(idx); }
+        }
+
+        // Now we're done all our shifting. Return the value we grabbed
+        // earlier.
+        return Some(retval);
+    }
+
+    /// Like `pop`, but can operate on any type that is equivalent to a key.
+    #[experimental]
+    pub fn pop_equiv<Q:Hash<S> + Equiv<K>>(&mut self, k: &Q) -> Option<V> {
+        if self.table.size() == 0 {
+            return None
+        }
+
+        let potential_new_size = self.table.size() - 1;
+        self.make_some_room(potential_new_size);
+
+        let starting_index = match self.search_equiv(k) {
+            Some(idx) => idx,
+            None      => return None,
+        };
+
+        self.pop_internal(starting_index)
+    }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Container for HashMap<K, V, H> {
+    /// Return the number of elements in the map
+    fn len(&self) -> uint { self.table.size() }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
+    /// Clear the map, removing all key-value pairs. Keeps the allocated memory
+    /// for reuse.
+    fn clear(&mut self) {
+        // Prevent reallocations from happening from now on. Makes it possible
+        // for the map to be reused but has a downside: reserves permanently.
+        self.resize_policy.reserve(self.table.size());
+
+        for i in range(0, self.table.capacity()) {
+            match self.table.peek(i) {
+                table::Empty(_)  => {},
+                table::Full(idx) => { self.table.take(idx); }
+            }
+        }
+    }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
+    fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
+        self.search(k).map(|idx| {
+            let (_, v) = self.table.read(&idx);
+            v
+        })
+    }
+
+    fn contains_key(&self, k: &K) -> bool {
+        self.search(k).is_some()
+    }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
+    fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
+        match self.search(k) {
+            None => None,
+            Some(idx) => {
+                let (_, v) = self.table.read_mut(&idx);
+                Some(v)
+            }
+        }
+    }
+
+    fn swap(&mut self, k: K, v: V) -> Option<V> {
+        let hash = self.make_hash(&k);
+        let potential_new_size = self.table.size() + 1;
+        self.make_some_room(potential_new_size);
+
+        for dib in range_inclusive(0u, self.table.size()) {
+            let probe = self.probe(&hash, dib);
+
+            let idx = match self.table.peek(probe) {
+                table::Empty(idx) => {
+                    // Found a hole!
+                    self.table.put(idx, hash, k, v);
+                    return None;
+                },
+                table::Full(idx) => idx
+            };
+
+            if idx.hash() == hash {
+                let (bucket_k, bucket_v) = self.table.read_mut(&idx);
+                if k == *bucket_k {
+                    // Found an existing value.
+                    return Some(replace(bucket_v, v));
+                }
+            }
+
+            let probe_dib = self.bucket_distance(&idx);
+
+            if probe_dib < dib {
+                // Found a luckier bucket. This implies that the key does not
+                // already exist in the hashtable. Just do a robin hood
+                // insertion, then.
+                self.robin_hood(idx, probe_dib, hash, k, v);
+                return None;
+            }
+        }
+
+        // We really shouldn't be here.
+        fail!("Internal HashMap error: Out of space.");
+    }
+
+    fn pop(&mut self, k: &K) -> Option<V> {
+        if self.table.size() == 0 {
+            return None
+        }
+
+        let potential_new_size = self.table.size() - 1;
+        self.make_some_room(potential_new_size);
+
+        let starting_index = match self.search(k) {
+            Some(idx) => idx,
+            None      => return None,
+        };
+
+        self.pop_internal(starting_index)
+    }
+
+}
+
+impl<K: Hash + Eq, V> HashMap<K, V, sip::SipHasher> {
+    /// Create an empty HashMap.
+    pub fn new() -> HashMap<K, V, sip::SipHasher> {
+        HashMap::with_capacity(INITIAL_CAPACITY)
+    }
+
+    /// Creates an empty hash map with the given initial capacity.
+    pub fn with_capacity(capacity: uint) -> HashMap<K, V, sip::SipHasher> {
+        let mut r = rand::task_rng();
+        let r0 = r.gen();
+        let r1 = r.gen();
+        let hasher = sip::SipHasher::new_with_keys(r0, r1);
+        HashMap::with_capacity_and_hasher(capacity, hasher)
+    }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
+    /// Creates an empty hashmap which will use the given hasher to hash keys.
+    ///
+    /// The creates map has the default initial capacity.
+    pub fn with_hasher(hasher: H) -> HashMap<K, V, H> {
+        HashMap::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
+    }
+
+    /// Create an empty HashMap with space for at least `capacity`
+    /// elements, using `hasher` to hash the keys.
+    ///
+    /// Warning: `hasher` is normally randomly generated, and
+    /// is designed to allow HashMaps to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashMap<K, V, H> {
+        let cap = num::next_power_of_two(max(INITIAL_CAPACITY, capacity));
+        HashMap {
+            hasher:        hasher,
+            resize_policy: DefaultResizePolicy::new(cap),
+            table:         table::RawTable::new(cap),
+        }
+    }
+
+    /// The hashtable will never try to shrink below this size. You can use
+    /// this function to reduce reallocations if your hashtable frequently
+    /// grows and shrinks by large amounts.
+    ///
+    /// This function has no effect on the operational semantics of the
+    /// hashtable, only on performance.
+    pub fn reserve(&mut self, new_minimum_capacity: uint) {
+        let cap = num::next_power_of_two(
+            max(INITIAL_CAPACITY, new_minimum_capacity));
+
+        self.resize_policy.reserve(cap);
+
+        if self.table.capacity() < cap {
+            self.resize(cap);
+        }
+    }
+
+    /// Resizes the internal vectors to a new capacity. It's your responsibility to:
+    ///   1) Make sure the new capacity is enough for all the elements, accounting
+    ///      for the load factor.
+    ///   2) Ensure new_capacity is a power of two.
+    fn resize(&mut self, new_capacity: uint) {
+        assert!(self.table.size() <= new_capacity);
+        assert!(num::is_power_of_two(new_capacity));
+
+        let old_table = replace(&mut self.table, table::RawTable::new(new_capacity));
+        let old_size  = old_table.size();
+
+        for (h, k, v) in old_table.move_iter() {
+            self.insert_hashed_nocheck(h, k, v);
+        }
+
+        assert_eq!(self.table.size(), old_size);
+    }
+
+    /// Performs any necessary resize operations, such that there's space for
+    /// new_size elements.
+    fn make_some_room(&mut self, new_size: uint) {
+        let (grow_at, shrink_at) = self.resize_policy.capacity_range(new_size);
+        let cap = self.table.capacity();
+
+        // An invalid value shouldn't make us run out of space.
+        debug_assert!(grow_at >= new_size);
+
+        if cap <= grow_at {
+            let new_capacity = cap << 1;
+            self.resize(new_capacity);
+        } else if shrink_at <= cap {
+            let new_capacity = cap >> 1;
+            self.resize(new_capacity);
+        }
+    }
+
+    /// Perform robin hood bucket stealing at the given 'index'. You must
+    /// also pass that probe's "distance to initial bucket" so we don't have
+    /// to recalculate it, as well as the total number of probes already done
+    /// so we have some sort of upper bound on the number of probes to do.
+    ///
+    /// 'hash', 'k', and 'v' are the elements to robin hood into the hashtable.
+    fn robin_hood(&mut self, mut index: table::FullIndex, mut dib_param: uint,
+                  mut hash: table::SafeHash, mut k: K, mut v: V) {
+        'outer: loop {
+            let (old_hash, old_key, old_val) = {
+                let (old_hash_ref, old_key_ref, old_val_ref) =
+                        self.table.read_all_mut(&index);
+
+                let old_hash = replace(old_hash_ref, hash);
+                let old_key  = replace(old_key_ref,  k);
+                let old_val  = replace(old_val_ref,  v);
+
+                (old_hash, old_key, old_val)
+            };
+
+            let mut probe = self.probe_next(index.raw_index());
+
+            for dib in range(dib_param + 1, self.table.size()) {
+                let full_index = match self.table.peek(probe) {
+                    table::Empty(idx) => {
+                        // Finally. A hole!
+                        self.table.put(idx, old_hash, old_key, old_val);
+                        return;
+                    },
+                    table::Full(idx) => idx
+                };
+
+                let probe_dib = self.bucket_distance(&full_index);
+
+                // Robin hood! Steal the spot.
+                if probe_dib < dib {
+                    index = full_index;
+                    dib_param = probe_dib;
+                    hash = old_hash;
+                    k = old_key;
+                    v = old_val;
+                    continue 'outer;
+                }
+
+                probe = self.probe_next(probe);
+            }
+
+            fail!("HashMap fatal error: 100% load factor?");
+        }
+    }
+
+    /// Insert a pre-hashed key-value pair, without first checking
+    /// that there's enough room in the buckets. Returns a reference to the
+    /// newly insert value.
+    ///
+    /// If the key already exists, the hashtable will be returned untouched
+    /// and a reference to the existing element will be returned.
+    fn insert_hashed_nocheck<'a>(
+        &'a mut self, hash: table::SafeHash, k: K, v: V) -> &'a mut V {
+
+        for dib in range_inclusive(0u, self.table.size()) {
+            let probe = self.probe(&hash, dib);
+
+            let idx = match self.table.peek(probe) {
+                table::Empty(idx) => {
+                    // Found a hole!
+                    let fullidx  = self.table.put(idx, hash, k, v);
+                    let (_, val) = self.table.read_mut(&fullidx);
+                    return val;
+                },
+                table::Full(idx) => idx
+            };
+
+            if idx.hash() == hash {
+                let (bucket_k, bucket_v) = self.table.read_mut(&idx);
+                // FIXME #12147 the conditional return confuses
+                // borrowck if we return bucket_v directly
+                let bv: *mut V = bucket_v;
+                if k == *bucket_k {
+                    // Key already exists. Get its reference.
+                    return unsafe {&mut *bv};
+                }
+            }
+
+            let probe_dib = self.bucket_distance(&idx);
+
+            if  probe_dib < dib {
+                // Found a luckier bucket than me. Better steal his spot.
+                self.robin_hood(idx, probe_dib, hash, k, v);
+
+                // Now that it's stolen, just read the value's pointer
+                // right out of the table!
+                match self.table.peek(probe) {
+                    table::Empty(_)  => fail!("Just stole a spot, but now that spot's empty."),
+                    table::Full(idx) => {
+                        let (_, v) = self.table.read_mut(&idx);
+                        return v;
+                    }
+                }
+            }
+        }
+
+        // We really shouldn't be here.
+        fail!("Internal HashMap error: Out of space.");
+    }
+
+    /// Inserts an element which has already been hashed, returning a reference
+    /// to that element inside the hashtable. This is more efficient that using
+    /// `insert`, since the key will not be rehashed.
+    fn insert_hashed<'a>(&'a mut self, hash: table::SafeHash, k: K, v: V) -> &'a mut V {
+        let potential_new_size = self.table.size() + 1;
+        self.make_some_room(potential_new_size);
+        self.insert_hashed_nocheck(hash, k, v)
+    }
+
+    /// Return the value corresponding to the key in the map, or insert
+    /// and return the value if it doesn't exist.
+    pub fn find_or_insert<'a>(&'a mut self, k: K, v: V) -> &'a mut V {
+        self.find_with_or_insert_with(k, v, |_k, _v, _a| (), |_k, a| a)
+    }
+
+    /// Return the value corresponding to the key in the map, or create,
+    /// insert, and return a new value if it doesn't exist.
+    pub fn find_or_insert_with<'a>(&'a mut self, k: K, f: |&K| -> V)
+                               -> &'a mut V {
+        self.find_with_or_insert_with(k, (), |_k, _v, _a| (), |k, _a| f(k))
+    }
+
+    /// Insert a key-value pair into the map if the key is not already present.
+    /// Otherwise, modify the existing value for the key.
+    /// Returns the new or modified value for the key.
+    pub fn insert_or_update_with<'a>(
+                                 &'a mut self,
+                                 k: K,
+                                 v: V,
+                                 f: |&K, &mut V|)
+                                 -> &'a mut V {
+        self.find_with_or_insert_with(k, v, |k, v, _a| f(k, v), |_k, a| a)
+    }
+
+    /// Modify and return the value corresponding to the key in the map, or
+    /// insert and return a new value if it doesn't exist.
+    ///
+    /// This method allows for all insertion behaviours of a hashmap;
+    /// see methods like `insert`, `find_or_insert` and
+    /// `insert_or_update_with` for less general and more friendly
+    /// variations of this.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use collections::HashMap;
+    ///
+    /// // map some strings to vectors of strings
+    /// let mut map = HashMap::new();
+    /// map.insert("a key", vec!["value"]);
+    /// map.insert("z key", vec!["value"]);
+    ///
+    /// let new = vec!["a key", "b key", "z key"];
+    ///
+    /// for k in new.move_iter() {
+    ///     map.find_with_or_insert_with(
+    ///         k, "new value",
+    ///         // if the key does exist either prepend or append this
+    ///         // new value based on the first letter of the key.
+    ///         |key, already, new| {
+    ///             if key.as_slice().starts_with("z") {
+    ///                 already.unshift(new);
+    ///             } else {
+    ///                 already.push(new);
+    ///             }
+    ///         },
+    ///         // if the key doesn't exist in the map yet, add it in
+    ///         // the obvious way.
+    ///         |_k, v| vec![v]);
+    /// }
+    ///
+    /// assert_eq!(map.len(), 3);
+    /// assert_eq!(map.get(&"a key"), &vec!["value", "new value"]);
+    /// assert_eq!(map.get(&"b key"), &vec!["new value"]);
+    /// assert_eq!(map.get(&"z key"), &vec!["new value", "value"]);
+    /// ```
+    pub fn find_with_or_insert_with<'a, A>(&'a mut self,
+                                           k: K,
+                                           a: A,
+                                           found: |&K, &mut V, A|,
+                                           not_found: |&K, A| -> V)
+                                          -> &'a mut V {
+        let hash = self.make_hash(&k);
+        match self.search_hashed(&hash, &k) {
+            None => {
+                let v = not_found(&k, a);
+                self.insert_hashed(hash, k, v)
+            },
+            Some(idx) => {
+                let (_, v_ref) = self.table.read_mut(&idx);
+                found(&k, v_ref, a);
+                v_ref
+            }
+        }
+    }
+
+    /// Retrieves a value for the given key, failing if the key is not present.
+    pub fn get<'a>(&'a self, k: &K) -> &'a V {
+        match self.find(k) {
+            Some(v) => v,
+            None => fail!("no entry found for key")
+        }
+    }
+
+    /// Retrieves a (mutable) value for the given key, failing if the key is not present.
+    pub fn get_mut<'a>(&'a mut self, k: &K) -> &'a mut V {
+        match self.find_mut(k) {
+            Some(v) => v,
+            None => fail!("no entry found for key")
+        }
+    }
+
+    /// Return true if the map contains a value for the specified key,
+    /// using equivalence.
+    pub fn contains_key_equiv<Q: Hash<S> + Equiv<K>>(&self, key: &Q) -> bool {
+        self.search_equiv(key).is_some()
+    }
+
+    /// Return the value corresponding to the key in the map, using
+    /// equivalence.
+    pub fn find_equiv<'a, Q: Hash<S> + Equiv<K>>(&'a self, k: &Q) -> Option<&'a V> {
+        match self.search_equiv(k) {
+            None      => None,
+            Some(idx) => {
+                let (_, v_ref) = self.table.read(&idx);
+                Some(v_ref)
+            }
+        }
+    }
+
+    /// An iterator visiting all keys in arbitrary order.
+    /// Iterator element type is &'a K.
+    pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
+        self.iter().map(|(k, _v)| k)
+    }
+
+    /// An iterator visiting all values in arbitrary order.
+    /// Iterator element type is &'a V.
+    pub fn values<'a>(&'a self) -> Values<'a, K, V> {
+        self.iter().map(|(_k, v)| v)
+    }
+
+    /// An iterator visiting all key-value pairs in arbitrary order.
+    /// Iterator element type is (&'a K, &'a V).
+    pub fn iter<'a>(&'a self) -> Entries<'a, K, V> {
+        self.table.iter()
+    }
+
+    /// An iterator visiting all key-value pairs in arbitrary order,
+    /// with mutable references to the values.
+    /// Iterator element type is (&'a K, &'a mut V).
+    pub fn mut_iter<'a>(&'a mut self) -> MutEntries<'a, K, V> {
+        self.table.mut_iter()
+    }
+
+    /// Creates a consuming iterator, that is, one that moves each key-value
+    /// pair out of the map in arbitrary order. The map cannot be used after
+    /// calling this.
+    pub fn move_iter(self) -> MoveEntries<K, V> {
+        self.table.move_iter().map(|(_, k, v)| (k, v))
+    }
+}
+
+impl<K: Eq + Hash<S>, V: Clone, S, H: Hasher<S>> HashMap<K, V, H> {
+    /// Like `find`, but returns a copy of the value.
+    pub fn find_copy(&self, k: &K) -> Option<V> {
+        self.find(k).map(|v| (*v).clone())
+    }
+
+    /// Like `get`, but returns a copy of the value.
+    pub fn get_copy(&self, k: &K) -> V {
+        (*self.get(k)).clone()
+    }
+}
+
+impl<K: Eq + Hash<S>, V: PartialEq, S, H: Hasher<S>> PartialEq for HashMap<K, V, H> {
+    fn eq(&self, other: &HashMap<K, V, H>) -> bool {
+        if self.len() != other.len() { return false; }
+
+        self.iter()
+          .all(|(key, value)| {
+            match other.find(key) {
+                None    => false,
+                Some(v) => *value == *v
+            }
+        })
+    }
+}
+
+impl<K: Eq + Hash<S> + Show, V: Show, S, H: Hasher<S>> Show for HashMap<K, V, H> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(f, r"\{"));
+
+        for (i, (k, v)) in self.iter().enumerate() {
+            if i != 0 { try!(write!(f, ", ")); }
+            try!(write!(f, "{}: {}", *k, *v));
+        }
+
+        write!(f, r"\}")
+    }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Default for HashMap<K, V, H> {
+    fn default() -> HashMap<K, V, H> {
+        HashMap::with_hasher(Default::default())
+    }
+}
+
+/// HashMap iterator
+pub type Entries<'a, K, V> = table::Entries<'a, K, V>;
+
+/// HashMap mutable values iterator
+pub type MutEntries<'a, K, V> = table::MutEntries<'a, K, V>;
+
+/// HashMap move iterator
+pub type MoveEntries<K, V> =
+    iter::Map<'static, (table::SafeHash, K, V), (K, V), table::MoveEntries<K, V>>;
+
+/// HashMap keys iterator
+pub type Keys<'a, K, V> =
+    iter::Map<'static, (&'a K, &'a V), &'a K, Entries<'a, K, V>>;
+
+/// HashMap values iterator
+pub type Values<'a, K, V> =
+    iter::Map<'static, (&'a K, &'a V), &'a V, Entries<'a, K, V>>;
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> FromIterator<(K, V)> for HashMap<K, V, H> {
+    fn from_iter<T: Iterator<(K, V)>>(iter: T) -> HashMap<K, V, H> {
+        let (lower, _) = iter.size_hint();
+        let mut map = HashMap::with_capacity_and_hasher(lower, Default::default());
+        map.extend(iter);
+        map
+    }
+}
+
+impl<K: Eq + Hash<S>, V, S, H: Hasher<S> + Default> Extendable<(K, V)> for HashMap<K, V, H> {
+    fn extend<T: Iterator<(K, V)>>(&mut self, mut iter: T) {
+        for (k, v) in iter {
+            self.insert(k, v);
+        }
+    }
+}
+
+/// HashSet iterator
+pub type SetItems<'a, K> =
+    iter::Map<'static, (&'a K, &'a ()), &'a K, Entries<'a, K, ()>>;
+
+/// HashSet move iterator
+pub type SetMoveItems<K> =
+    iter::Map<'static, (K, ()), K, MoveEntries<K, ()>>;
+
+/// An implementation of a hash set using the underlying representation of a
+/// HashMap where the value is (). As with the `HashMap` type, a `HashSet`
+/// requires that the elements implement the `PartialEq` and `Hash` traits.
+#[deriving(Clone)]
+pub struct HashSet<T, H = sip::SipHasher> {
+    map: HashMap<T, (), H>
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
+    fn eq(&self, other: &HashSet<T, H>) -> bool {
+        if self.len() != other.len() { return false; }
+
+        self.iter().all(|key| other.contains(key))
+    }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Container for HashSet<T, H> {
+    fn len(&self) -> uint { self.map.len() }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
+    fn clear(&mut self) { self.map.clear() }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
+    fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
+
+    fn is_disjoint(&self, other: &HashSet<T, H>) -> bool {
+        self.iter().all(|v| !other.contains(v))
+    }
+
+    fn is_subset(&self, other: &HashSet<T, H>) -> bool {
+        self.iter().all(|v| other.contains(v))
+    }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
+    fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+
+    fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
+}
+
+impl<T: Hash + Eq> HashSet<T, sip::SipHasher> {
+    /// Create an empty HashSet
+    pub fn new() -> HashSet<T, sip::SipHasher> {
+        HashSet::with_capacity(INITIAL_CAPACITY)
+    }
+
+    /// Create an empty HashSet with space for at least `n` elements in
+    /// the hash table.
+    pub fn with_capacity(capacity: uint) -> HashSet<T, sip::SipHasher> {
+        HashSet { map: HashMap::with_capacity(capacity) }
+    }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
+    /// Creates a new empty hash set which will use the given hasher to hash
+    /// keys.
+    ///
+    /// The hash set is also created with the default initial capacity.
+    pub fn with_hasher(hasher: H) -> HashSet<T, H> {
+        HashSet::with_capacity_and_hasher(INITIAL_CAPACITY, hasher)
+    }
+
+    /// Create an empty HashSet with space for at least `capacity`
+    /// elements in the hash table, using `hasher` to hash the keys.
+    ///
+    /// Warning: `hasher` is normally randomly generated, and
+    /// is designed to allow `HashSet`s to be resistant to attacks that
+    /// cause many collisions and very poor performance. Setting it
+    /// manually using this function can expose a DoS attack vector.
+    pub fn with_capacity_and_hasher(capacity: uint, hasher: H) -> HashSet<T, H> {
+        HashSet { map: HashMap::with_capacity_and_hasher(capacity, hasher) }
+    }
+
+    /// Reserve space for at least `n` elements in the hash table.
+    pub fn reserve(&mut self, n: uint) {
+        self.map.reserve(n)
+    }
+
+    /// Returns true if the hash set contains a value equivalent to the
+    /// given query value.
+    pub fn contains_equiv<Q: Hash<S> + Equiv<T>>(&self, value: &Q) -> bool {
+      self.map.contains_key_equiv(value)
+    }
+
+    /// An iterator visiting all elements in arbitrary order.
+    /// Iterator element type is &'a T.
+    pub fn iter<'a>(&'a self) -> SetItems<'a, T> {
+        self.map.keys()
+    }
+
+    /// Creates a consuming iterator, that is, one that moves each value out
+    /// of the set in arbitrary order. The set cannot be used after calling
+    /// this.
+    pub fn move_iter(self) -> SetMoveItems<T> {
+        self.map.move_iter().map(|(k, _)| k)
+    }
+
+    /// Visit the values representing the difference
+    pub fn difference<'a>(&'a self, other: &'a HashSet<T, H>) -> SetAlgebraItems<'a, T, H> {
+        Repeat::new(other).zip(self.iter())
+            .filter_map(|(other, elt)| {
+                if !other.contains(elt) { Some(elt) } else { None }
+            })
+    }
+
+    /// Visit the values representing the symmetric difference
+    pub fn symmetric_difference<'a>(&'a self, other: &'a HashSet<T, H>)
+        -> Chain<SetAlgebraItems<'a, T, H>, SetAlgebraItems<'a, T, H>> {
+        self.difference(other).chain(other.difference(self))
+    }
+
+    /// Visit the values representing the intersection
+    pub fn intersection<'a>(&'a self, other: &'a HashSet<T, H>)
+        -> SetAlgebraItems<'a, T, H> {
+        Repeat::new(other).zip(self.iter())
+            .filter_map(|(other, elt)| {
+                if other.contains(elt) { Some(elt) } else { None }
+            })
+    }
+
+    /// Visit the values representing the union
+    pub fn union<'a>(&'a self, other: &'a HashSet<T, H>)
+        -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>> {
+        self.iter().chain(other.difference(self))
+    }
+}
+
+impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(f, r"\{"));
+
+        for (i, x) in self.iter().enumerate() {
+            if i != 0 { try!(write!(f, ", ")); }
+            try!(write!(f, "{}", *x));
+        }
+
+        write!(f, r"\}")
+    }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> FromIterator<T> for HashSet<T, H> {
+    fn from_iter<I: Iterator<T>>(iter: I) -> HashSet<T, H> {
+        let (lower, _) = iter.size_hint();
+        let mut set = HashSet::with_capacity_and_hasher(lower, Default::default());
+        set.extend(iter);
+        set
+    }
+}
+
+impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H> {
+    fn extend<I: Iterator<T>>(&mut self, mut iter: I) {
+        for k in iter {
+            self.insert(k);
+        }
+    }
+}
+
+impl<T: TotalEq + Hash<S>, S, H: Hasher<S> + Default> Default for HashSet<T, H> {
+    fn default() -> HashSet<T, H> {
+        HashSet::with_hasher(Default::default())
+    }
+}
+
+// `Repeat` is used to feed the filter closure an explicit capture
+// of a reference to the other set
+/// Set operations iterator
+pub type SetAlgebraItems<'a, T, H> =
+    FilterMap<'static, (&'a HashSet<T, H>, &'a T), &'a T,
+              Zip<Repeat<&'a HashSet<T, H>>, SetItems<'a, T>>>;
+
+#[cfg(test)]
+mod test_map {
+    use super::HashMap;
+    use std::cmp::Equiv;
+    use std::hash::Hash;
+    use std::iter::{Iterator,range_inclusive,range_step_inclusive};
+    use std::cell::RefCell;
+
+    struct KindaIntLike(int);
+
+    impl Equiv<int> for KindaIntLike {
+        fn equiv(&self, other: &int) -> bool {
+            let KindaIntLike(this) = *self;
+            this == *other
+        }
+    }
+    impl<S: Writer> Hash<S> for KindaIntLike {
+        fn hash(&self, state: &mut S) {
+            let KindaIntLike(this) = *self;
+            this.hash(state)
+        }
+    }
+
+    #[test]
+    fn test_create_capacity_zero() {
+        let mut m = HashMap::with_capacity(0);
+
+        assert!(m.insert(1, 1));
+
+        assert!(m.contains_key(&1));
+        assert!(!m.contains_key(&0));
+    }
+
+    #[test]
+    fn test_insert() {
+        let mut m = HashMap::new();
+        assert_eq!(m.len(), 0);
+        assert!(m.insert(1, 2));
+        assert_eq!(m.len(), 1);
+        assert!(m.insert(2, 4));
+        assert_eq!(m.len(), 2);
+        assert_eq!(*m.find(&1).unwrap(), 2);
+        assert_eq!(*m.find(&2).unwrap(), 4);
+    }
+
+    local_data_key!(drop_vector: RefCell<Vec<int>>)
+
+    #[deriving(Hash, PartialEq, Eq)]
+    struct Dropable {
+        k: uint
+    }
+
+
+    impl Dropable {
+        fn new(k: uint) -> Dropable {
+            let v = drop_vector.get().unwrap();
+            v.borrow_mut().as_mut_slice()[k] += 1;
+
+            Dropable { k: k }
+        }
+    }
+
+    impl Drop for Dropable {
+        fn drop(&mut self) {
+            let v = drop_vector.get().unwrap();
+            v.borrow_mut().as_mut_slice()[self.k] -= 1;
+        }
+    }
+
+    #[test]
+    fn test_drops() {
+        drop_vector.replace(Some(RefCell::new(Vec::from_elem(200, 0))));
+
+        {
+            let mut m = HashMap::new();
+
+            let v = drop_vector.get().unwrap();
+            for i in range(0u, 200) {
+                assert_eq!(v.borrow().as_slice()[i], 0);
+            }
+            drop(v);
+
+            for i in range(0u, 100) {
+                let d1 = Dropable::new(i);
+                let d2 = Dropable::new(i+100);
+                m.insert(d1, d2);
+            }
+
+            let v = drop_vector.get().unwrap();
+            for i in range(0u, 200) {
+                assert_eq!(v.borrow().as_slice()[i], 1);
+            }
+            drop(v);
+
+            for i in range(0u, 50) {
+                let k = Dropable::new(i);
+                let v = m.pop(&k);
+
+                assert!(v.is_some());
+
+                let v = drop_vector.get().unwrap();
+                assert_eq!(v.borrow().as_slice()[i], 1);
+                assert_eq!(v.borrow().as_slice()[i+100], 1);
+            }
+
+            let v = drop_vector.get().unwrap();
+            for i in range(0u, 50) {
+                assert_eq!(v.borrow().as_slice()[i], 0);
+                assert_eq!(v.borrow().as_slice()[i+100], 0);
+            }
+
+            for i in range(50u, 100) {
+                assert_eq!(v.borrow().as_slice()[i], 1);
+                assert_eq!(v.borrow().as_slice()[i+100], 1);
+            }
+        }
+
+        let v = drop_vector.get().unwrap();
+        for i in range(0u, 200) {
+            assert_eq!(v.borrow().as_slice()[i], 0);
+        }
+    }
+
+    #[test]
+    fn test_empty_pop() {
+        let mut m: HashMap<int, bool> = HashMap::new();
+        assert_eq!(m.pop(&0), None);
+    }
+
+    #[test]
+    fn test_lots_of_insertions() {
+        let mut m = HashMap::new();
+
+        // Try this a few times to make sure we never screw up the hashmap's
+        // internal state.
+        for _ in range(0, 10) {
+            assert!(m.is_empty());
+
+            for i in range_inclusive(1, 1000) {
+                assert!(m.insert(i, i));
+
+                for j in range_inclusive(1, i) {
+                    let r = m.find(&j);
+                    assert_eq!(r, Some(&j));
+                }
+
+                for j in range_inclusive(i+1, 1000) {
+                    let r = m.find(&j);
+                    assert_eq!(r, None);
+                }
+            }
+
+            for i in range_inclusive(1001, 2000) {
+                assert!(!m.contains_key(&i));
+            }
+
+            // remove forwards
+            for i in range_inclusive(1, 1000) {
+                assert!(m.remove(&i));
+
+                for j in range_inclusive(1, i) {
+                    assert!(!m.contains_key(&j));
+                }
+
+                for j in range_inclusive(i+1, 1000) {
+                    assert!(m.contains_key(&j));
+                }
+            }
+
+            for i in range_inclusive(1, 1000) {
+                assert!(!m.contains_key(&i));
+            }
+
+            for i in range_inclusive(1, 1000) {
+                assert!(m.insert(i, i));
+            }
+
+            // remove backwards
+            for i in range_step_inclusive(1000, 1, -1) {
+                assert!(m.remove(&i));
+
+                for j in range_inclusive(i, 1000) {
+                    assert!(!m.contains_key(&j));
+                }
+
+                for j in range_inclusive(1, i-1) {
+                    assert!(m.contains_key(&j));
+                }
+            }
+        }
+    }
+
+    #[test]
+    fn test_find_mut() {
+        let mut m = HashMap::new();
+        assert!(m.insert(1, 12));
+        assert!(m.insert(2, 8));
+        assert!(m.insert(5, 14));
+        let new = 100;
+        match m.find_mut(&5) {
+            None => fail!(), Some(x) => *x = new
+        }
+        assert_eq!(m.find(&5), Some(&new));
+    }
+
+    #[test]
+    fn test_insert_overwrite() {
+        let mut m = HashMap::new();
+        assert!(m.insert(1, 2));
+        assert_eq!(*m.find(&1).unwrap(), 2);
+        assert!(!m.insert(1, 3));
+        assert_eq!(*m.find(&1).unwrap(), 3);
+    }
+
+    #[test]
+    fn test_insert_conflicts() {
+        let mut m = HashMap::with_capacity(4);
+        assert!(m.insert(1, 2));
+        assert!(m.insert(5, 3));
+        assert!(m.insert(9, 4));
+        assert_eq!(*m.find(&9).unwrap(), 4);
+        assert_eq!(*m.find(&5).unwrap(), 3);
+        assert_eq!(*m.find(&1).unwrap(), 2);
+    }
+
+    #[test]
+    fn test_conflict_remove() {
+        let mut m = HashMap::with_capacity(4);
+        assert!(m.insert(1, 2));
+        assert_eq!(*m.find(&1).unwrap(), 2);
+        assert!(m.insert(5, 3));
+        assert_eq!(*m.find(&1).unwrap(), 2);
+        assert_eq!(*m.find(&5).unwrap(), 3);
+        assert!(m.insert(9, 4));
+        assert_eq!(*m.find(&1).unwrap(), 2);
+        assert_eq!(*m.find(&5).unwrap(), 3);
+        assert_eq!(*m.find(&9).unwrap(), 4);
+        assert!(m.remove(&1));
+        assert_eq!(*m.find(&9).unwrap(), 4);
+        assert_eq!(*m.find(&5).unwrap(), 3);
+    }
+
+    #[test]
+    fn test_is_empty() {
+        let mut m = HashMap::with_capacity(4);
+        assert!(m.insert(1, 2));
+        assert!(!m.is_empty());
+        assert!(m.remove(&1));
+        assert!(m.is_empty());
+    }
+
+    #[test]
+    fn test_pop() {
+        let mut m = HashMap::new();
+        m.insert(1, 2);
+        assert_eq!(m.pop(&1), Some(2));
+        assert_eq!(m.pop(&1), None);
+    }
+
+    #[test]
+    #[allow(experimental)]
+    fn test_pop_equiv() {
+        let mut m = HashMap::new();
+        m.insert(1, 2);
+        assert_eq!(m.pop_equiv(&KindaIntLike(1)), Some(2));
+        assert_eq!(m.pop_equiv(&KindaIntLike(1)), None);
+    }
+
+    #[test]
+    fn test_swap() {
+        let mut m = HashMap::new();
+        assert_eq!(m.swap(1, 2), None);
+        assert_eq!(m.swap(1, 3), Some(2));
+        assert_eq!(m.swap(1, 4), Some(3));
+    }
+
+    #[test]
+    fn test_move_iter() {
+        let hm = {
+            let mut hm = HashMap::new();
+
+            hm.insert('a', 1);
+            hm.insert('b', 2);
+
+            hm
+        };
+
+        let v = hm.move_iter().collect::<Vec<(char, int)>>();
+        assert!([('a', 1), ('b', 2)] == v.as_slice() || [('b', 2), ('a', 1)] == v.as_slice());
+    }
+
+    #[test]
+    fn test_iterate() {
+        let mut m = HashMap::with_capacity(4);
+        for i in range(0u, 32) {
+            assert!(m.insert(i, i*2));
+        }
+        assert_eq!(m.len(), 32);
+
+        let mut observed: u32 = 0;
+
+        for (k, v) in m.iter() {
+            assert_eq!(*v, *k * 2);
+            observed |= 1 << *k;
+        }
+        assert_eq!(observed, 0xFFFF_FFFF);
+    }
+
+    #[test]
+    fn test_keys() {
+        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+        let map = vec.move_iter().collect::<HashMap<int, char>>();
+        let keys = map.keys().map(|&k| k).collect::<Vec<int>>();
+        assert_eq!(keys.len(), 3);
+        assert!(keys.contains(&1));
+        assert!(keys.contains(&2));
+        assert!(keys.contains(&3));
+    }
+
+    #[test]
+    fn test_values() {
+        let vec = vec![(1, 'a'), (2, 'b'), (3, 'c')];
+        let map = vec.move_iter().collect::<HashMap<int, char>>();
+        let values = map.values().map(|&v| v).collect::<Vec<char>>();
+        assert_eq!(values.len(), 3);
+        assert!(values.contains(&'a'));
+        assert!(values.contains(&'b'));
+        assert!(values.contains(&'c'));
+    }
+
+    #[test]
+    fn test_find() {
+        let mut m = HashMap::new();
+        assert!(m.find(&1).is_none());
+        m.insert(1, 2);
+        match m.find(&1) {
+            None => fail!(),
+            Some(v) => assert_eq!(*v, 2)
+        }
+    }
+
+    #[test]
+    fn test_eq() {
+        let mut m1 = HashMap::new();
+        m1.insert(1, 2);
+        m1.insert(2, 3);
+        m1.insert(3, 4);
+
+        let mut m2 = HashMap::new();
+        m2.insert(1, 2);
+        m2.insert(2, 3);
+
+        assert!(m1 != m2);
+
+        m2.insert(3, 4);
+
+        assert_eq!(m1, m2);
+    }
+
+    #[test]
+    fn test_show() {
+        let mut map: HashMap<int, int> = HashMap::new();
+        let empty: HashMap<int, int> = HashMap::new();
+
+        map.insert(1, 2);
+        map.insert(3, 4);
+
+        let map_str = format!("{}", map);
+
+        assert!(map_str == "{1: 2, 3: 4}".to_string() || map_str == "{3: 4, 1: 2}".to_string());
+        assert_eq!(format!("{}", empty), "{}".to_string());
+    }
+
+    #[test]
+    fn test_expand() {
+        let mut m = HashMap::new();
+
+        assert_eq!(m.len(), 0);
+        assert!(m.is_empty());
+
+        let mut i = 0u;
+        let old_cap = m.table.capacity();
+        while old_cap == m.table.capacity() {
+            m.insert(i, i);
+            i += 1;
+        }
+
+        assert_eq!(m.len(), i);
+        assert!(!m.is_empty());
+    }
+
+    #[test]
+    fn test_resize_policy() {
+        let mut m = HashMap::new();
+
+        assert_eq!(m.len(), 0);
+        assert!(m.is_empty());
+
+        let initial_cap = m.table.capacity();
+        m.reserve(initial_cap * 2);
+        let cap = m.table.capacity();
+
+        assert_eq!(cap, initial_cap * 2);
+
+        let mut i = 0u;
+        for _ in range(0, cap * 3 / 4) {
+            m.insert(i, i);
+            i += 1;
+        }
+
+        assert_eq!(m.len(), i);
+        assert_eq!(m.table.capacity(), cap);
+
+        for _ in range(0, cap / 4) {
+            m.insert(i, i);
+            i += 1;
+        }
+
+        let new_cap = m.table.capacity();
+        assert_eq!(new_cap, cap * 2);
+
+        for _ in range(0, cap / 2) {
+            i -= 1;
+            m.remove(&i);
+            assert_eq!(m.table.capacity(), new_cap);
+        }
+
+        for _ in range(0, cap / 2 - 1) {
+            i -= 1;
+            m.remove(&i);
+        }
+
+        assert_eq!(m.table.capacity(), cap);
+        assert_eq!(m.len(), i);
+        assert!(!m.is_empty());
+    }
+
+    #[test]
+    fn test_find_equiv() {
+        let mut m = HashMap::new();
+
+        let (foo, bar, baz) = (1,2,3);
+        m.insert("foo".to_string(), foo);
+        m.insert("bar".to_string(), bar);
+        m.insert("baz".to_string(), baz);
+
+
+        assert_eq!(m.find_equiv(&("foo")), Some(&foo));
+        assert_eq!(m.find_equiv(&("bar")), Some(&bar));
+        assert_eq!(m.find_equiv(&("baz")), Some(&baz));
+
+        assert_eq!(m.find_equiv(&("qux")), None);
+    }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+        for &(k, v) in xs.iter() {
+            assert_eq!(map.find(&k), Some(&v));
+        }
+    }
+
+    #[test]
+    fn test_size_hint() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+        let mut iter = map.iter();
+
+        for _ in iter.by_ref().take(3) {}
+
+        assert_eq!(iter.size_hint(), (3, Some(3)));
+    }
+
+    #[test]
+    fn test_mut_size_hint() {
+        let xs = [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)];
+
+        let mut map: HashMap<int, int> = xs.iter().map(|&x| x).collect();
+
+        let mut iter = map.mut_iter();
+
+        for _ in iter.by_ref().take(3) {}
+
+        assert_eq!(iter.size_hint(), (3, Some(3)));
+    }
+}
+
+#[cfg(test)]
+mod test_set {
+    use super::HashSet;
+    use std::container::Container;
+    use std::slice::ImmutableEqVector;
+
+    #[test]
+    fn test_disjoint() {
+        let mut xs = HashSet::new();
+        let mut ys = HashSet::new();
+        assert!(xs.is_disjoint(&ys));
+        assert!(ys.is_disjoint(&xs));
+        assert!(xs.insert(5));
+        assert!(ys.insert(11));
+        assert!(xs.is_disjoint(&ys));
+        assert!(ys.is_disjoint(&xs));
+        assert!(xs.insert(7));
+        assert!(xs.insert(19));
+        assert!(xs.insert(4));
+        assert!(ys.insert(2));
+        assert!(ys.insert(-11));
+        assert!(xs.is_disjoint(&ys));
+        assert!(ys.is_disjoint(&xs));
+        assert!(ys.insert(7));
+        assert!(!xs.is_disjoint(&ys));
+        assert!(!ys.is_disjoint(&xs));
+    }
+
+    #[test]
+    fn test_subset_and_superset() {
+        let mut a = HashSet::new();
+        assert!(a.insert(0));
+        assert!(a.insert(5));
+        assert!(a.insert(11));
+        assert!(a.insert(7));
+
+        let mut b = HashSet::new();
+        assert!(b.insert(0));
+        assert!(b.insert(7));
+        assert!(b.insert(19));
+        assert!(b.insert(250));
+        assert!(b.insert(11));
+        assert!(b.insert(200));
+
+        assert!(!a.is_subset(&b));
+        assert!(!a.is_superset(&b));
+        assert!(!b.is_subset(&a));
+        assert!(!b.is_superset(&a));
+
+        assert!(b.insert(5));
+
+        assert!(a.is_subset(&b));
+        assert!(!a.is_superset(&b));
+        assert!(!b.is_subset(&a));
+        assert!(b.is_superset(&a));
+    }
+
+    #[test]
+    fn test_iterate() {
+        let mut a = HashSet::new();
+        for i in range(0u, 32) {
+            assert!(a.insert(i));
+        }
+        let mut observed: u32 = 0;
+        for k in a.iter() {
+            observed |= 1 << *k;
+        }
+        assert_eq!(observed, 0xFFFF_FFFF);
+    }
+
+    #[test]
+    fn test_intersection() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(11));
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(77));
+        assert!(a.insert(103));
+        assert!(a.insert(5));
+        assert!(a.insert(-5));
+
+        assert!(b.insert(2));
+        assert!(b.insert(11));
+        assert!(b.insert(77));
+        assert!(b.insert(-9));
+        assert!(b.insert(-42));
+        assert!(b.insert(5));
+        assert!(b.insert(3));
+
+        let mut i = 0;
+        let expected = [3, 5, 11, 77];
+        for x in a.intersection(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_difference() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(5));
+        assert!(a.insert(9));
+        assert!(a.insert(11));
+
+        assert!(b.insert(3));
+        assert!(b.insert(9));
+
+        let mut i = 0;
+        let expected = [1, 5, 11];
+        for x in a.difference(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_symmetric_difference() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(5));
+        assert!(a.insert(9));
+        assert!(a.insert(11));
+
+        assert!(b.insert(-2));
+        assert!(b.insert(3));
+        assert!(b.insert(9));
+        assert!(b.insert(14));
+        assert!(b.insert(22));
+
+        let mut i = 0;
+        let expected = [-2, 1, 5, 11, 14, 22];
+        for x in a.symmetric_difference(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_union() {
+        let mut a = HashSet::new();
+        let mut b = HashSet::new();
+
+        assert!(a.insert(1));
+        assert!(a.insert(3));
+        assert!(a.insert(5));
+        assert!(a.insert(9));
+        assert!(a.insert(11));
+        assert!(a.insert(16));
+        assert!(a.insert(19));
+        assert!(a.insert(24));
+
+        assert!(b.insert(-2));
+        assert!(b.insert(1));
+        assert!(b.insert(5));
+        assert!(b.insert(9));
+        assert!(b.insert(13));
+        assert!(b.insert(19));
+
+        let mut i = 0;
+        let expected = [-2, 1, 3, 5, 9, 11, 13, 16, 19, 24];
+        for x in a.union(&b) {
+            assert!(expected.contains(x));
+            i += 1
+        }
+        assert_eq!(i, expected.len());
+    }
+
+    #[test]
+    fn test_from_iter() {
+        let xs = [1, 2, 3, 4, 5, 6, 7, 8, 9];
+
+        let set: HashSet<int> = xs.iter().map(|&x| x).collect();
+
+        for x in xs.iter() {
+            assert!(set.contains(x));
+        }
+    }
+
+    #[test]
+    fn test_move_iter() {
+        let hs = {
+            let mut hs = HashSet::new();
+
+            hs.insert('a');
+            hs.insert('b');
+
+            hs
+        };
+
+        let v = hs.move_iter().collect::<Vec<char>>();
+        assert!(['a', 'b'] == v.as_slice() || ['b', 'a'] == v.as_slice());
+    }
+
+    #[test]
+    fn test_eq() {
+        // These constants once happened to expose a bug in insert().
+        // I'm keeping them around to prevent a regression.
+        let mut s1 = HashSet::new();
+
+        s1.insert(1);
+        s1.insert(2);
+        s1.insert(3);
+
+        let mut s2 = HashSet::new();
+
+        s2.insert(1);
+        s2.insert(2);
+
+        assert!(s1 != s2);
+
+        s2.insert(3);
+
+        assert_eq!(s1, s2);
+    }
+
+    #[test]
+    fn test_show() {
+        let mut set: HashSet<int> = HashSet::new();
+        let empty: HashSet<int> = HashSet::new();
+
+        set.insert(1);
+        set.insert(2);
+
+        let set_str = format!("{}", set);
+
+        assert!(set_str == "{1, 2}".to_string() || set_str == "{2, 1}".to_string());
+        assert_eq!(format!("{}", empty), "{}".to_string());
+    }
+}
+
+#[cfg(test)]
+mod bench {
+    extern crate test;
+    use self::test::Bencher;
+    use std::iter::{range_inclusive};
+
+    #[bench]
+    fn new_drop(b : &mut Bencher) {
+        use super::HashMap;
+
+        b.iter(|| {
+            let m : HashMap<int, int> = HashMap::new();
+            assert_eq!(m.len(), 0);
+        })
+    }
+
+    #[bench]
+    fn new_insert_drop(b : &mut Bencher) {
+        use super::HashMap;
+
+        b.iter(|| {
+            let mut m = HashMap::new();
+            m.insert(0, 0);
+            assert_eq!(m.len(), 1);
+        })
+    }
+
+    #[bench]
+    fn insert(b: &mut Bencher) {
+        use super::HashMap;
+
+        let mut m = HashMap::new();
+
+        for i in range_inclusive(1, 1000) {
+            m.insert(i, i);
+        }
+
+        let mut k = 1001;
+
+        b.iter(|| {
+            m.insert(k, k);
+            k += 1;
+        });
+    }
+
+    #[bench]
+    fn find_existing(b: &mut Bencher) {
+        use super::HashMap;
+
+        let mut m = HashMap::new();
+
+        for i in range_inclusive(1, 1000) {
+            m.insert(i, i);
+        }
+
+        b.iter(|| {
+            for i in range_inclusive(1, 1000) {
+                m.contains_key(&i);
+            }
+        });
+    }
+
+    #[bench]
+    fn find_nonexisting(b: &mut Bencher) {
+        use super::HashMap;
+
+        let mut m = HashMap::new();
+
+        for i in range_inclusive(1, 1000) {
+            m.insert(i, i);
+        }
+
+        b.iter(|| {
+            for i in range_inclusive(1001, 2000) {
+                m.contains_key(&i);
+            }
+        });
+    }
+
+    #[bench]
+    fn hashmap_as_queue(b: &mut Bencher) {
+        use super::HashMap;
+
+        let mut m = HashMap::new();
+
+        for i in range_inclusive(1, 1000) {
+            m.insert(i, i);
+        }
+
+        let mut k = 1;
+
+        b.iter(|| {
+            m.pop(&k);
+            m.insert(k + 1000, k + 1000);
+            k += 1;
+        });
+    }
+
+    #[bench]
+    fn find_pop_insert(b: &mut Bencher) {
+        use super::HashMap;
+
+        let mut m = HashMap::new();
+
+        for i in range_inclusive(1, 1000) {
+            m.insert(i, i);
+        }
+
+        let mut k = 1;
+
+        b.iter(|| {
+            m.find(&(k + 400));
+            m.find(&(k + 2000));
+            m.pop(&k);
+            m.insert(k + 1000, k + 1000);
+            k += 1;
+        })
+    }
+}
diff --git a/src/libstd/collections/lru_cache.rs b/src/libstd/collections/lru_cache.rs
new file mode 100644 (file)
index 0000000..0951131
--- /dev/null
@@ -0,0 +1,348 @@
+// 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.
+
+
+//! A cache that holds a limited number of key-value pairs. When the
+//! capacity of the cache is exceeded, the least-recently-used
+//! (where "used" means a look-up or putting the pair into the cache)
+//! pair is automatically removed.
+//!
+//! # Example
+//!
+//! ```rust
+//! use collections::LruCache;
+//!
+//! let mut cache: LruCache<int, int> = LruCache::new(2);
+//! cache.put(1, 10);
+//! cache.put(2, 20);
+//! cache.put(3, 30);
+//! assert!(cache.get(&1).is_none());
+//! assert_eq!(*cache.get(&2).unwrap(), 20);
+//! assert_eq!(*cache.get(&3).unwrap(), 30);
+//!
+//! cache.put(2, 22);
+//! assert_eq!(*cache.get(&2).unwrap(), 22);
+//!
+//! cache.put(6, 60);
+//! assert!(cache.get(&3).is_none());
+//!
+//! cache.change_capacity(1);
+//! assert!(cache.get(&2).is_none());
+//! ```
+
+use cmp::{Eq, TotalEq};
+use collections::HashMap;
+use container::{Container, Mutable, MutableMap};
+use fmt;
+use hash::Hash;
+use iter::{range, Iterator};
+use mem;
+use ops::Drop;
+use option::{Some, None, Option};
+use owned::Box;
+use ptr;
+use result::{Ok, Err};
+
+struct KeyRef<K> { k: *K }
+
+struct LruEntry<K, V> {
+    next: *mut LruEntry<K, V>,
+    prev: *mut LruEntry<K, V>,
+    key: K,
+    value: V,
+}
+
+/// An LRU Cache.
+pub struct LruCache<K, V> {
+    map: HashMap<KeyRef<K>, Box<LruEntry<K, V>>>,
+    max_size: uint,
+    head: *mut LruEntry<K, V>,
+}
+
+impl<S, K: Hash<S>> Hash<S> for KeyRef<K> {
+    fn hash(&self, state: &mut S) {
+        unsafe { (*self.k).hash(state) }
+    }
+}
+
+impl<K: PartialEq> PartialEq for KeyRef<K> {
+    fn eq(&self, other: &KeyRef<K>) -> bool {
+        unsafe{ (*self.k).eq(&*other.k) }
+    }
+}
+
+impl<K: Eq> Eq for KeyRef<K> {}
+
+impl<K, V> LruEntry<K, V> {
+    fn new(k: K, v: V) -> LruEntry<K, V> {
+        LruEntry {
+            key: k,
+            value: v,
+            next: ptr::mut_null(),
+            prev: ptr::mut_null(),
+        }
+    }
+}
+
+impl<K: Hash + Eq, V> LruCache<K, V> {
+    /// Create an LRU Cache that holds at most `capacity` items.
+    pub fn new(capacity: uint) -> LruCache<K, V> {
+        let cache = LruCache {
+            map: HashMap::new(),
+            max_size: capacity,
+            head: unsafe{ mem::transmute(box mem::uninitialized::<LruEntry<K, V>>()) },
+        };
+        unsafe {
+            (*cache.head).next = cache.head;
+            (*cache.head).prev = cache.head;
+        }
+        return cache;
+    }
+
+    /// Put a key-value pair into cache.
+    pub fn put(&mut self, k: K, v: V) {
+        let (node_ptr, node_opt) = match self.map.find_mut(&KeyRef{k: &k}) {
+            Some(node) => {
+                node.value = v;
+                let node_ptr: *mut LruEntry<K, V> = &mut **node;
+                (node_ptr, None)
+            }
+            None => {
+                let mut node = box LruEntry::new(k, v);
+                let node_ptr: *mut LruEntry<K, V> = &mut *node;
+                (node_ptr, Some(node))
+            }
+        };
+        match node_opt {
+            None => {
+                // Existing node, just update LRU position
+                self.detach(node_ptr);
+                self.attach(node_ptr);
+            }
+            Some(node) => {
+                let keyref = unsafe { &(*node_ptr).key };
+                self.map.swap(KeyRef{k: keyref}, node);
+                self.attach(node_ptr);
+                if self.len() > self.capacity() {
+                    self.remove_lru();
+                }
+            }
+        }
+    }
+
+    /// Return a value corresponding to the key in the cache.
+    pub fn get<'a>(&'a mut self, k: &K) -> Option<&'a V> {
+        let (value, node_ptr_opt) = match self.map.find_mut(&KeyRef{k: k}) {
+            None => (None, None),
+            Some(node) => {
+                let node_ptr: *mut LruEntry<K, V> = &mut **node;
+                (Some(unsafe { &(*node_ptr).value }), Some(node_ptr))
+            }
+        };
+        match node_ptr_opt {
+            None => (),
+            Some(node_ptr) => {
+                self.detach(node_ptr);
+                self.attach(node_ptr);
+            }
+        }
+        return value;
+    }
+
+    /// Remove and return a value corresponding to the key from the cache.
+    pub fn pop(&mut self, k: &K) -> Option<V> {
+        match self.map.pop(&KeyRef{k: k}) {
+            None => None,
+            Some(lru_entry) => Some(lru_entry.value)
+        }
+    }
+
+    /// Return the maximum number of key-value pairs the cache can hold.
+    pub fn capacity(&self) -> uint {
+        self.max_size
+    }
+
+    /// Change the number of key-value pairs the cache can hold. Remove
+    /// least-recently-used key-value pairs if necessary.
+    pub fn change_capacity(&mut self, capacity: uint) {
+        for _ in range(capacity, self.len()) {
+            self.remove_lru();
+        }
+        self.max_size = capacity;
+    }
+
+    #[inline]
+    fn remove_lru(&mut self) {
+        if self.len() > 0 {
+            let lru = unsafe { (*self.head).prev };
+            self.detach(lru);
+            self.map.pop(&KeyRef{k: unsafe { &(*lru).key }});
+        }
+    }
+
+    #[inline]
+    fn detach(&mut self, node: *mut LruEntry<K, V>) {
+        unsafe {
+            (*(*node).prev).next = (*node).next;
+            (*(*node).next).prev = (*node).prev;
+        }
+    }
+
+    #[inline]
+    fn attach(&mut self, node: *mut LruEntry<K, V>) {
+        unsafe {
+            (*node).next = (*self.head).next;
+            (*node).prev = self.head;
+            (*self.head).next = node;
+            (*(*node).next).prev = node;
+        }
+    }
+}
+
+impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
+    /// Return a string that lists the key-value pairs from most-recently
+    /// used to least-recently used.
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(f, r"\{"));
+        let mut cur = self.head;
+        for i in range(0, self.len()) {
+            if i > 0 { try!(write!(f, ", ")) }
+            unsafe {
+                cur = (*cur).next;
+                try!(write!(f, "{}", (*cur).key));
+            }
+            try!(write!(f, ": "));
+            unsafe {
+                try!(write!(f, "{}", (*cur).value));
+            }
+        }
+        write!(f, r"\}")
+    }
+}
+
+impl<K: Hash + Eq, V> Container for LruCache<K, V> {
+    /// Return the number of key-value pairs in the cache.
+    fn len(&self) -> uint {
+        self.map.len()
+    }
+}
+
+impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
+    /// Clear the cache of all key-value pairs.
+    fn clear(&mut self) {
+        self.map.clear();
+    }
+}
+
+#[unsafe_destructor]
+impl<K, V> Drop for LruCache<K, V> {
+    fn drop(&mut self) {
+        unsafe {
+            let node: Box<LruEntry<K, V>> = mem::transmute(self.head);
+            // Prevent compiler from trying to drop the un-initialized field in the sigil node.
+            let box LruEntry { key: k, value: v, .. } = node;
+            mem::forget(k);
+            mem::forget(v);
+        }
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::LruCache;
+
+    fn assert_opt_eq<V: PartialEq>(opt: Option<&V>, v: V) {
+        assert!(opt.is_some());
+        assert!(opt.unwrap() == &v);
+    }
+
+    #[test]
+    fn test_put_and_get() {
+        let mut cache: LruCache<int, int> = LruCache::new(2);
+        cache.put(1, 10);
+        cache.put(2, 20);
+        assert_opt_eq(cache.get(&1), 10);
+        assert_opt_eq(cache.get(&2), 20);
+        assert_eq!(cache.len(), 2);
+    }
+
+    #[test]
+    fn test_put_update() {
+        let mut cache: LruCache<String, Vec<u8>> = LruCache::new(1);
+        cache.put("1".to_string(), vec![10, 10]);
+        cache.put("1".to_string(), vec![10, 19]);
+        assert_opt_eq(cache.get(&"1".to_string()), vec![10, 19]);
+        assert_eq!(cache.len(), 1);
+    }
+
+    #[test]
+    fn test_expire_lru() {
+        let mut cache: LruCache<String, String> = LruCache::new(2);
+        cache.put("foo1".to_string(), "bar1".to_string());
+        cache.put("foo2".to_string(), "bar2".to_string());
+        cache.put("foo3".to_string(), "bar3".to_string());
+        assert!(cache.get(&"foo1".to_string()).is_none());
+        cache.put("foo2".to_string(), "bar2update".to_string());
+        cache.put("foo4".to_string(), "bar4".to_string());
+        assert!(cache.get(&"foo3".to_string()).is_none());
+    }
+
+    #[test]
+    fn test_pop() {
+        let mut cache: LruCache<int, int> = LruCache::new(2);
+        cache.put(1, 10);
+        cache.put(2, 20);
+        assert_eq!(cache.len(), 2);
+        let opt1 = cache.pop(&1);
+        assert!(opt1.is_some());
+        assert_eq!(opt1.unwrap(), 10);
+        assert!(cache.get(&1).is_none());
+        assert_eq!(cache.len(), 1);
+    }
+
+    #[test]
+    fn test_change_capacity() {
+        let mut cache: LruCache<int, int> = LruCache::new(2);
+        assert_eq!(cache.capacity(), 2);
+        cache.put(1, 10);
+        cache.put(2, 20);
+        cache.change_capacity(1);
+        assert!(cache.get(&1).is_none());
+        assert_eq!(cache.capacity(), 1);
+    }
+
+    #[test]
+    fn test_to_str() {
+        let mut cache: LruCache<int, int> = LruCache::new(3);
+        cache.put(1, 10);
+        cache.put(2, 20);
+        cache.put(3, 30);
+        assert_eq!(cache.to_str(), "{3: 30, 2: 20, 1: 10}".to_string());
+        cache.put(2, 22);
+        assert_eq!(cache.to_str(), "{2: 22, 3: 30, 1: 10}".to_string());
+        cache.put(6, 60);
+        assert_eq!(cache.to_str(), "{6: 60, 2: 22, 3: 30}".to_string());
+        cache.get(&3);
+        assert_eq!(cache.to_str(), "{3: 30, 6: 60, 2: 22}".to_string());
+        cache.change_capacity(2);
+        assert_eq!(cache.to_str(), "{3: 30, 6: 60}".to_string());
+    }
+
+    #[test]
+    fn test_clear() {
+        let mut cache: LruCache<int, int> = LruCache::new(2);
+        cache.put(1, 10);
+        cache.put(2, 20);
+        cache.clear();
+        assert!(cache.get(&1).is_none());
+        assert!(cache.get(&2).is_none());
+        assert_eq!(cache.to_str(), "{}".to_string());
+    }
+}
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
new file mode 100644 (file)
index 0000000..16a6a35
--- /dev/null
@@ -0,0 +1,25 @@
+// Copyright 2013-2014 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.
+
+/*!
+ * Collection types.
+ */
+
+pub use core_collections::{Bitv, BitvSet, BTree, Deque, DList, EnumSet};
+pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap};
+pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet};
+pub use core_collections::{bitv, btree, deque, dlist, enum_set};
+pub use core_collections::{priority_queue, ringbuf, smallintmap, treemap, trie};
+
+pub use self::hashmap::{HashMap, HashSet};
+pub use self::lru_cache::LruCache;
+
+pub mod hashmap;
+pub mod lru_cache;
index 62bb8e4d969f0221b580552b94dcef7da313e04e..4394fb9d35556a77dc5fe3273ef0b97ea92a1caf 100644 (file)
@@ -11,6 +11,8 @@
 //! The `FromStr` trait for types that can be created from strings
 
 use option::{Option, Some, None};
+use string::String;
+use str::StrAllocating;
 
 /// A trait to abstract the idea of creating a new instance of a type from a
 /// string.
@@ -47,6 +49,13 @@ fn from_str(s: &str) -> Option<bool> {
     }
 }
 
+impl FromStr for String {
+    #[inline]
+    fn from_str(s: &str) -> Option<String> {
+        Some(s.to_string())
+    }
+}
+
 #[cfg(test)]
 mod test {
     use prelude::*;
diff --git a/src/libstd/hash/mod.rs b/src/libstd/hash/mod.rs
deleted file mode 100644 (file)
index 8e95263..0000000
+++ /dev/null
@@ -1,391 +0,0 @@
-// Copyright 2012-2014 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.
-
-/*!
- * Generic hashing support.
- *
- * This module provides a generic way to compute the hash of a value. The
- * simplest way to make a type hashable is to use `#[deriving(Hash)]`:
- *
- * # Example
- *
- * ```rust
- * use std::hash;
- * use std::hash::Hash;
- *
- * #[deriving(Hash)]
- * struct Person {
- *     id: uint,
- *     name: String,
- *     phone: u64,
- * }
- *
- * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
- * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
- *
- * assert!(hash::hash(&person1) != hash::hash(&person2));
- * ```
- *
- * If you need more control over how a value is hashed, you need to implement
- * the trait `Hash`:
- *
- * ```rust
- * use std::hash;
- * use std::hash::Hash;
- * use std::hash::sip::SipState;
- *
- * struct Person {
- *     id: uint,
- *     name: String,
- *     phone: u64,
- * }
- *
- * impl Hash for Person {
- *     fn hash(&self, state: &mut SipState) {
- *         self.id.hash(state);
- *         self.phone.hash(state);
- *     }
- * }
- *
- * let person1 = Person { id: 5, name: "Janet".to_string(), phone: 555_666_7777 };
- * let person2 = Person { id: 5, name: "Bob".to_string(), phone: 555_666_7777 };
- *
- * assert!(hash::hash(&person1) == hash::hash(&person2));
- * ```
- */
-
-#![allow(unused_must_use)]
-
-use container::Container;
-use intrinsics::TypeId;
-use iter::Iterator;
-use option::{Option, Some, None};
-use owned::Box;
-use rc::Rc;
-use result::{Result, Ok, Err};
-use slice::{Vector, ImmutableVector};
-use str::{Str, StrSlice};
-use vec::Vec;
-
-/// Reexport the `sip::hash` function as our default hasher.
-pub use hash = self::sip::hash;
-
-pub use Writer = io::Writer;
-
-pub mod sip;
-
-/// A trait that represents a hashable type. The `S` type parameter is an
-/// abstract hash state that is used by the `Hash` to compute the hash.
-/// It defaults to `std::hash::sip::SipState`.
-pub trait Hash<S = sip::SipState> {
-    /// Compute a hash of the value.
-    fn hash(&self, state: &mut S);
-}
-
-/// A trait that computes a hash for a value. The main users of this trait are
-/// containers like `HashMap`, which need a generic way hash multiple types.
-pub trait Hasher<S> {
-    /// Compute a hash of the value.
-    fn hash<T: Hash<S>>(&self, value: &T) -> u64;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-macro_rules! impl_hash(
-    ( $( $ty:ty => $method:ident;)* ) => (
-        $(
-            impl<S: Writer> Hash<S> for $ty {
-                #[inline]
-                fn hash(&self, state: &mut S) {
-                    state.$method(*self);
-                }
-            }
-        )*
-    )
-)
-
-impl_hash!(
-    u8 => write_u8;
-    u16 => write_le_u16;
-    u32 => write_le_u32;
-    u64 => write_le_u64;
-    uint => write_le_uint;
-    i8 => write_i8;
-    i16 => write_le_i16;
-    i32 => write_le_i32;
-    i64 => write_le_i64;
-    int => write_le_int;
-)
-
-impl<S: Writer> Hash<S> for bool {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (*self as u8).hash(state);
-    }
-}
-
-impl<S: Writer> Hash<S> for char {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (*self as u32).hash(state);
-    }
-}
-
-impl<'a, S: Writer> Hash<S> for &'a str {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        state.write(self.as_bytes());
-        state.write_u8(0xFF);
-    }
-}
-
-macro_rules! impl_hash_tuple(
-    () => (
-        impl<S: Writer> Hash<S> for () {
-            #[inline]
-            fn hash(&self, state: &mut S) {
-                state.write([]);
-            }
-        }
-    );
-
-    ($A:ident $($B:ident)*) => (
-        impl<
-            S: Writer,
-            $A: Hash<S> $(, $B: Hash<S>)*
-        > Hash<S> for ($A, $($B),*) {
-            #[inline]
-            fn hash(&self, state: &mut S) {
-                match *self {
-                    (ref $A, $(ref $B),*) => {
-                        $A.hash(state);
-                        $(
-                            $B.hash(state);
-                        )*
-                    }
-                }
-            }
-        }
-
-        impl_hash_tuple!($($B)*)
-    );
-)
-
-impl_hash_tuple!(a0 a1 a2 a3 a4 a5 a6 a7)
-
-impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a [T] {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.len().hash(state);
-        for elt in self.iter() {
-            elt.hash(state);
-        }
-    }
-}
-
-
-impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a mut [T] {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.as_slice().hash(state);
-    }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for ~[T] {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.as_slice().hash(state);
-    }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for Vec<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.as_slice().hash(state);
-    }
-}
-
-impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-
-impl<'a, S: Writer, T: Hash<S>> Hash<S> for &'a mut T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for Box<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for @T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for Rc<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        (**self).hash(state);
-    }
-}
-
-impl<S: Writer, T: Hash<S>> Hash<S> for Option<T> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        match *self {
-            Some(ref x) => {
-                0u8.hash(state);
-                x.hash(state);
-            }
-            None => {
-                1u8.hash(state);
-            }
-        }
-    }
-}
-
-impl<S: Writer, T> Hash<S> for *T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        // NB: raw-pointer Hash does _not_ dereference
-        // to the target; it just gives you the pointer-bytes.
-        (*self as uint).hash(state);
-    }
-}
-
-impl<S: Writer, T> Hash<S> for *mut T {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        // NB: raw-pointer Hash does _not_ dereference
-        // to the target; it just gives you the pointer-bytes.
-        (*self as uint).hash(state);
-    }
-}
-
-impl<S: Writer> Hash<S> for TypeId {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        self.hash().hash(state)
-    }
-}
-
-impl<S: Writer, T: Hash<S>, U: Hash<S>> Hash<S> for Result<T, U> {
-    #[inline]
-    fn hash(&self, state: &mut S) {
-        match *self {
-            Ok(ref t) => { 1u.hash(state); t.hash(state); }
-            Err(ref t) => { 2u.hash(state); t.hash(state); }
-        }
-    }
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-#[cfg(test)]
-mod tests {
-    use mem;
-    use io::{IoResult, Writer};
-    use iter::{Iterator};
-    use option::{Some, None};
-    use result::Ok;
-    use slice::ImmutableVector;
-
-    use super::{Hash, Hasher};
-
-    struct MyWriterHasher;
-
-    impl Hasher<MyWriter> for MyWriterHasher {
-        fn hash<T: Hash<MyWriter>>(&self, value: &T) -> u64 {
-            let mut state = MyWriter { hash: 0 };
-            value.hash(&mut state);
-            state.hash
-        }
-    }
-
-    struct MyWriter {
-        hash: u64,
-    }
-
-    impl Writer for MyWriter {
-        // Most things we'll just add up the bytes.
-        fn write(&mut self, buf: &[u8]) -> IoResult<()> {
-            for byte in buf.iter() {
-                self.hash += *byte as u64;
-            }
-            Ok(())
-        }
-    }
-
-    #[test]
-    fn test_writer_hasher() {
-        let hasher = MyWriterHasher;
-
-        assert_eq!(hasher.hash(&()), 0);
-
-        assert_eq!(hasher.hash(&5u8), 5);
-        assert_eq!(hasher.hash(&5u16), 5);
-        assert_eq!(hasher.hash(&5u32), 5);
-        assert_eq!(hasher.hash(&5u64), 5);
-        assert_eq!(hasher.hash(&5u), 5);
-
-        assert_eq!(hasher.hash(&5i8), 5);
-        assert_eq!(hasher.hash(&5i16), 5);
-        assert_eq!(hasher.hash(&5i32), 5);
-        assert_eq!(hasher.hash(&5i64), 5);
-        assert_eq!(hasher.hash(&5i), 5);
-
-        assert_eq!(hasher.hash(&false), 0);
-        assert_eq!(hasher.hash(&true), 1);
-
-        assert_eq!(hasher.hash(&'a'), 97);
-
-        assert_eq!(hasher.hash(&("a")), 97 + 0xFF);
-        assert_eq!(hasher.hash(& &[1u8, 2u8, 3u8]), 9);
-
-        unsafe {
-            let ptr: *int = mem::transmute(5);
-            assert_eq!(hasher.hash(&ptr), 5);
-        }
-
-        unsafe {
-            let ptr: *mut int = mem::transmute(5);
-            assert_eq!(hasher.hash(&ptr), 5);
-        }
-    }
-
-    struct Custom {
-        hash: u64
-    }
-
-    impl Hash<u64> for Custom {
-        fn hash(&self, state: &mut u64) {
-            *state = self.hash;
-        }
-    }
-
-    #[test]
-    fn test_custom_state() {
-        let custom = Custom { hash: 5 };
-        let mut state = 0;
-        custom.hash(&mut state);
-        assert_eq!(state, 5);
-    }
-}
diff --git a/src/libstd/hash/sip.rs b/src/libstd/hash/sip.rs
deleted file mode 100644 (file)
index 9076790..0000000
+++ /dev/null
@@ -1,651 +0,0 @@
-// Copyright 2012-2014 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.
-
-/*!
- * Implementation of SipHash 2-4
- *
- * See: http://131002.net/siphash/
- *
- * Consider this as a main "general-purpose" hash for all hashtables: it
- * runs at good speed (competitive with spooky and city) and permits
- * strong _keyed_ hashing. Key your hashtables from a strong RNG,
- * such as `rand::Rng`.
- *
- * Although the SipHash algorithm is considered to be cryptographically
- * strong, this implementation has not been reviewed for such purposes.
- * As such, all cryptographic uses of this implementation are strongly
- * discouraged.
- */
-
-use clone::Clone;
-use container::Container;
-use default::Default;
-use int;
-use io::{IoResult, Writer};
-use iter::Iterator;
-use result::Ok;
-use slice::ImmutableVector;
-use uint;
-
-use super::{Hash, Hasher};
-
-/// `SipState` computes a SipHash 2-4 hash over a stream of bytes.
-pub struct SipState {
-    k0: u64,
-    k1: u64,
-    length: uint, // how many bytes we've processed
-    v0: u64,      // hash state
-    v1: u64,
-    v2: u64,
-    v3: u64,
-    tail: u64, // unprocessed bytes le
-    ntail: uint,  // how many bytes in tail are valid
-}
-
-// sadly, these macro definitions can't appear later,
-// because they're needed in the following defs;
-// this design could be improved.
-
-macro_rules! u8to64_le (
-    ($buf:expr, $i:expr) =>
-    ($buf[0+$i] as u64 |
-     $buf[1+$i] as u64 << 8 |
-     $buf[2+$i] as u64 << 16 |
-     $buf[3+$i] as u64 << 24 |
-     $buf[4+$i] as u64 << 32 |
-     $buf[5+$i] as u64 << 40 |
-     $buf[6+$i] as u64 << 48 |
-     $buf[7+$i] as u64 << 56);
-    ($buf:expr, $i:expr, $len:expr) =>
-    ({
-        let mut t = 0;
-        let mut out = 0u64;
-        while t < $len {
-            out |= $buf[t+$i] as u64 << t*8;
-            t += 1;
-        }
-        out
-    });
-)
-
-macro_rules! rotl (
-    ($x:expr, $b:expr) =>
-    (($x << $b) | ($x >> (64 - $b)))
-)
-
-macro_rules! compress (
-    ($v0:expr, $v1:expr, $v2:expr, $v3:expr) =>
-    ({
-        $v0 += $v1; $v1 = rotl!($v1, 13); $v1 ^= $v0;
-        $v0 = rotl!($v0, 32);
-        $v2 += $v3; $v3 = rotl!($v3, 16); $v3 ^= $v2;
-        $v0 += $v3; $v3 = rotl!($v3, 21); $v3 ^= $v0;
-        $v2 += $v1; $v1 = rotl!($v1, 17); $v1 ^= $v2;
-        $v2 = rotl!($v2, 32);
-    })
-)
-
-impl SipState {
-    /// Create a `SipState` that is keyed off the provided keys.
-    #[inline]
-    pub fn new() -> SipState {
-        SipState::new_with_keys(0, 0)
-    }
-
-    /// Create a `SipState` that is keyed off the provided keys.
-    #[inline]
-    pub fn new_with_keys(key0: u64, key1: u64) -> SipState {
-        let mut state = SipState {
-            k0: key0,
-            k1: key1,
-            length: 0,
-            v0: 0,
-            v1: 0,
-            v2: 0,
-            v3: 0,
-            tail: 0,
-            ntail: 0,
-        };
-        state.reset();
-        state
-    }
-
-    /// Reset the state back to it's initial state.
-    #[inline]
-    pub fn reset(&mut self) {
-        self.length = 0;
-        self.v0 = self.k0 ^ 0x736f6d6570736575;
-        self.v1 = self.k1 ^ 0x646f72616e646f6d;
-        self.v2 = self.k0 ^ 0x6c7967656e657261;
-        self.v3 = self.k1 ^ 0x7465646279746573;
-        self.ntail = 0;
-    }
-
-    /// Return the computed hash.
-    #[inline]
-    pub fn result(&self) -> u64 {
-        let mut v0 = self.v0;
-        let mut v1 = self.v1;
-        let mut v2 = self.v2;
-        let mut v3 = self.v3;
-
-        let b: u64 = ((self.length as u64 & 0xff) << 56) | self.tail;
-
-        v3 ^= b;
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-        v0 ^= b;
-
-        v2 ^= 0xff;
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-        compress!(v0, v1, v2, v3);
-
-        v0 ^ v1 ^ v2 ^ v3
-    }
-
-    #[inline]
-    fn write_le(&mut self, n: u64, size: uint) {
-        self.tail |= n << 8*self.ntail;
-        self.ntail += size;
-
-        if self.ntail >= 8 {
-            let m = self.tail;
-
-            self.v3 ^= m;
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            self.v0 ^= m;
-
-            self.ntail -= 8;
-            if self.ntail == 0 {
-                self.tail = 0;
-            } else {
-                self.tail = n >> 64 - 8*self.ntail;
-            }
-        }
-    }
-}
-
-macro_rules! make_write_le(
-    ($this:expr, $n:expr, $size:expr) => ({
-          $this.write_le($n as u64, $size);
-          $this.length += $size;
-          Ok(())
-    })
-)
-
-impl Writer for SipState {
-    #[inline]
-    fn write(&mut self, msg: &[u8]) -> IoResult<()> {
-        let length = msg.len();
-        self.length += length;
-
-        let mut needed = 0u;
-
-        if self.ntail != 0 {
-            needed = 8 - self.ntail;
-            if length < needed {
-                self.tail |= u8to64_le!(msg, 0, length) << 8*self.ntail;
-                self.ntail += length;
-                return Ok(());
-            }
-
-            let m = self.tail | u8to64_le!(msg, 0, needed) << 8*self.ntail;
-
-            self.v3 ^= m;
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            self.v0 ^= m;
-
-            self.ntail = 0;
-        }
-
-        // Buffered tail is now flushed, process new input.
-        let len = length - needed;
-        let end = len & (!0x7);
-        let left = len & 0x7;
-
-        let mut i = needed;
-        while i < end {
-            let mi = u8to64_le!(msg, i);
-
-            self.v3 ^= mi;
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            compress!(self.v0, self.v1, self.v2, self.v3);
-            self.v0 ^= mi;
-
-            i += 8;
-        }
-
-        self.tail = u8to64_le!(msg, i, left);
-        self.ntail = left;
-
-        Ok(())
-    }
-
-    #[inline]
-    fn write_u8(&mut self, n: u8) -> IoResult<()> {
-        make_write_le!(self, n, 1)
-    }
-
-    #[inline]
-    fn write_le_u16(&mut self, n: u16) -> IoResult<()> {
-        make_write_le!(self, n, 2)
-    }
-
-    #[inline]
-    fn write_le_u32(&mut self, n: u32) -> IoResult<()> {
-        make_write_le!(self, n, 4)
-    }
-
-    #[inline]
-    fn write_le_u64(&mut self, n: u64) -> IoResult<()> {
-        make_write_le!(self, n, 8)
-    }
-
-    #[inline]
-    fn write_le_uint(&mut self, n: uint) -> IoResult<()> {
-        make_write_le!(self, n, uint::BYTES)
-    }
-
-    #[inline]
-    fn write_i8(&mut self, n: i8) -> IoResult<()> {
-        make_write_le!(self, n, 1)
-    }
-
-    #[inline]
-    fn write_le_i16(&mut self, n: i16) -> IoResult<()> {
-        make_write_le!(self, n, 2)
-    }
-
-    #[inline]
-    fn write_le_i32(&mut self, n: i32) -> IoResult<()> {
-        make_write_le!(self, n, 4)
-    }
-
-    #[inline]
-    fn write_le_i64(&mut self, n: i64) -> IoResult<()> {
-        make_write_le!(self, n, 8)
-    }
-
-    #[inline]
-    fn write_le_int(&mut self, n: int) -> IoResult<()> {
-        make_write_le!(self, n, int::BYTES)
-    }
-
-}
-
-impl Clone for SipState {
-    #[inline]
-    fn clone(&self) -> SipState {
-        *self
-    }
-}
-
-impl Default for SipState {
-    #[inline]
-    fn default() -> SipState {
-        SipState::new()
-    }
-}
-
-/// `SipHasher` computes the SipHash algorithm from a stream of bytes.
-#[deriving(Clone)]
-pub struct SipHasher {
-    k0: u64,
-    k1: u64,
-}
-
-impl SipHasher {
-    /// Create a `Sip`.
-    #[inline]
-    pub fn new() -> SipHasher {
-        SipHasher::new_with_keys(0, 0)
-    }
-
-    /// Create a `Sip` that is keyed off the provided keys.
-    #[inline]
-    pub fn new_with_keys(key0: u64, key1: u64) -> SipHasher {
-        SipHasher {
-            k0: key0,
-            k1: key1,
-        }
-    }
-}
-
-impl Hasher<SipState> for SipHasher {
-    #[inline]
-    fn hash<T: Hash<SipState>>(&self, value: &T) -> u64 {
-        let mut state = SipState::new_with_keys(self.k0, self.k1);
-        value.hash(&mut state);
-        state.result()
-    }
-}
-
-impl Default for SipHasher {
-    #[inline]
-    fn default() -> SipHasher {
-        SipHasher::new()
-    }
-}
-
-/// Hash a value using the SipHash algorithm.
-#[inline]
-pub fn hash<T: Hash<SipState>>(value: &T) -> u64 {
-    let mut state = SipState::new();
-    value.hash(&mut state);
-    state.result()
-}
-
-/// Hash a value with the SipHash algorithm with the provided keys.
-#[inline]
-pub fn hash_with_keys<T: Hash<SipState>>(k0: u64, k1: u64, value: &T) -> u64 {
-    let mut state = SipState::new_with_keys(k0, k1);
-    value.hash(&mut state);
-    state.result()
-}
-
-
-
-#[cfg(test)]
-mod tests {
-    extern crate test;
-    use prelude::*;
-    use num::ToStrRadix;
-    use option::{Some, None};
-    use str::Str;
-    use string::String;
-    use slice::{Vector, ImmutableVector};
-    use self::test::Bencher;
-
-    use super::super::Hash;
-    use super::{SipState, hash, hash_with_keys};
-
-    // Hash just the bytes of the slice, without length prefix
-    struct Bytes<'a>(&'a [u8]);
-
-    impl<'a, S: Writer> Hash<S> for Bytes<'a> {
-        #[allow(unused_must_use)]
-        fn hash(&self, state: &mut S) {
-            let Bytes(v) = *self;
-            state.write(v);
-        }
-    }
-
-    #[test]
-    #[allow(unused_must_use)]
-    fn test_siphash() {
-        let vecs : [[u8, ..8], ..64] = [
-            [ 0x31, 0x0e, 0x0e, 0xdd, 0x47, 0xdb, 0x6f, 0x72, ],
-            [ 0xfd, 0x67, 0xdc, 0x93, 0xc5, 0x39, 0xf8, 0x74, ],
-            [ 0x5a, 0x4f, 0xa9, 0xd9, 0x09, 0x80, 0x6c, 0x0d, ],
-            [ 0x2d, 0x7e, 0xfb, 0xd7, 0x96, 0x66, 0x67, 0x85, ],
-            [ 0xb7, 0x87, 0x71, 0x27, 0xe0, 0x94, 0x27, 0xcf, ],
-            [ 0x8d, 0xa6, 0x99, 0xcd, 0x64, 0x55, 0x76, 0x18, ],
-            [ 0xce, 0xe3, 0xfe, 0x58, 0x6e, 0x46, 0xc9, 0xcb, ],
-            [ 0x37, 0xd1, 0x01, 0x8b, 0xf5, 0x00, 0x02, 0xab, ],
-            [ 0x62, 0x24, 0x93, 0x9a, 0x79, 0xf5, 0xf5, 0x93, ],
-            [ 0xb0, 0xe4, 0xa9, 0x0b, 0xdf, 0x82, 0x00, 0x9e, ],
-            [ 0xf3, 0xb9, 0xdd, 0x94, 0xc5, 0xbb, 0x5d, 0x7a, ],
-            [ 0xa7, 0xad, 0x6b, 0x22, 0x46, 0x2f, 0xb3, 0xf4, ],
-            [ 0xfb, 0xe5, 0x0e, 0x86, 0xbc, 0x8f, 0x1e, 0x75, ],
-            [ 0x90, 0x3d, 0x84, 0xc0, 0x27, 0x56, 0xea, 0x14, ],
-            [ 0xee, 0xf2, 0x7a, 0x8e, 0x90, 0xca, 0x23, 0xf7, ],
-            [ 0xe5, 0x45, 0xbe, 0x49, 0x61, 0xca, 0x29, 0xa1, ],
-            [ 0xdb, 0x9b, 0xc2, 0x57, 0x7f, 0xcc, 0x2a, 0x3f, ],
-            [ 0x94, 0x47, 0xbe, 0x2c, 0xf5, 0xe9, 0x9a, 0x69, ],
-            [ 0x9c, 0xd3, 0x8d, 0x96, 0xf0, 0xb3, 0xc1, 0x4b, ],
-            [ 0xbd, 0x61, 0x79, 0xa7, 0x1d, 0xc9, 0x6d, 0xbb, ],
-            [ 0x98, 0xee, 0xa2, 0x1a, 0xf2, 0x5c, 0xd6, 0xbe, ],
-            [ 0xc7, 0x67, 0x3b, 0x2e, 0xb0, 0xcb, 0xf2, 0xd0, ],
-            [ 0x88, 0x3e, 0xa3, 0xe3, 0x95, 0x67, 0x53, 0x93, ],
-            [ 0xc8, 0xce, 0x5c, 0xcd, 0x8c, 0x03, 0x0c, 0xa8, ],
-            [ 0x94, 0xaf, 0x49, 0xf6, 0xc6, 0x50, 0xad, 0xb8, ],
-            [ 0xea, 0xb8, 0x85, 0x8a, 0xde, 0x92, 0xe1, 0xbc, ],
-            [ 0xf3, 0x15, 0xbb, 0x5b, 0xb8, 0x35, 0xd8, 0x17, ],
-            [ 0xad, 0xcf, 0x6b, 0x07, 0x63, 0x61, 0x2e, 0x2f, ],
-            [ 0xa5, 0xc9, 0x1d, 0xa7, 0xac, 0xaa, 0x4d, 0xde, ],
-            [ 0x71, 0x65, 0x95, 0x87, 0x66, 0x50, 0xa2, 0xa6, ],
-            [ 0x28, 0xef, 0x49, 0x5c, 0x53, 0xa3, 0x87, 0xad, ],
-            [ 0x42, 0xc3, 0x41, 0xd8, 0xfa, 0x92, 0xd8, 0x32, ],
-            [ 0xce, 0x7c, 0xf2, 0x72, 0x2f, 0x51, 0x27, 0x71, ],
-            [ 0xe3, 0x78, 0x59, 0xf9, 0x46, 0x23, 0xf3, 0xa7, ],
-            [ 0x38, 0x12, 0x05, 0xbb, 0x1a, 0xb0, 0xe0, 0x12, ],
-            [ 0xae, 0x97, 0xa1, 0x0f, 0xd4, 0x34, 0xe0, 0x15, ],
-            [ 0xb4, 0xa3, 0x15, 0x08, 0xbe, 0xff, 0x4d, 0x31, ],
-            [ 0x81, 0x39, 0x62, 0x29, 0xf0, 0x90, 0x79, 0x02, ],
-            [ 0x4d, 0x0c, 0xf4, 0x9e, 0xe5, 0xd4, 0xdc, 0xca, ],
-            [ 0x5c, 0x73, 0x33, 0x6a, 0x76, 0xd8, 0xbf, 0x9a, ],
-            [ 0xd0, 0xa7, 0x04, 0x53, 0x6b, 0xa9, 0x3e, 0x0e, ],
-            [ 0x92, 0x59, 0x58, 0xfc, 0xd6, 0x42, 0x0c, 0xad, ],
-            [ 0xa9, 0x15, 0xc2, 0x9b, 0xc8, 0x06, 0x73, 0x18, ],
-            [ 0x95, 0x2b, 0x79, 0xf3, 0xbc, 0x0a, 0xa6, 0xd4, ],
-            [ 0xf2, 0x1d, 0xf2, 0xe4, 0x1d, 0x45, 0x35, 0xf9, ],
-            [ 0x87, 0x57, 0x75, 0x19, 0x04, 0x8f, 0x53, 0xa9, ],
-            [ 0x10, 0xa5, 0x6c, 0xf5, 0xdf, 0xcd, 0x9a, 0xdb, ],
-            [ 0xeb, 0x75, 0x09, 0x5c, 0xcd, 0x98, 0x6c, 0xd0, ],
-            [ 0x51, 0xa9, 0xcb, 0x9e, 0xcb, 0xa3, 0x12, 0xe6, ],
-            [ 0x96, 0xaf, 0xad, 0xfc, 0x2c, 0xe6, 0x66, 0xc7, ],
-            [ 0x72, 0xfe, 0x52, 0x97, 0x5a, 0x43, 0x64, 0xee, ],
-            [ 0x5a, 0x16, 0x45, 0xb2, 0x76, 0xd5, 0x92, 0xa1, ],
-            [ 0xb2, 0x74, 0xcb, 0x8e, 0xbf, 0x87, 0x87, 0x0a, ],
-            [ 0x6f, 0x9b, 0xb4, 0x20, 0x3d, 0xe7, 0xb3, 0x81, ],
-            [ 0xea, 0xec, 0xb2, 0xa3, 0x0b, 0x22, 0xa8, 0x7f, ],
-            [ 0x99, 0x24, 0xa4, 0x3c, 0xc1, 0x31, 0x57, 0x24, ],
-            [ 0xbd, 0x83, 0x8d, 0x3a, 0xaf, 0xbf, 0x8d, 0xb7, ],
-            [ 0x0b, 0x1a, 0x2a, 0x32, 0x65, 0xd5, 0x1a, 0xea, ],
-            [ 0x13, 0x50, 0x79, 0xa3, 0x23, 0x1c, 0xe6, 0x60, ],
-            [ 0x93, 0x2b, 0x28, 0x46, 0xe4, 0xd7, 0x06, 0x66, ],
-            [ 0xe1, 0x91, 0x5f, 0x5c, 0xb1, 0xec, 0xa4, 0x6c, ],
-            [ 0xf3, 0x25, 0x96, 0x5c, 0xa1, 0x6d, 0x62, 0x9f, ],
-            [ 0x57, 0x5f, 0xf2, 0x8e, 0x60, 0x38, 0x1b, 0xe5, ],
-            [ 0x72, 0x45, 0x06, 0xeb, 0x4c, 0x32, 0x8a, 0x95, ]
-        ];
-
-        let k0 = 0x_07_06_05_04_03_02_01_00_u64;
-        let k1 = 0x_0f_0e_0d_0c_0b_0a_09_08_u64;
-        let mut buf = Vec::new();
-        let mut t = 0;
-        let mut state_inc = SipState::new_with_keys(k0, k1);
-        let mut state_full = SipState::new_with_keys(k0, k1);
-
-        fn to_hex_str(r: &[u8, ..8]) -> String {
-            let mut s = String::new();
-            for b in r.iter() {
-                s.push_str((*b as uint).to_str_radix(16u).as_slice());
-            }
-            s
-        }
-
-        fn result_bytes(h: u64) -> ~[u8] {
-            box [(h >> 0) as u8,
-              (h >> 8) as u8,
-              (h >> 16) as u8,
-              (h >> 24) as u8,
-              (h >> 32) as u8,
-              (h >> 40) as u8,
-              (h >> 48) as u8,
-              (h >> 56) as u8,
-            ]
-        }
-
-        fn result_str(h: u64) -> String {
-            let r = result_bytes(h);
-            let mut s = String::new();
-            for b in r.iter() {
-                s.push_str((*b as uint).to_str_radix(16u).as_slice());
-            }
-            s
-        }
-
-        while t < 64 {
-            debug!("siphash test {}", t);
-            let vec = u8to64_le!(vecs[t], 0);
-            let out = hash_with_keys(k0, k1, &Bytes(buf.as_slice()));
-            debug!("got {:?}, expected {:?}", out, vec);
-            assert_eq!(vec, out);
-
-            state_full.reset();
-            state_full.write(buf.as_slice());
-            let f = result_str(state_full.result());
-            let i = result_str(state_inc.result());
-            let v = to_hex_str(&vecs[t]);
-            debug!("{}: ({}) => inc={} full={}", t, v, i, f);
-
-            assert!(f == i && f == v);
-
-            buf.push(t as u8);
-            state_inc.write_u8(t as u8);
-
-            t += 1;
-        }
-    }
-
-    #[test] #[cfg(target_arch = "arm")]
-    fn test_hash_uint() {
-        let val = 0xdeadbeef_deadbeef_u64;
-        assert!(hash(&(val as u64)) != hash(&(val as uint)));
-        assert_eq!(hash(&(val as u32)), hash(&(val as uint)));
-    }
-    #[test] #[cfg(target_arch = "x86_64")]
-    fn test_hash_uint() {
-        let val = 0xdeadbeef_deadbeef_u64;
-        assert_eq!(hash(&(val as u64)), hash(&(val as uint)));
-        assert!(hash(&(val as u32)) != hash(&(val as uint)));
-    }
-    #[test] #[cfg(target_arch = "x86")]
-    fn test_hash_uint() {
-        let val = 0xdeadbeef_deadbeef_u64;
-        assert!(hash(&(val as u64)) != hash(&(val as uint)));
-        assert_eq!(hash(&(val as u32)), hash(&(val as uint)));
-    }
-
-    #[test]
-    fn test_hash_idempotent() {
-        let val64 = 0xdeadbeef_deadbeef_u64;
-        assert_eq!(hash(&val64), hash(&val64));
-        let val32 = 0xdeadbeef_u32;
-        assert_eq!(hash(&val32), hash(&val32));
-    }
-
-    #[test]
-    fn test_hash_no_bytes_dropped_64() {
-        let val = 0xdeadbeef_deadbeef_u64;
-
-        assert!(hash(&val) != hash(&zero_byte(val, 0)));
-        assert!(hash(&val) != hash(&zero_byte(val, 1)));
-        assert!(hash(&val) != hash(&zero_byte(val, 2)));
-        assert!(hash(&val) != hash(&zero_byte(val, 3)));
-        assert!(hash(&val) != hash(&zero_byte(val, 4)));
-        assert!(hash(&val) != hash(&zero_byte(val, 5)));
-        assert!(hash(&val) != hash(&zero_byte(val, 6)));
-        assert!(hash(&val) != hash(&zero_byte(val, 7)));
-
-        fn zero_byte(val: u64, byte: uint) -> u64 {
-            assert!(byte < 8);
-            val & !(0xff << (byte * 8))
-        }
-    }
-
-    #[test]
-    fn test_hash_no_bytes_dropped_32() {
-        let val = 0xdeadbeef_u32;
-
-        assert!(hash(&val) != hash(&zero_byte(val, 0)));
-        assert!(hash(&val) != hash(&zero_byte(val, 1)));
-        assert!(hash(&val) != hash(&zero_byte(val, 2)));
-        assert!(hash(&val) != hash(&zero_byte(val, 3)));
-
-        fn zero_byte(val: u32, byte: uint) -> u32 {
-            assert!(byte < 4);
-            val & !(0xff << (byte * 8))
-        }
-    }
-
-    #[test]
-    fn test_hash_no_concat_alias() {
-        let s = ("aa", "bb");
-        let t = ("aabb", "");
-        let u = ("a", "abb");
-
-        assert!(s != t && t != u);
-        assert!(hash(&s) != hash(&t) && hash(&s) != hash(&u));
-
-        let v = (&[1u8], &[0u8, 0], &[0u8]);
-        let w = (&[1u8, 0, 0, 0], &[], &[]);
-
-        assert!(v != w);
-        assert!(hash(&v) != hash(&w));
-    }
-
-    #[bench]
-    fn bench_str_under_8_bytes(b: &mut Bencher) {
-        let s = "foo";
-        b.iter(|| {
-            assert_eq!(hash(&s), 16262950014981195938);
-        })
-    }
-
-    #[bench]
-    fn bench_str_of_8_bytes(b: &mut Bencher) {
-        let s = "foobar78";
-        b.iter(|| {
-            assert_eq!(hash(&s), 4898293253460910787);
-        })
-    }
-
-    #[bench]
-    fn bench_str_over_8_bytes(b: &mut Bencher) {
-        let s = "foobarbaz0";
-        b.iter(|| {
-            assert_eq!(hash(&s), 10581415515220175264);
-        })
-    }
-
-    #[bench]
-    fn bench_long_str(b: &mut Bencher) {
-        let s = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor \
-incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud \
-exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute \
-irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla \
-pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui \
-officia deserunt mollit anim id est laborum.";
-        b.iter(|| {
-            assert_eq!(hash(&s), 17717065544121360093);
-        })
-    }
-
-    #[bench]
-    fn bench_u64(b: &mut Bencher) {
-        let u = 16262950014981195938u64;
-        b.iter(|| {
-            assert_eq!(hash(&u), 5254097107239593357);
-        })
-    }
-
-    #[deriving(Hash)]
-    struct Compound {
-        x: u8,
-        y: u64,
-    }
-
-    #[bench]
-    fn bench_compound_1(b: &mut Bencher) {
-        let compound = Compound {
-            x: 1,
-            y: 2,
-        };
-        b.iter(|| {
-            assert_eq!(hash(&compound), 12506681940457338191);
-        })
-    }
-}
index db84a724adb4ecdf655a275df710daec87dd4530..90d6677d61228024600bc3c579c84342cc96983a 100644 (file)
 extern crate core;
 extern crate libc;
 extern crate core_rand = "rand";
+extern crate core_collections = "collections";
 
 // Make std testable by not duplicating lang items. See #2912
 #[cfg(test)] extern crate realstd = "std";
 pub use alloc::owned;
 pub use alloc::rc;
 
+pub use core_collections::hash;
+pub use core_collections::slice;
+pub use core_collections::str;
+pub use core_collections::string;
+pub use core_collections::vec;
+
 // Run tests with libgreen instead of libnative.
 //
 // FIXME: This egregiously hacks around starting the test runner in a different
@@ -203,10 +210,6 @@ fn start(argc: int, argv: **u8) -> int {
 #[path = "num/f32.rs"]   pub mod f32;
 #[path = "num/f64.rs"]   pub mod f64;
 
-pub mod slice;
-pub mod vec;
-pub mod str;
-pub mod string;
 pub mod rand;
 
 pub mod ascii;
@@ -218,7 +221,10 @@ fn start(argc: int, argv: **u8) -> int {
 pub mod from_str;
 pub mod num;
 pub mod to_str;
-pub mod hash;
+
+/* Common data structures */
+
+pub mod collections;
 
 /* Tasks and communication */
 
@@ -242,10 +248,6 @@ fn start(argc: int, argv: **u8) -> int {
 #[unstable]
 pub mod unstable;
 
-/* For internal use, not exported */
-
-mod unicode;
-
 // FIXME #7809: This shouldn't be pub, and it should be reexported under 'unstable'
 // but name resolution doesn't work without it being pub.
 #[unstable]
index a6bbf22b4019095f3d739fa2625c166021487b27..8dfb64194e7977d1b0809d5fcbe9cf96583e1e99 100644 (file)
 
 //! POSIX file path handling
 
-use container::Container;
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq};
+use container::Container;
 use from_str::FromStr;
+use hash;
 use io::Writer;
 use iter::{DoubleEndedIterator, AdditiveIterator, Extendable, Iterator, Map};
 use option::{Option, None, Some};
-use str;
 use str::Str;
+use str;
 use slice::{CloneableVector, Splits, Vector, VectorVector,
             ImmutableEqVector, OwnedVector, ImmutableVector};
 use vec::Vec;
@@ -105,7 +106,7 @@ unsafe fn to_c_str_unchecked(&self) -> CString {
     }
 }
 
-impl<S: Writer> ::hash::Hash<S> for Path {
+impl<S: hash::Writer> hash::Hash<S> for Path {
     #[inline]
     fn hash(&self, state: &mut S) {
         self.repr.hash(state)
index 865e53cbe38dc1c90aeee12cfaa8ee32b4d2ac57..e53842ecd8faf741443369a0122d41b4719ab393 100644 (file)
@@ -16,6 +16,7 @@
 use cmp::{PartialEq, Eq};
 use container::Container;
 use from_str::FromStr;
+use hash;
 use io::Writer;
 use iter::{AdditiveIterator, DoubleEndedIterator, Extendable, Iterator, Map};
 use mem;
@@ -126,7 +127,7 @@ unsafe fn to_c_str_unchecked(&self) -> CString {
     }
 }
 
-impl<S: Writer> ::hash::Hash<S> for Path {
+impl<S: hash::Writer> hash::Hash<S> for Path {
     #[cfg(not(test))]
     #[inline]
     fn hash(&self, state: &mut S) {
diff --git a/src/libstd/slice.rs b/src/libstd/slice.rs
deleted file mode 100644 (file)
index d6f63da..0000000
+++ /dev/null
@@ -1,2546 +0,0 @@
-// Copyright 2012-2014 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.
-
-/*!
-
-Utilities for vector manipulation
-
-The `vec` module contains useful code to help work with vector values.
-Vectors are Rust's list type. Vectors contain zero or more values of
-homogeneous types:
-
-```rust
-let int_vector = [1,2,3];
-let str_vector = ["one", "two", "three"];
-```
-
-This is a big module, but for a high-level overview:
-
-## Structs
-
-Several structs that are useful for vectors, such as `Items`, which
-represents iteration over a vector.
-
-## Traits
-
-A number of traits add methods that allow you to accomplish tasks with vectors.
-
-Traits defined for the `&[T]` type (a vector slice), have methods that can be
-called on either owned vectors, denoted `~[T]`, or on vector slices themselves.
-These traits include `ImmutableVector`, and `MutableVector` for the `&mut [T]`
-case.
-
-An example is the method `.slice(a, b)` that returns an immutable "view" into
-a vector or a vector slice from the index interval `[a, b)`:
-
-```rust
-let numbers = [0, 1, 2];
-let last_numbers = numbers.slice(1, 3);
-// last_numbers is now &[1, 2]
-```
-
-Traits defined for the `~[T]` type, like `OwnedVector`, can only be called
-on such vectors. These methods deal with adding elements or otherwise changing
-the allocation of the vector.
-
-An example is the method `.push(element)` that will add an element at the end
-of the vector:
-
-```rust
-let mut numbers = vec![0, 1, 2];
-numbers.push(7);
-// numbers is now vec![0, 1, 2, 7];
-```
-
-## Implementations of other traits
-
-Vectors are a very useful type, and so there's several implementations of
-traits from other modules. Some notable examples:
-
-* `Clone`
-* `Eq`, `Ord`, `Eq`, `Ord` -- vectors can be compared,
-  if the element type defines the corresponding trait.
-
-## Iteration
-
-The method `iter()` returns an iteration value for a vector or a vector slice.
-The iterator yields references to the vector's elements, so if the element
-type of the vector is `int`, the element type of the iterator is `&int`.
-
-```rust
-let numbers = [0, 1, 2];
-for &x in numbers.iter() {
-    println!("{} is a number!", x);
-}
-```
-
-* `.mut_iter()` returns an iterator that allows modifying each value.
-* `.move_iter()` converts an owned vector into an iterator that
-  moves out a value from the vector each iteration.
-* Further iterators exist that split, chunk or permute the vector.
-
-## Function definitions
-
-There are a number of free functions that create or take vectors, for example:
-
-* Creating a vector, like `from_elem` and `from_fn`
-* Creating a vector with a given size: `with_capacity`
-* Modifying a vector and returning it, like `append`
-* Operations on paired elements, like `unzip`.
-
-*/
-
-#![doc(primitive = "slice")]
-
-use mem::transmute;
-use clone::Clone;
-use cmp::{Ord, Ordering, Less, Greater};
-use cmp;
-use container::Container;
-use iter::*;
-use mem::size_of;
-use mem;
-use ops::Drop;
-use option::{None, Option, Some};
-use ptr::RawPtr;
-use ptr;
-use rt::heap::{allocate, deallocate};
-use finally::try_finally;
-use vec::Vec;
-
-pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows};
-pub use core::slice::{Chunks, Vector, ImmutableVector, ImmutableEqVector};
-pub use core::slice::{ImmutableOrdVector, MutableVector, Items, MutItems};
-pub use core::slice::{MutSplits, MutChunks};
-pub use core::slice::{bytes, MutableCloneableVector};
-
-// Functional utilities
-
-#[allow(missing_doc)]
-pub trait VectorVector<T> {
-    // FIXME #5898: calling these .concat and .connect conflicts with
-    // StrVector::con{cat,nect}, since they have generic contents.
-    /// Flattens a vector of vectors of T into a single vector of T.
-    fn concat_vec(&self) -> Vec<T>;
-
-    /// Concatenate a vector of vectors, placing a given separator between each.
-    fn connect_vec(&self, sep: &T) -> Vec<T>;
-}
-
-impl<'a, T: Clone, V: Vector<T>> VectorVector<T> for &'a [V] {
-    fn concat_vec(&self) -> Vec<T> {
-        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
-        let mut result = Vec::with_capacity(size);
-        for v in self.iter() {
-            result.push_all(v.as_slice())
-        }
-        result
-    }
-
-    fn connect_vec(&self, sep: &T) -> Vec<T> {
-        let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len());
-        let mut result = Vec::with_capacity(size + self.len());
-        let mut first = true;
-        for v in self.iter() {
-            if first { first = false } else { result.push(sep.clone()) }
-            result.push_all(v.as_slice())
-        }
-        result
-    }
-}
-
-/// An Iterator that yields the element swaps needed to produce
-/// a sequence of all possible permutations for an indexed sequence of
-/// elements. Each permutation is only a single swap apart.
-///
-/// The Steinhaus–Johnson–Trotter algorithm is used.
-///
-/// Generates even and odd permutations alternately.
-///
-/// The last generated swap is always (0, 1), and it returns the
-/// sequence to its initial order.
-pub struct ElementSwaps {
-    sdir: Vec<SizeDirection>,
-    /// If true, emit the last swap that returns the sequence to initial state
-    emit_reset: bool,
-    swaps_made : uint,
-}
-
-impl ElementSwaps {
-    /// Create an `ElementSwaps` iterator for a sequence of `length` elements
-    pub fn new(length: uint) -> ElementSwaps {
-        // Initialize `sdir` with a direction that position should move in
-        // (all negative at the beginning) and the `size` of the
-        // element (equal to the original index).
-        ElementSwaps{
-            emit_reset: true,
-            sdir: range(0, length).map(|i| SizeDirection{ size: i, dir: Neg }).collect(),
-            swaps_made: 0
-        }
-    }
-}
-
-enum Direction { Pos, Neg }
-
-/// An Index and Direction together
-struct SizeDirection {
-    size: uint,
-    dir: Direction,
-}
-
-impl Iterator<(uint, uint)> for ElementSwaps {
-    #[inline]
-    fn next(&mut self) -> Option<(uint, uint)> {
-        fn new_pos(i: uint, s: Direction) -> uint {
-            i + match s { Pos => 1, Neg => -1 }
-        }
-
-        // Find the index of the largest mobile element:
-        // The direction should point into the vector, and the
-        // swap should be with a smaller `size` element.
-        let max = self.sdir.iter().map(|&x| x).enumerate()
-                           .filter(|&(i, sd)|
-                                new_pos(i, sd.dir) < self.sdir.len() &&
-                                self.sdir.get(new_pos(i, sd.dir)).size < sd.size)
-                           .max_by(|&(_, sd)| sd.size);
-        match max {
-            Some((i, sd)) => {
-                let j = new_pos(i, sd.dir);
-                self.sdir.as_mut_slice().swap(i, j);
-
-                // Swap the direction of each larger SizeDirection
-                for x in self.sdir.mut_iter() {
-                    if x.size > sd.size {
-                        x.dir = match x.dir { Pos => Neg, Neg => Pos };
-                    }
-                }
-                self.swaps_made += 1;
-                Some((i, j))
-            },
-            None => if self.emit_reset {
-                self.emit_reset = false;
-                if self.sdir.len() > 1 {
-                    // The last swap
-                    self.swaps_made += 1;
-                    Some((0, 1))
-                } else {
-                    // Vector is of the form [] or [x], and the only permutation is itself
-                    self.swaps_made += 1;
-                    Some((0,0))
-                }
-            } else { None }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        // For a vector of size n, there are exactly n! permutations.
-        let n = range(2, self.sdir.len() + 1).product();
-        (n - self.swaps_made, Some(n - self.swaps_made))
-    }
-}
-
-/// An Iterator that uses `ElementSwaps` to iterate through
-/// all possible permutations of a vector.
-///
-/// The first iteration yields a clone of the vector as it is,
-/// then each successive element is the vector with one
-/// swap applied.
-///
-/// Generates even and odd permutations alternately.
-pub struct Permutations<T> {
-    swaps: ElementSwaps,
-    v: ~[T],
-}
-
-impl<T: Clone> Iterator<~[T]> for Permutations<T> {
-    #[inline]
-    fn next(&mut self) -> Option<~[T]> {
-        match self.swaps.next() {
-            None => None,
-            Some((0,0)) => Some(self.v.clone()),
-            Some((a, b)) => {
-                let elt = self.v.clone();
-                self.v.swap(a, b);
-                Some(elt)
-            }
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        self.swaps.size_hint()
-    }
-}
-
-/// Extension methods for vector slices with cloneable elements
-pub trait CloneableVector<T> {
-    /// Copy `self` into a new owned vector
-    fn to_owned(&self) -> ~[T];
-
-    /// Convert `self` into an owned vector, not making a copy if possible.
-    fn into_owned(self) -> ~[T];
-}
-
-/// Extension methods for vector slices
-impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
-    /// Returns a copy of `v`.
-    #[inline]
-    fn to_owned(&self) -> ~[T] {
-        use RawVec = core::raw::Vec;
-        use num::{CheckedAdd, CheckedMul};
-
-        let len = self.len();
-        let data_size = len.checked_mul(&mem::size_of::<T>());
-        let data_size = data_size.expect("overflow in to_owned()");
-        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
-        let size = size.expect("overflow in to_owned()");
-
-        unsafe {
-            // this should pass the real required alignment
-            let ret = allocate(size, 8) as *mut RawVec<()>;
-
-            let a_size = mem::size_of::<T>();
-            let a_size = if a_size == 0 {1} else {a_size};
-            (*ret).fill = len * a_size;
-            (*ret).alloc = len * a_size;
-
-            // Be careful with the following loop. We want it to be optimized
-            // to a memcpy (or something similarly fast) when T is Copy. LLVM
-            // is easily confused, so any extra operations during the loop can
-            // prevent this optimization.
-            let mut i = 0;
-            let p = &mut (*ret).data as *mut _ as *mut T;
-            try_finally(
-                &mut i, (),
-                |i, ()| while *i < len {
-                    mem::overwrite(
-                        &mut(*p.offset(*i as int)),
-                        self.unsafe_ref(*i).clone());
-                    *i += 1;
-                },
-                |i| if *i < len {
-                    // we must be failing, clean up after ourselves
-                    for j in range(0, *i as int) {
-                        ptr::read(&*p.offset(j));
-                    }
-                    // FIXME: #13994 (should pass align and size here)
-                    deallocate(ret as *mut u8, 0, 8);
-                });
-            mem::transmute(ret)
-        }
-    }
-
-    #[inline(always)]
-    fn into_owned(self) -> ~[T] { self.to_owned() }
-}
-
-/// Extension methods for owned vectors
-impl<T: Clone> CloneableVector<T> for ~[T] {
-    #[inline]
-    fn to_owned(&self) -> ~[T] { self.clone() }
-
-    #[inline(always)]
-    fn into_owned(self) -> ~[T] { self }
-}
-
-/// Extension methods for vectors containing `Clone` elements.
-pub trait ImmutableCloneableVector<T> {
-    /// Partitions the vector into two vectors `(A,B)`, where all
-    /// elements of `A` satisfy `f` and all elements of `B` do not.
-    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
-
-    /// Create an iterator that yields every possible permutation of the
-    /// vector in succession.
-    fn permutations(self) -> Permutations<T>;
-}
-
-impl<'a,T:Clone> ImmutableCloneableVector<T> for &'a [T] {
-    #[inline]
-    fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
-        let mut lefts  = Vec::new();
-        let mut rights = Vec::new();
-
-        for elt in self.iter() {
-            if f(elt) {
-                lefts.push((*elt).clone());
-            } else {
-                rights.push((*elt).clone());
-            }
-        }
-
-        (lefts, rights)
-    }
-
-    fn permutations(self) -> Permutations<T> {
-        Permutations{
-            swaps: ElementSwaps::new(self.len()),
-            v: self.to_owned(),
-        }
-    }
-
-}
-
-/// Extension methods for owned vectors.
-pub trait OwnedVector<T> {
-    /// Creates a consuming iterator, that is, one that moves each
-    /// value out of the vector (from start to end). The vector cannot
-    /// be used after calling this.
-    ///
-    /// # Examples
-    ///
-    /// ```rust
-    /// let v = ~["a".to_string(), "b".to_string()];
-    /// for s in v.move_iter() {
-    ///   // s has type ~str, not &~str
-    ///   println!("{}", s);
-    /// }
-    /// ```
-    fn move_iter(self) -> MoveItems<T>;
-
-    /**
-     * Partitions the vector into two vectors `(A,B)`, where all
-     * elements of `A` satisfy `f` and all elements of `B` do not.
-     */
-    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>);
-}
-
-impl<T> OwnedVector<T> for ~[T] {
-    #[inline]
-    fn move_iter(self) -> MoveItems<T> {
-        unsafe {
-            let iter = transmute(self.iter());
-            let ptr = transmute(self);
-            MoveItems { allocation: ptr, iter: iter }
-        }
-    }
-
-    #[inline]
-    fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
-        let mut lefts  = Vec::new();
-        let mut rights = Vec::new();
-
-        for elt in self.move_iter() {
-            if f(&elt) {
-                lefts.push(elt);
-            } else {
-                rights.push(elt);
-            }
-        }
-
-        (lefts, rights)
-    }
-}
-
-fn insertion_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
-    let len = v.len() as int;
-    let buf_v = v.as_mut_ptr();
-
-    // 1 <= i < len;
-    for i in range(1, len) {
-        // j satisfies: 0 <= j <= i;
-        let mut j = i;
-        unsafe {
-            // `i` is in bounds.
-            let read_ptr = buf_v.offset(i) as *T;
-
-            // find where to insert, we need to do strict <,
-            // rather than <=, to maintain stability.
-
-            // 0 <= j - 1 < len, so .offset(j - 1) is in bounds.
-            while j > 0 &&
-                    compare(&*read_ptr, &*buf_v.offset(j - 1)) == Less {
-                j -= 1;
-            }
-
-            // shift everything to the right, to make space to
-            // insert this value.
-
-            // j + 1 could be `len` (for the last `i`), but in
-            // that case, `i == j` so we don't copy. The
-            // `.offset(j)` is always in bounds.
-
-            if i != j {
-                let tmp = ptr::read(read_ptr);
-                ptr::copy_memory(buf_v.offset(j + 1),
-                                 &*buf_v.offset(j),
-                                 (i - j) as uint);
-                ptr::copy_nonoverlapping_memory(buf_v.offset(j),
-                                                &tmp as *T,
-                                                1);
-                mem::forget(tmp);
-            }
-        }
-    }
-}
-
-fn merge_sort<T>(v: &mut [T], compare: |&T, &T| -> Ordering) {
-    // warning: this wildly uses unsafe.
-    static BASE_INSERTION: uint = 32;
-    static LARGE_INSERTION: uint = 16;
-
-    // FIXME #12092: smaller insertion runs seems to make sorting
-    // vectors of large elements a little faster on some platforms,
-    // but hasn't been tested/tuned extensively
-    let insertion = if size_of::<T>() <= 16 {
-        BASE_INSERTION
-    } else {
-        LARGE_INSERTION
-    };
-
-    let len = v.len();
-
-    // short vectors get sorted in-place via insertion sort to avoid allocations
-    if len <= insertion {
-        insertion_sort(v, compare);
-        return;
-    }
-
-    // allocate some memory to use as scratch memory, we keep the
-    // length 0 so we can keep shallow copies of the contents of `v`
-    // without risking the dtors running on an object twice if
-    // `compare` fails.
-    let mut working_space = Vec::with_capacity(2 * len);
-    // these both are buffers of length `len`.
-    let mut buf_dat = working_space.as_mut_ptr();
-    let mut buf_tmp = unsafe {buf_dat.offset(len as int)};
-
-    // length `len`.
-    let buf_v = v.as_ptr();
-
-    // step 1. sort short runs with insertion sort. This takes the
-    // values from `v` and sorts them into `buf_dat`, leaving that
-    // with sorted runs of length INSERTION.
-
-    // We could hardcode the sorting comparisons here, and we could
-    // manipulate/step the pointers themselves, rather than repeatedly
-    // .offset-ing.
-    for start in range_step(0, len, insertion) {
-        // start <= i < len;
-        for i in range(start, cmp::min(start + insertion, len)) {
-            // j satisfies: start <= j <= i;
-            let mut j = i as int;
-            unsafe {
-                // `i` is in bounds.
-                let read_ptr = buf_v.offset(i as int);
-
-                // find where to insert, we need to do strict <,
-                // rather than <=, to maintain stability.
-
-                // start <= j - 1 < len, so .offset(j - 1) is in
-                // bounds.
-                while j > start as int &&
-                        compare(&*read_ptr, &*buf_dat.offset(j - 1)) == Less {
-                    j -= 1;
-                }
-
-                // shift everything to the right, to make space to
-                // insert this value.
-
-                // j + 1 could be `len` (for the last `i`), but in
-                // that case, `i == j` so we don't copy. The
-                // `.offset(j)` is always in bounds.
-                ptr::copy_memory(buf_dat.offset(j + 1),
-                                 &*buf_dat.offset(j),
-                                 i - j as uint);
-                ptr::copy_nonoverlapping_memory(buf_dat.offset(j), read_ptr, 1);
-            }
-        }
-    }
-
-    // step 2. merge the sorted runs.
-    let mut width = insertion;
-    while width < len {
-        // merge the sorted runs of length `width` in `buf_dat` two at
-        // a time, placing the result in `buf_tmp`.
-
-        // 0 <= start <= len.
-        for start in range_step(0, len, 2 * width) {
-            // manipulate pointers directly for speed (rather than
-            // using a `for` loop with `range` and `.offset` inside
-            // that loop).
-            unsafe {
-                // the end of the first run & start of the
-                // second. Offset of `len` is defined, since this is
-                // precisely one byte past the end of the object.
-                let right_start = buf_dat.offset(cmp::min(start + width, len) as int);
-                // end of the second. Similar reasoning to the above re safety.
-                let right_end_idx = cmp::min(start + 2 * width, len);
-                let right_end = buf_dat.offset(right_end_idx as int);
-
-                // the pointers to the elements under consideration
-                // from the two runs.
-
-                // both of these are in bounds.
-                let mut left = buf_dat.offset(start as int);
-                let mut right = right_start;
-
-                // where we're putting the results, it is a run of
-                // length `2*width`, so we step it once for each step
-                // of either `left` or `right`.  `buf_tmp` has length
-                // `len`, so these are in bounds.
-                let mut out = buf_tmp.offset(start as int);
-                let out_end = buf_tmp.offset(right_end_idx as int);
-
-                while out < out_end {
-                    // Either the left or the right run are exhausted,
-                    // so just copy the remainder from the other run
-                    // and move on; this gives a huge speed-up (order
-                    // of 25%) for mostly sorted vectors (the best
-                    // case).
-                    if left == right_start {
-                        // the number remaining in this run.
-                        let elems = (right_end as uint - right as uint) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping_memory(out, &*right, elems);
-                        break;
-                    } else if right == right_end {
-                        let elems = (right_start as uint - left as uint) / mem::size_of::<T>();
-                        ptr::copy_nonoverlapping_memory(out, &*left, elems);
-                        break;
-                    }
-
-                    // check which side is smaller, and that's the
-                    // next element for the new run.
-
-                    // `left < right_start` and `right < right_end`,
-                    // so these are valid.
-                    let to_copy = if compare(&*left, &*right) == Greater {
-                        step(&mut right)
-                    } else {
-                        step(&mut left)
-                    };
-                    ptr::copy_nonoverlapping_memory(out, &*to_copy, 1);
-                    step(&mut out);
-                }
-            }
-        }
-
-        mem::swap(&mut buf_dat, &mut buf_tmp);
-
-        width *= 2;
-    }
-
-    // write the result to `v` in one go, so that there are never two copies
-    // of the same object in `v`.
-    unsafe {
-        ptr::copy_nonoverlapping_memory(v.as_mut_ptr(), &*buf_dat, len);
-    }
-
-    // increment the pointer, returning the old pointer.
-    #[inline(always)]
-    unsafe fn step<T>(ptr: &mut *mut T) -> *mut T {
-        let old = *ptr;
-        *ptr = ptr.offset(1);
-        old
-    }
-}
-
-/// Extension methods for vectors such that their elements are
-/// mutable.
-pub trait MutableVectorAllocating<'a, T> {
-    /// Sort the vector, in place, using `compare` to compare
-    /// elements.
-    ///
-    /// This sort is `O(n log n)` worst-case and stable, but allocates
-    /// approximately `2 * n`, where `n` is the length of `self`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [5i, 4, 1, 3, 2];
-    /// v.sort_by(|a, b| a.cmp(b));
-    /// assert!(v == [1, 2, 3, 4, 5]);
-    ///
-    /// // reverse sorting
-    /// v.sort_by(|a, b| b.cmp(a));
-    /// assert!(v == [5, 4, 3, 2, 1]);
-    /// ```
-    fn sort_by(self, compare: |&T, &T| -> Ordering);
-
-    /**
-     * Consumes `src` and moves as many elements as it can into `self`
-     * from the range [start,end).
-     *
-     * Returns the number of elements copied (the shorter of self.len()
-     * and end - start).
-     *
-     * # Arguments
-     *
-     * * src - A mutable vector of `T`
-     * * start - The index into `src` to start copying from
-     * * end - The index into `str` to stop copying from
-     */
-    fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;
-}
-
-impl<'a,T> MutableVectorAllocating<'a, T> for &'a mut [T] {
-    #[inline]
-    fn sort_by(self, compare: |&T, &T| -> Ordering) {
-        merge_sort(self, compare)
-    }
-
-    #[inline]
-    fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
-        for (a, b) in self.mut_iter().zip(src.mut_slice(start, end).mut_iter()) {
-            mem::swap(a, b);
-        }
-        cmp::min(self.len(), end-start)
-    }
-}
-
-/// Methods for mutable vectors with orderable elements, such as
-/// in-place sorting.
-pub trait MutableOrdVector<T> {
-    /// Sort the vector, in place.
-    ///
-    /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = [-5, 4, 1, -3, 2];
-    ///
-    /// v.sort();
-    /// assert!(v == [-5, -3, 1, 2, 4]);
-    /// ```
-    fn sort(self);
-
-    /// Mutates the slice to the next lexicographic permutation.
-    ///
-    /// Returns `true` if successful, `false` if the slice is at the last-ordered permutation.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let v = &mut [0, 1, 2];
-    /// v.next_permutation();
-    /// assert_eq!(v, &mut [0, 2, 1]);
-    /// v.next_permutation();
-    /// assert_eq!(v, &mut [1, 0, 2]);
-    /// ```
-    fn next_permutation(self) -> bool;
-
-    /// Mutates the slice to the previous lexicographic permutation.
-    ///
-    /// Returns `true` if successful, `false` if the slice is at the first-ordered permutation.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let v = &mut [1, 0, 2];
-    /// v.prev_permutation();
-    /// assert_eq!(v, &mut [0, 2, 1]);
-    /// v.prev_permutation();
-    /// assert_eq!(v, &mut [0, 1, 2]);
-    /// ```
-    fn prev_permutation(self) -> bool;
-}
-
-impl<'a, T: Ord> MutableOrdVector<T> for &'a mut [T] {
-    #[inline]
-    fn sort(self) {
-        self.sort_by(|a,b| a.cmp(b))
-    }
-
-    fn next_permutation(self) -> bool {
-        // These cases only have 1 permutation each, so we can't do anything.
-        if self.len() < 2 { return false; }
-
-        // Step 1: Identify the longest, rightmost weakly decreasing part of the vector
-        let mut i = self.len() - 1;
-        while i > 0 && self[i-1] >= self[i] {
-            i -= 1;
-        }
-
-        // If that is the entire vector, this is the last-ordered permutation.
-        if i == 0 {
-            return false;
-        }
-
-        // Step 2: Find the rightmost element larger than the pivot (i-1)
-        let mut j = self.len() - 1;
-        while j >= i && self[j] <= self[i-1]  {
-            j -= 1;
-        }
-
-        // Step 3: Swap that element with the pivot
-        self.swap(j, i-1);
-
-        // Step 4: Reverse the (previously) weakly decreasing part
-        self.mut_slice_from(i).reverse();
-
-        true
-    }
-
-    fn prev_permutation(self) -> bool {
-        // These cases only have 1 permutation each, so we can't do anything.
-        if self.len() < 2 { return false; }
-
-        // Step 1: Identify the longest, rightmost weakly increasing part of the vector
-        let mut i = self.len() - 1;
-        while i > 0 && self[i-1] <= self[i] {
-            i -= 1;
-        }
-
-        // If that is the entire vector, this is the first-ordered permutation.
-        if i == 0 {
-            return false;
-        }
-
-        // Step 2: Reverse the weakly increasing part
-        self.mut_slice_from(i).reverse();
-
-        // Step 3: Find the rightmost element equal to or bigger than the pivot (i-1)
-        let mut j = self.len() - 1;
-        while j >= i && self[j-1] < self[i-1]  {
-            j -= 1;
-        }
-
-        // Step 4: Swap that element with the pivot
-        self.swap(i-1, j);
-
-        true
-    }
-}
-
-/// Unsafe operations
-pub mod raw {
-    pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice};
-    pub use core::slice::raw::{shift_ptr, pop_ptr};
-}
-
-/// An iterator that moves out of a vector.
-pub struct MoveItems<T> {
-    allocation: *mut u8, // the block of memory allocated for the vector
-    iter: Items<'static, T>
-}
-
-impl<T> Iterator<T> for MoveItems<T> {
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        unsafe {
-            self.iter.next().map(|x| ptr::read(x))
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        self.iter.size_hint()
-    }
-}
-
-impl<T> DoubleEndedIterator<T> for MoveItems<T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        unsafe {
-            self.iter.next_back().map(|x| ptr::read(x))
-        }
-    }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for MoveItems<T> {
-    fn drop(&mut self) {
-        // destroy the remaining elements
-        for _x in *self {}
-        unsafe {
-            // FIXME: #13994 (should pass align and size here)
-            deallocate(self.allocation, 0, 8)
-        }
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use cmp::*;
-    use mem;
-    use owned::Box;
-    use rand::{Rng, task_rng};
-    use slice::*;
-
-    fn square(n: uint) -> uint { n * n }
-
-    fn is_odd(n: &uint) -> bool { *n % 2u == 1u }
-
-    #[test]
-    fn test_from_fn() {
-        // Test on-stack from_fn.
-        let mut v = Vec::from_fn(3u, square);
-        {
-            let v = v.as_slice();
-            assert_eq!(v.len(), 3u);
-            assert_eq!(v[0], 0u);
-            assert_eq!(v[1], 1u);
-            assert_eq!(v[2], 4u);
-        }
-
-        // Test on-heap from_fn.
-        v = Vec::from_fn(5u, square);
-        {
-            let v = v.as_slice();
-            assert_eq!(v.len(), 5u);
-            assert_eq!(v[0], 0u);
-            assert_eq!(v[1], 1u);
-            assert_eq!(v[2], 4u);
-            assert_eq!(v[3], 9u);
-            assert_eq!(v[4], 16u);
-        }
-    }
-
-    #[test]
-    fn test_from_elem() {
-        // Test on-stack from_elem.
-        let mut v = Vec::from_elem(2u, 10u);
-        {
-            let v = v.as_slice();
-            assert_eq!(v.len(), 2u);
-            assert_eq!(v[0], 10u);
-            assert_eq!(v[1], 10u);
-        }
-
-        // Test on-heap from_elem.
-        v = Vec::from_elem(6u, 20u);
-        {
-            let v = v.as_slice();
-            assert_eq!(v[0], 20u);
-            assert_eq!(v[1], 20u);
-            assert_eq!(v[2], 20u);
-            assert_eq!(v[3], 20u);
-            assert_eq!(v[4], 20u);
-            assert_eq!(v[5], 20u);
-        }
-    }
-
-    #[test]
-    fn test_is_empty() {
-        let xs: [int, ..0] = [];
-        assert!(xs.is_empty());
-        assert!(![0].is_empty());
-    }
-
-    #[test]
-    fn test_len_divzero() {
-        type Z = [i8, ..0];
-        let v0 : &[Z] = &[];
-        let v1 : &[Z] = &[[]];
-        let v2 : &[Z] = &[[], []];
-        assert_eq!(mem::size_of::<Z>(), 0);
-        assert_eq!(v0.len(), 0);
-        assert_eq!(v1.len(), 1);
-        assert_eq!(v2.len(), 2);
-    }
-
-    #[test]
-    fn test_get() {
-        let mut a = box [11];
-        assert_eq!(a.get(1), None);
-        a = box [11, 12];
-        assert_eq!(a.get(1).unwrap(), &12);
-        a = box [11, 12, 13];
-        assert_eq!(a.get(1).unwrap(), &12);
-    }
-
-    #[test]
-    fn test_head() {
-        let mut a = box [];
-        assert_eq!(a.head(), None);
-        a = box [11];
-        assert_eq!(a.head().unwrap(), &11);
-        a = box [11, 12];
-        assert_eq!(a.head().unwrap(), &11);
-    }
-
-    #[test]
-    fn test_tail() {
-        let mut a = box [11];
-        assert_eq!(a.tail(), &[]);
-        a = box [11, 12];
-        assert_eq!(a.tail(), &[12]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tail_empty() {
-        let a: ~[int] = box [];
-        a.tail();
-    }
-
-    #[test]
-    fn test_tailn() {
-        let mut a = box [11, 12, 13];
-        assert_eq!(a.tailn(0), &[11, 12, 13]);
-        a = box [11, 12, 13];
-        assert_eq!(a.tailn(2), &[13]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_tailn_empty() {
-        let a: ~[int] = box [];
-        a.tailn(2);
-    }
-
-    #[test]
-    fn test_init() {
-        let mut a = box [11];
-        assert_eq!(a.init(), &[]);
-        a = box [11, 12];
-        assert_eq!(a.init(), &[11]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_init_empty() {
-        let a: ~[int] = box [];
-        a.init();
-    }
-
-    #[test]
-    fn test_initn() {
-        let mut a = box [11, 12, 13];
-        assert_eq!(a.initn(0), &[11, 12, 13]);
-        a = box [11, 12, 13];
-        assert_eq!(a.initn(2), &[11]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_initn_empty() {
-        let a: ~[int] = box [];
-        a.initn(2);
-    }
-
-    #[test]
-    fn test_last() {
-        let mut a = box [];
-        assert_eq!(a.last(), None);
-        a = box [11];
-        assert_eq!(a.last().unwrap(), &11);
-        a = box [11, 12];
-        assert_eq!(a.last().unwrap(), &12);
-    }
-
-    #[test]
-    fn test_slice() {
-        // Test fixed length vector.
-        let vec_fixed = [1, 2, 3, 4];
-        let v_a = vec_fixed.slice(1u, vec_fixed.len()).to_owned();
-        assert_eq!(v_a.len(), 3u);
-        assert_eq!(v_a[0], 2);
-        assert_eq!(v_a[1], 3);
-        assert_eq!(v_a[2], 4);
-
-        // Test on stack.
-        let vec_stack = &[1, 2, 3];
-        let v_b = vec_stack.slice(1u, 3u).to_owned();
-        assert_eq!(v_b.len(), 2u);
-        assert_eq!(v_b[0], 2);
-        assert_eq!(v_b[1], 3);
-
-        // Test `Box<[T]>`
-        let vec_unique = box [1, 2, 3, 4, 5, 6];
-        let v_d = vec_unique.slice(1u, 6u).to_owned();
-        assert_eq!(v_d.len(), 5u);
-        assert_eq!(v_d[0], 2);
-        assert_eq!(v_d[1], 3);
-        assert_eq!(v_d[2], 4);
-        assert_eq!(v_d[3], 5);
-        assert_eq!(v_d[4], 6);
-    }
-
-    #[test]
-    fn test_slice_from() {
-        let vec = &[1, 2, 3, 4];
-        assert_eq!(vec.slice_from(0), vec);
-        assert_eq!(vec.slice_from(2), &[3, 4]);
-        assert_eq!(vec.slice_from(4), &[]);
-    }
-
-    #[test]
-    fn test_slice_to() {
-        let vec = &[1, 2, 3, 4];
-        assert_eq!(vec.slice_to(4), vec);
-        assert_eq!(vec.slice_to(2), &[1, 2]);
-        assert_eq!(vec.slice_to(0), &[]);
-    }
-
-
-    #[test]
-    fn test_pop() {
-        let mut v = vec![5];
-        let e = v.pop();
-        assert_eq!(v.len(), 0);
-        assert_eq!(e, Some(5));
-        let f = v.pop();
-        assert_eq!(f, None);
-        let g = v.pop();
-        assert_eq!(g, None);
-    }
-
-    #[test]
-    fn test_swap_remove() {
-        let mut v = vec![1, 2, 3, 4, 5];
-        let mut e = v.swap_remove(0);
-        assert_eq!(e, Some(1));
-        assert_eq!(v, vec![5, 2, 3, 4]);
-        e = v.swap_remove(3);
-        assert_eq!(e, Some(4));
-        assert_eq!(v, vec![5, 2, 3]);
-
-        e = v.swap_remove(3);
-        assert_eq!(e, None);
-        assert_eq!(v, vec![5, 2, 3]);
-    }
-
-    #[test]
-    fn test_swap_remove_noncopyable() {
-        // Tests that we don't accidentally run destructors twice.
-        let mut v = vec![::unstable::sync::Exclusive::new(()),
-                         ::unstable::sync::Exclusive::new(()),
-                         ::unstable::sync::Exclusive::new(())];
-        let mut _e = v.swap_remove(0);
-        assert_eq!(v.len(), 2);
-        _e = v.swap_remove(1);
-        assert_eq!(v.len(), 1);
-        _e = v.swap_remove(0);
-        assert_eq!(v.len(), 0);
-    }
-
-    #[test]
-    fn test_push() {
-        // Test on-stack push().
-        let mut v = vec![];
-        v.push(1);
-        assert_eq!(v.len(), 1u);
-        assert_eq!(v.as_slice()[0], 1);
-
-        // Test on-heap push().
-        v.push(2);
-        assert_eq!(v.len(), 2u);
-        assert_eq!(v.as_slice()[0], 1);
-        assert_eq!(v.as_slice()[1], 2);
-    }
-
-    #[test]
-    fn test_grow() {
-        // Test on-stack grow().
-        let mut v = vec![];
-        v.grow(2u, &1);
-        {
-            let v = v.as_slice();
-            assert_eq!(v.len(), 2u);
-            assert_eq!(v[0], 1);
-            assert_eq!(v[1], 1);
-        }
-
-        // Test on-heap grow().
-        v.grow(3u, &2);
-        {
-            let v = v.as_slice();
-            assert_eq!(v.len(), 5u);
-            assert_eq!(v[0], 1);
-            assert_eq!(v[1], 1);
-            assert_eq!(v[2], 2);
-            assert_eq!(v[3], 2);
-            assert_eq!(v[4], 2);
-        }
-    }
-
-    #[test]
-    fn test_grow_fn() {
-        let mut v = vec![];
-        v.grow_fn(3u, square);
-        let v = v.as_slice();
-        assert_eq!(v.len(), 3u);
-        assert_eq!(v[0], 0u);
-        assert_eq!(v[1], 1u);
-        assert_eq!(v[2], 4u);
-    }
-
-    #[test]
-    fn test_grow_set() {
-        let mut v = vec![1, 2, 3];
-        v.grow_set(4u, &4, 5);
-        let v = v.as_slice();
-        assert_eq!(v.len(), 5u);
-        assert_eq!(v[0], 1);
-        assert_eq!(v[1], 2);
-        assert_eq!(v[2], 3);
-        assert_eq!(v[3], 4);
-        assert_eq!(v[4], 5);
-    }
-
-    #[test]
-    fn test_truncate() {
-        let mut v = vec![box 6,box 5,box 4];
-        v.truncate(1);
-        let v = v.as_slice();
-        assert_eq!(v.len(), 1);
-        assert_eq!(*(v[0]), 6);
-        // If the unsafe block didn't drop things properly, we blow up here.
-    }
-
-    #[test]
-    fn test_clear() {
-        let mut v = vec![box 6,box 5,box 4];
-        v.clear();
-        assert_eq!(v.len(), 0);
-        // If the unsafe block didn't drop things properly, we blow up here.
-    }
-
-    #[test]
-    fn test_dedup() {
-        fn case(a: Vec<uint>, b: Vec<uint>) {
-            let mut v = a;
-            v.dedup();
-            assert_eq!(v, b);
-        }
-        case(vec![], vec![]);
-        case(vec![1], vec![1]);
-        case(vec![1,1], vec![1]);
-        case(vec![1,2,3], vec![1,2,3]);
-        case(vec![1,1,2,3], vec![1,2,3]);
-        case(vec![1,2,2,3], vec![1,2,3]);
-        case(vec![1,2,3,3], vec![1,2,3]);
-        case(vec![1,1,2,2,2,3,3], vec![1,2,3]);
-    }
-
-    #[test]
-    fn test_dedup_unique() {
-        let mut v0 = vec![box 1, box 1, box 2, box 3];
-        v0.dedup();
-        let mut v1 = vec![box 1, box 2, box 2, box 3];
-        v1.dedup();
-        let mut v2 = vec![box 1, box 2, box 3, box 3];
-        v2.dedup();
-        /*
-         * If the boxed pointers were leaked or otherwise misused, valgrind
-         * and/or rustrt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_dedup_shared() {
-        let mut v0 = vec![box 1, box 1, box 2, box 3];
-        v0.dedup();
-        let mut v1 = vec![box 1, box 2, box 2, box 3];
-        v1.dedup();
-        let mut v2 = vec![box 1, box 2, box 3, box 3];
-        v2.dedup();
-        /*
-         * If the pointers were leaked or otherwise misused, valgrind and/or
-         * rustrt should raise errors.
-         */
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut v = vec![1, 2, 3, 4, 5];
-        v.retain(is_odd);
-        assert_eq!(v, vec![1, 3, 5]);
-    }
-
-    #[test]
-    fn test_element_swaps() {
-        let mut v = [1, 2, 3];
-        for (i, (a, b)) in ElementSwaps::new(v.len()).enumerate() {
-            v.swap(a, b);
-            match i {
-                0 => assert!(v == [1, 3, 2]),
-                1 => assert!(v == [3, 1, 2]),
-                2 => assert!(v == [3, 2, 1]),
-                3 => assert!(v == [2, 3, 1]),
-                4 => assert!(v == [2, 1, 3]),
-                5 => assert!(v == [1, 2, 3]),
-                _ => fail!(),
-            }
-        }
-    }
-
-    #[test]
-    fn test_permutations() {
-        {
-            let v: [int, ..0] = [];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 1);
-            assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.as_slice().to_owned()));
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = ["Hello".to_string()];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 1);
-            assert_eq!(max_opt.unwrap(), 1);
-            assert_eq!(it.next(), Some(v.as_slice().to_owned()));
-            assert_eq!(it.next(), None);
-        }
-        {
-            let v = [1, 2, 3];
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 3*2);
-            assert_eq!(max_opt.unwrap(), 3*2);
-            assert_eq!(it.next(), Some(box [1,2,3]));
-            assert_eq!(it.next(), Some(box [1,3,2]));
-            assert_eq!(it.next(), Some(box [3,1,2]));
-            let (min_size, max_opt) = it.size_hint();
-            assert_eq!(min_size, 3);
-            assert_eq!(max_opt.unwrap(), 3);
-            assert_eq!(it.next(), Some(box [3,2,1]));
-            assert_eq!(it.next(), Some(box [2,3,1]));
-            assert_eq!(it.next(), Some(box [2,1,3]));
-            assert_eq!(it.next(), None);
-        }
-        {
-            // check that we have N! permutations
-            let v = ['A', 'B', 'C', 'D', 'E', 'F'];
-            let mut amt = 0;
-            let mut it = v.permutations();
-            let (min_size, max_opt) = it.size_hint();
-            for _perm in it {
-                amt += 1;
-            }
-            assert_eq!(amt, it.swaps.swaps_made);
-            assert_eq!(amt, min_size);
-            assert_eq!(amt, 2 * 3 * 4 * 5 * 6);
-            assert_eq!(amt, max_opt.unwrap());
-        }
-    }
-
-    #[test]
-    fn test_lexicographic_permutations() {
-        let v : &mut[int] = &mut[1, 2, 3, 4, 5];
-        assert!(v.prev_permutation() == false);
-        assert!(v.next_permutation());
-        assert_eq!(v, &mut[1, 2, 3, 5, 4]);
-        assert!(v.prev_permutation());
-        assert_eq!(v, &mut[1, 2, 3, 4, 5]);
-        assert!(v.next_permutation());
-        assert!(v.next_permutation());
-        assert_eq!(v, &mut[1, 2, 4, 3, 5]);
-        assert!(v.next_permutation());
-        assert_eq!(v, &mut[1, 2, 4, 5, 3]);
-
-        let v : &mut[int] = &mut[1, 0, 0, 0];
-        assert!(v.next_permutation() == false);
-        assert!(v.prev_permutation());
-        assert_eq!(v, &mut[0, 1, 0, 0]);
-        assert!(v.prev_permutation());
-        assert_eq!(v, &mut[0, 0, 1, 0]);
-        assert!(v.prev_permutation());
-        assert_eq!(v, &mut[0, 0, 0, 1]);
-        assert!(v.prev_permutation() == false);
-    }
-
-    #[test]
-    fn test_lexicographic_permutations_empty_and_short() {
-        let empty : &mut[int] = &mut[];
-        assert!(empty.next_permutation() == false);
-        assert_eq!(empty, &mut[]);
-        assert!(empty.prev_permutation() == false);
-        assert_eq!(empty, &mut[]);
-
-        let one_elem : &mut[int] = &mut[4];
-        assert!(one_elem.prev_permutation() == false);
-        assert_eq!(one_elem, &mut[4]);
-        assert!(one_elem.next_permutation() == false);
-        assert_eq!(one_elem, &mut[4]);
-
-        let two_elem : &mut[int] = &mut[1, 2];
-        assert!(two_elem.prev_permutation() == false);
-        assert_eq!(two_elem, &mut[1, 2]);
-        assert!(two_elem.next_permutation());
-        assert_eq!(two_elem, &mut[2, 1]);
-        assert!(two_elem.next_permutation() == false);
-        assert_eq!(two_elem, &mut[2, 1]);
-        assert!(two_elem.prev_permutation());
-        assert_eq!(two_elem, &mut[1, 2]);
-        assert!(two_elem.prev_permutation() == false);
-        assert_eq!(two_elem, &mut[1, 2]);
-    }
-
-    #[test]
-    fn test_position_elem() {
-        assert!([].position_elem(&1).is_none());
-
-        let v1 = box [1, 2, 3, 3, 2, 5];
-        assert_eq!(v1.position_elem(&1), Some(0u));
-        assert_eq!(v1.position_elem(&2), Some(1u));
-        assert_eq!(v1.position_elem(&5), Some(5u));
-        assert!(v1.position_elem(&4).is_none());
-    }
-
-    #[test]
-    fn test_bsearch_elem() {
-        assert_eq!([1,2,3,4,5].bsearch_elem(&5), Some(4));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&4), Some(3));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&3), Some(2));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&2), Some(1));
-        assert_eq!([1,2,3,4,5].bsearch_elem(&1), Some(0));
-
-        assert_eq!([2,4,6,8,10].bsearch_elem(&1), None);
-        assert_eq!([2,4,6,8,10].bsearch_elem(&5), None);
-        assert_eq!([2,4,6,8,10].bsearch_elem(&4), Some(1));
-        assert_eq!([2,4,6,8,10].bsearch_elem(&10), Some(4));
-
-        assert_eq!([2,4,6,8].bsearch_elem(&1), None);
-        assert_eq!([2,4,6,8].bsearch_elem(&5), None);
-        assert_eq!([2,4,6,8].bsearch_elem(&4), Some(1));
-        assert_eq!([2,4,6,8].bsearch_elem(&8), Some(3));
-
-        assert_eq!([2,4,6].bsearch_elem(&1), None);
-        assert_eq!([2,4,6].bsearch_elem(&5), None);
-        assert_eq!([2,4,6].bsearch_elem(&4), Some(1));
-        assert_eq!([2,4,6].bsearch_elem(&6), Some(2));
-
-        assert_eq!([2,4].bsearch_elem(&1), None);
-        assert_eq!([2,4].bsearch_elem(&5), None);
-        assert_eq!([2,4].bsearch_elem(&2), Some(0));
-        assert_eq!([2,4].bsearch_elem(&4), Some(1));
-
-        assert_eq!([2].bsearch_elem(&1), None);
-        assert_eq!([2].bsearch_elem(&5), None);
-        assert_eq!([2].bsearch_elem(&2), Some(0));
-
-        assert_eq!([].bsearch_elem(&1), None);
-        assert_eq!([].bsearch_elem(&5), None);
-
-        assert!([1,1,1,1,1].bsearch_elem(&1) != None);
-        assert!([1,1,1,1,2].bsearch_elem(&1) != None);
-        assert!([1,1,1,2,2].bsearch_elem(&1) != None);
-        assert!([1,1,2,2,2].bsearch_elem(&1) != None);
-        assert_eq!([1,2,2,2,2].bsearch_elem(&1), Some(0));
-
-        assert_eq!([1,2,3,4,5].bsearch_elem(&6), None);
-        assert_eq!([1,2,3,4,5].bsearch_elem(&0), None);
-    }
-
-    #[test]
-    fn test_reverse() {
-        let mut v: ~[int] = box [10, 20];
-        assert_eq!(v[0], 10);
-        assert_eq!(v[1], 20);
-        v.reverse();
-        assert_eq!(v[0], 20);
-        assert_eq!(v[1], 10);
-
-        let mut v3: ~[int] = box [];
-        v3.reverse();
-        assert!(v3.is_empty());
-    }
-
-    #[test]
-    fn test_sort() {
-        use realstd::slice::Vector;
-        use realstd::clone::Clone;
-        for len in range(4u, 25) {
-            for _ in range(0, 100) {
-                let mut v = task_rng().gen_iter::<uint>().take(len)
-                                      .collect::<Vec<uint>>();
-                let mut v1 = v.clone();
-
-                v.as_mut_slice().sort();
-                assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
-
-                v1.as_mut_slice().sort_by(|a, b| a.cmp(b));
-                assert!(v1.as_slice().windows(2).all(|w| w[0] <= w[1]));
-
-                v1.as_mut_slice().sort_by(|a, b| b.cmp(a));
-                assert!(v1.as_slice().windows(2).all(|w| w[0] >= w[1]));
-            }
-        }
-
-        // shouldn't fail/crash
-        let mut v: [uint, .. 0] = [];
-        v.sort();
-
-        let mut v = [0xDEADBEEFu];
-        v.sort();
-        assert!(v == [0xDEADBEEF]);
-    }
-
-    #[test]
-    fn test_sort_stability() {
-        for len in range(4, 25) {
-            for _ in range(0 , 10) {
-                let mut counts = [0, .. 10];
-
-                // create a vector like [(6, 1), (5, 1), (6, 2), ...],
-                // where the first item of each tuple is random, but
-                // the second item represents which occurrence of that
-                // number this element is, i.e. the second elements
-                // will occur in sorted order.
-                let mut v = range(0, len).map(|_| {
-                        let n = task_rng().gen::<uint>() % 10;
-                        counts[n] += 1;
-                        (n, counts[n])
-                    }).collect::<Vec<(uint, int)>>();
-
-                // only sort on the first element, so an unstable sort
-                // may mix up the counts.
-                v.sort_by(|&(a,_), &(b,_)| a.cmp(&b));
-
-                // this comparison includes the count (the second item
-                // of the tuple), so elements with equal first items
-                // will need to be ordered with increasing
-                // counts... i.e. exactly asserting that this sort is
-                // stable.
-                assert!(v.as_slice().windows(2).all(|w| w[0] <= w[1]));
-            }
-        }
-    }
-
-    #[test]
-    fn test_partition() {
-        assert_eq!((box []).partition(|x: &int| *x < 3), (vec![], vec![]));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
-        assert_eq!((box [1, 2, 3]).partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
-    }
-
-    #[test]
-    fn test_partitioned() {
-        assert_eq!(([]).partitioned(|x: &int| *x < 3), (vec![], vec![]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
-        assert_eq!(([1, 2, 3]).partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
-    }
-
-    #[test]
-    fn test_concat() {
-        let v: [~[int], ..0] = [];
-        assert_eq!(v.concat_vec(), vec![]);
-        assert_eq!([box [1], box [2,3]].concat_vec(), vec![1, 2, 3]);
-
-        assert_eq!([&[1], &[2,3]].concat_vec(), vec![1, 2, 3]);
-    }
-
-    #[test]
-    fn test_connect() {
-        let v: [~[int], ..0] = [];
-        assert_eq!(v.connect_vec(&0), vec![]);
-        assert_eq!([box [1], box [2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
-        assert_eq!([box [1], box [2], box [3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
-
-        assert_eq!([&[1], &[2, 3]].connect_vec(&0), vec![1, 0, 2, 3]);
-        assert_eq!([&[1], &[2], &[3]].connect_vec(&0), vec![1, 0, 2, 0, 3]);
-    }
-
-    #[test]
-    fn test_shift() {
-        let mut x = vec![1, 2, 3];
-        assert_eq!(x.shift(), Some(1));
-        assert_eq!(&x, &vec![2, 3]);
-        assert_eq!(x.shift(), Some(2));
-        assert_eq!(x.shift(), Some(3));
-        assert_eq!(x.shift(), None);
-        assert_eq!(x.len(), 0);
-    }
-
-    #[test]
-    fn test_unshift() {
-        let mut x = vec![1, 2, 3];
-        x.unshift(0);
-        assert_eq!(x, vec![0, 1, 2, 3]);
-    }
-
-    #[test]
-    fn test_insert() {
-        let mut a = vec![1, 2, 4];
-        a.insert(2, 3);
-        assert_eq!(a, vec![1, 2, 3, 4]);
-
-        let mut a = vec![1, 2, 3];
-        a.insert(0, 0);
-        assert_eq!(a, vec![0, 1, 2, 3]);
-
-        let mut a = vec![1, 2, 3];
-        a.insert(3, 4);
-        assert_eq!(a, vec![1, 2, 3, 4]);
-
-        let mut a = vec![];
-        a.insert(0, 1);
-        assert_eq!(a, vec![1]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_insert_oob() {
-        let mut a = vec![1, 2, 3];
-        a.insert(4, 5);
-    }
-
-    #[test]
-    fn test_remove() {
-        let mut a = vec![1,2,3,4];
-
-        assert_eq!(a.remove(2), Some(3));
-        assert_eq!(a, vec![1,2,4]);
-
-        assert_eq!(a.remove(2), Some(4));
-        assert_eq!(a, vec![1,2]);
-
-        assert_eq!(a.remove(2), None);
-        assert_eq!(a, vec![1,2]);
-
-        assert_eq!(a.remove(0), Some(1));
-        assert_eq!(a, vec![2]);
-
-        assert_eq!(a.remove(0), Some(2));
-        assert_eq!(a, vec![]);
-
-        assert_eq!(a.remove(0), None);
-        assert_eq!(a.remove(10), None);
-    }
-
-    #[test]
-    fn test_capacity() {
-        let mut v = vec![0u64];
-        v.reserve_exact(10u);
-        assert_eq!(v.capacity(), 10u);
-        let mut v = vec![0u32];
-        v.reserve_exact(10u);
-        assert_eq!(v.capacity(), 10u);
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let v = vec![1, 2, 3, 4, 5];
-        let v = v.slice(1u, 3u);
-        assert_eq!(v.len(), 2u);
-        assert_eq!(v[0], 2);
-        assert_eq!(v[1], 3);
-    }
-
-
-    #[test]
-    #[should_fail]
-    fn test_from_fn_fail() {
-        Vec::from_fn(100, |v| {
-            if v == 50 { fail!() }
-            box 0
-        });
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_from_elem_fail() {
-        use cell::Cell;
-        use rc::Rc;
-
-        struct S {
-            f: Cell<int>,
-            boxes: (Box<int>, Rc<int>)
-        }
-
-        impl Clone for S {
-            fn clone(&self) -> S {
-                self.f.set(self.f.get() + 1);
-                if self.f.get() == 10 { fail!() }
-                S { f: self.f, boxes: self.boxes.clone() }
-            }
-        }
-
-        let s = S { f: Cell::new(0), boxes: (box 0, Rc::new(0)) };
-        let _ = Vec::from_elem(100, s);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_grow_fn_fail() {
-        use rc::Rc;
-        let mut v = vec![];
-        v.grow_fn(100, |i| {
-            if i == 50 {
-                fail!()
-            }
-            (box 0, Rc::new(0))
-        })
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_permute_fail() {
-        use rc::Rc;
-        let v = [(box 0, Rc::new(0)), (box 0, Rc::new(0)),
-                 (box 0, Rc::new(0)), (box 0, Rc::new(0))];
-        let mut i = 0;
-        for _ in v.permutations() {
-            if i == 2 {
-                fail!()
-            }
-            i += 1;
-        }
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_copy_memory_oob() {
-        unsafe {
-            let mut a = [1, 2, 3, 4];
-            let b = [1, 2, 3, 4, 5];
-            a.copy_memory(b);
-        }
-    }
-
-    #[test]
-    fn test_total_ord() {
-        [1, 2, 3, 4].cmp(& &[1, 2, 3]) == Greater;
-        [1, 2, 3].cmp(& &[1, 2, 3, 4]) == Less;
-        [1, 2, 3, 4].cmp(& &[1, 2, 3, 4]) == Equal;
-        [1, 2, 3, 4, 5, 5, 5, 5].cmp(& &[1, 2, 3, 4, 5, 6]) == Less;
-        [2, 2].cmp(& &[1, 2, 3, 4]) == Greater;
-    }
-
-    #[test]
-    fn test_iterator() {
-        use iter::*;
-        let xs = [1, 2, 5, 10, 11];
-        let mut it = xs.iter();
-        assert_eq!(it.size_hint(), (5, Some(5)));
-        assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.size_hint(), (4, Some(4)));
-        assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.size_hint(), (3, Some(3)));
-        assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.size_hint(), (2, Some(2)));
-        assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.size_hint(), (1, Some(1)));
-        assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.size_hint(), (0, Some(0)));
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_random_access_iterator() {
-        use iter::*;
-        let xs = [1, 2, 5, 10, 11];
-        let mut it = xs.iter();
-
-        assert_eq!(it.indexable(), 5);
-        assert_eq!(it.idx(0).unwrap(), &1);
-        assert_eq!(it.idx(2).unwrap(), &5);
-        assert_eq!(it.idx(4).unwrap(), &11);
-        assert!(it.idx(5).is_none());
-
-        assert_eq!(it.next().unwrap(), &1);
-        assert_eq!(it.indexable(), 4);
-        assert_eq!(it.idx(0).unwrap(), &2);
-        assert_eq!(it.idx(3).unwrap(), &11);
-        assert!(it.idx(4).is_none());
-
-        assert_eq!(it.next().unwrap(), &2);
-        assert_eq!(it.indexable(), 3);
-        assert_eq!(it.idx(1).unwrap(), &10);
-        assert!(it.idx(3).is_none());
-
-        assert_eq!(it.next().unwrap(), &5);
-        assert_eq!(it.indexable(), 2);
-        assert_eq!(it.idx(1).unwrap(), &11);
-
-        assert_eq!(it.next().unwrap(), &10);
-        assert_eq!(it.indexable(), 1);
-        assert_eq!(it.idx(0).unwrap(), &11);
-        assert!(it.idx(1).is_none());
-
-        assert_eq!(it.next().unwrap(), &11);
-        assert_eq!(it.indexable(), 0);
-        assert!(it.idx(0).is_none());
-
-        assert!(it.next().is_none());
-    }
-
-    #[test]
-    fn test_iter_size_hints() {
-        use iter::*;
-        let mut xs = [1, 2, 5, 10, 11];
-        assert_eq!(xs.iter().size_hint(), (5, Some(5)));
-        assert_eq!(xs.mut_iter().size_hint(), (5, Some(5)));
-    }
-
-    #[test]
-    fn test_iter_clone() {
-        let xs = [1, 2, 5];
-        let mut it = xs.iter();
-        it.next();
-        let mut jt = it.clone();
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next(), jt.next());
-        assert_eq!(it.next(), jt.next());
-    }
-
-    #[test]
-    fn test_mut_iterator() {
-        use iter::*;
-        let mut xs = [1, 2, 3, 4, 5];
-        for x in xs.mut_iter() {
-            *x += 1;
-        }
-        assert!(xs == [2, 3, 4, 5, 6])
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-        use iter::*;
-
-        let xs = [1, 2, 5, 10, 11];
-        let ys = [11, 10, 5, 2, 1];
-        let mut i = 0;
-        for &x in xs.iter().rev() {
-            assert_eq!(x, ys[i]);
-            i += 1;
-        }
-        assert_eq!(i, 5);
-    }
-
-    #[test]
-    fn test_mut_rev_iterator() {
-        use iter::*;
-        let mut xs = [1u, 2, 3, 4, 5];
-        for (i,x) in xs.mut_iter().rev().enumerate() {
-            *x += i;
-        }
-        assert!(xs == [5, 5, 5, 5, 5])
-    }
-
-    #[test]
-    fn test_move_iterator() {
-        use iter::*;
-        let xs = box [1u,2,3,4,5];
-        assert_eq!(xs.move_iter().fold(0, |a: uint, b: uint| 10*a + b), 12345);
-    }
-
-    #[test]
-    fn test_move_rev_iterator() {
-        use iter::*;
-        let xs = box [1u,2,3,4,5];
-        assert_eq!(xs.move_iter().rev().fold(0, |a: uint, b: uint| 10*a + b), 54321);
-    }
-
-    #[test]
-    fn test_splitator() {
-        let xs = &[1i,2,3,4,5];
-
-        assert_eq!(xs.split(|x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1], &[3], &[5]]);
-        assert_eq!(xs.split(|x| *x == 1).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[], &[2,3,4,5]]);
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1,2,3,4], &[]]);
-        assert_eq!(xs.split(|x| *x == 10).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1,2,3,4,5]]);
-        assert_eq!(xs.split(|_| true).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[], &[], &[], &[], &[], &[]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
-    }
-
-    #[test]
-    fn test_splitnator() {
-        let xs = &[1i,2,3,4,5];
-
-        assert_eq!(xs.splitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1,2,3,4,5]]);
-        assert_eq!(xs.splitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1], &[3,4,5]]);
-        assert_eq!(xs.splitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[], &[], &[], &[4,5]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.splitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
-    }
-
-    #[test]
-    fn test_rsplitator() {
-        let xs = &[1i,2,3,4,5];
-
-        assert_eq!(xs.split(|x| *x % 2 == 0).rev().collect::<Vec<&[int]>>().as_slice(),
-                   &[&[5], &[3], &[1]]);
-        assert_eq!(xs.split(|x| *x == 1).rev().collect::<Vec<&[int]>>().as_slice(),
-                   &[&[2,3,4,5], &[]]);
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(),
-                   &[&[], &[1,2,3,4]]);
-        assert_eq!(xs.split(|x| *x == 10).rev().collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1,2,3,4,5]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.split(|x| *x == 5).rev().collect::<Vec<&[int]>>().as_slice(), &[&[]]);
-    }
-
-    #[test]
-    fn test_rsplitnator() {
-        let xs = &[1,2,3,4,5];
-
-        assert_eq!(xs.rsplitn(0, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[1,2,3,4,5]]);
-        assert_eq!(xs.rsplitn(1, |x| *x % 2 == 0).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[5], &[1,2,3]]);
-        assert_eq!(xs.rsplitn(3, |_| true).collect::<Vec<&[int]>>().as_slice(),
-                   &[&[], &[], &[], &[1,2]]);
-
-        let xs: &[int] = &[];
-        assert_eq!(xs.rsplitn(1, |x| *x == 5).collect::<Vec<&[int]>>().as_slice(), &[&[]]);
-    }
-
-    #[test]
-    fn test_windowsator() {
-        let v = &[1i,2,3,4];
-
-        assert_eq!(v.windows(2).collect::<Vec<&[int]>>().as_slice(), &[&[1,2], &[2,3], &[3,4]]);
-        assert_eq!(v.windows(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[2,3,4]]);
-        assert!(v.windows(6).next().is_none());
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_windowsator_0() {
-        let v = &[1i,2,3,4];
-        let _it = v.windows(0);
-    }
-
-    #[test]
-    fn test_chunksator() {
-        let v = &[1i,2,3,4,5];
-
-        assert_eq!(v.chunks(2).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2], &[3,4], &[5]]);
-        assert_eq!(v.chunks(3).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3], &[4,5]]);
-        assert_eq!(v.chunks(6).collect::<Vec<&[int]>>().as_slice(), &[&[1i,2,3,4,5]]);
-
-        assert_eq!(v.chunks(2).rev().collect::<Vec<&[int]>>().as_slice(), &[&[5i], &[3,4], &[1,2]]);
-        let mut it = v.chunks(2);
-        assert_eq!(it.indexable(), 3);
-        assert_eq!(it.idx(0).unwrap(), &[1,2]);
-        assert_eq!(it.idx(1).unwrap(), &[3,4]);
-        assert_eq!(it.idx(2).unwrap(), &[5]);
-        assert_eq!(it.idx(3), None);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_chunksator_0() {
-        let v = &[1i,2,3,4];
-        let _it = v.chunks(0);
-    }
-
-    #[test]
-    fn test_move_from() {
-        let mut a = [1,2,3,4,5];
-        let b = box [6,7,8];
-        assert_eq!(a.move_from(b, 0, 3), 3);
-        assert!(a == [6,7,8,4,5]);
-        let mut a = [7,2,8,1];
-        let b = box [3,1,4,1,5,9];
-        assert_eq!(a.move_from(b, 0, 6), 4);
-        assert!(a == [3,1,4,1]);
-        let mut a = [1,2,3,4];
-        let b = box [5,6,7,8,9,0];
-        assert_eq!(a.move_from(b, 2, 3), 1);
-        assert!(a == [7,2,3,4]);
-        let mut a = [1,2,3,4,5];
-        let b = box [5,6,7,8,9,0];
-        assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
-        assert!(a == [1,2,6,7,5]);
-    }
-
-    #[test]
-    fn test_copy_from() {
-        let mut a = [1,2,3,4,5];
-        let b = [6,7,8];
-        assert_eq!(a.copy_from(b), 3);
-        assert!(a == [6,7,8,4,5]);
-        let mut c = [7,2,8,1];
-        let d = [3,1,4,1,5,9];
-        assert_eq!(c.copy_from(d), 4);
-        assert!(c == [3,1,4,1]);
-    }
-
-    #[test]
-    fn test_reverse_part() {
-        let mut values = [1,2,3,4,5];
-        values.mut_slice(1, 4).reverse();
-        assert!(values == [1,4,3,2,5]);
-    }
-
-    #[test]
-    fn test_show() {
-        macro_rules! test_show_vec(
-            ($x:expr, $x_str:expr) => ({
-                let (x, x_str) = ($x, $x_str);
-                assert_eq!(format!("{}", x), x_str);
-                assert_eq!(format!("{}", x.as_slice()), x_str);
-            })
-        )
-        let empty: ~[int] = box [];
-        test_show_vec!(empty, "[]".to_string());
-        test_show_vec!(box [1], "[1]".to_string());
-        test_show_vec!(box [1, 2, 3], "[1, 2, 3]".to_string());
-        test_show_vec!(box [box [], box [1u], box [1u, 1u]],
-                       "[[], [1], [1, 1]]".to_string());
-
-        let empty_mut: &mut [int] = &mut[];
-        test_show_vec!(empty_mut, "[]".to_string());
-        test_show_vec!(&mut[1], "[1]".to_string());
-        test_show_vec!(&mut[1, 2, 3], "[1, 2, 3]".to_string());
-        test_show_vec!(&mut[&mut[], &mut[1u], &mut[1u, 1u]],
-                       "[[], [1], [1, 1]]".to_string());
-    }
-
-    #[test]
-    fn test_vec_default() {
-        use default::Default;
-        macro_rules! t (
-            ($ty:ty) => {{
-                let v: $ty = Default::default();
-                assert!(v.is_empty());
-            }}
-        );
-
-        t!(&[int]);
-        t!(~[int]);
-        t!(Vec<int>);
-    }
-
-    #[test]
-    fn test_bytes_set_memory() {
-        use slice::bytes::MutableByteVector;
-        let mut values = [1u8,2,3,4,5];
-        values.mut_slice(0,5).set_memory(0xAB);
-        assert!(values == [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
-        values.mut_slice(2,4).set_memory(0xFF);
-        assert!(values == [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow_does_not_cause_segfault() {
-        let mut v = vec![];
-        v.reserve_exact(-1);
-        v.push(1);
-        v.push(2);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_overflow_does_not_cause_segfault_managed() {
-        use rc::Rc;
-        let mut v = vec![Rc::new(1)];
-        v.reserve_exact(-1);
-        v.push(Rc::new(2));
-    }
-
-    #[test]
-    fn test_mut_split_at() {
-        let mut values = [1u8,2,3,4,5];
-        {
-            let (left, right) = values.mut_split_at(2);
-            assert!(left.slice(0, left.len()) == [1, 2]);
-            for p in left.mut_iter() {
-                *p += 1;
-            }
-
-            assert!(right.slice(0, right.len()) == [3, 4, 5]);
-            for p in right.mut_iter() {
-                *p += 2;
-            }
-        }
-
-        assert!(values == [2, 3, 5, 6, 7]);
-    }
-
-    #[deriving(Clone, PartialEq)]
-    struct Foo;
-
-    #[test]
-    fn test_iter_zero_sized() {
-        let mut v = vec![Foo, Foo, Foo];
-        assert_eq!(v.len(), 3);
-        let mut cnt = 0;
-
-        for f in v.iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 3);
-
-        for f in v.slice(1, 3).iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 5);
-
-        for f in v.mut_iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 8);
-
-        for f in v.move_iter() {
-            assert!(f == Foo);
-            cnt += 1;
-        }
-        assert_eq!(cnt, 11);
-
-        let xs: [Foo, ..3] = [Foo, Foo, Foo];
-        cnt = 0;
-        for f in xs.iter() {
-            assert!(*f == Foo);
-            cnt += 1;
-        }
-        assert!(cnt == 3);
-    }
-
-    #[test]
-    fn test_shrink_to_fit() {
-        let mut xs = vec![0, 1, 2, 3];
-        for i in range(4, 100) {
-            xs.push(i)
-        }
-        assert_eq!(xs.capacity(), 128);
-        xs.shrink_to_fit();
-        assert_eq!(xs.capacity(), 100);
-        assert_eq!(xs, range(0, 100).collect::<Vec<_>>());
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(bytes!("foobar").starts_with(bytes!("foo")));
-        assert!(!bytes!("foobar").starts_with(bytes!("oob")));
-        assert!(!bytes!("foobar").starts_with(bytes!("bar")));
-        assert!(!bytes!("foo").starts_with(bytes!("foobar")));
-        assert!(!bytes!("bar").starts_with(bytes!("foobar")));
-        assert!(bytes!("foobar").starts_with(bytes!("foobar")));
-        let empty: &[u8] = [];
-        assert!(empty.starts_with(empty));
-        assert!(!empty.starts_with(bytes!("foo")));
-        assert!(bytes!("foobar").starts_with(empty));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(bytes!("foobar").ends_with(bytes!("bar")));
-        assert!(!bytes!("foobar").ends_with(bytes!("oba")));
-        assert!(!bytes!("foobar").ends_with(bytes!("foo")));
-        assert!(!bytes!("foo").ends_with(bytes!("foobar")));
-        assert!(!bytes!("bar").ends_with(bytes!("foobar")));
-        assert!(bytes!("foobar").ends_with(bytes!("foobar")));
-        let empty: &[u8] = [];
-        assert!(empty.ends_with(empty));
-        assert!(!empty.ends_with(bytes!("foo")));
-        assert!(bytes!("foobar").ends_with(empty));
-    }
-
-    #[test]
-    fn test_shift_ref() {
-        let mut x: &[int] = [1, 2, 3, 4, 5];
-        let h = x.shift_ref();
-        assert_eq!(*h.unwrap(), 1);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 2);
-        assert_eq!(x[3], 5);
-
-        let mut y: &[int] = [];
-        assert_eq!(y.shift_ref(), None);
-    }
-
-    #[test]
-    fn test_pop_ref() {
-        let mut x: &[int] = [1, 2, 3, 4, 5];
-        let h = x.pop_ref();
-        assert_eq!(*h.unwrap(), 5);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 1);
-        assert_eq!(x[3], 4);
-
-        let mut y: &[int] = [];
-        assert!(y.pop_ref().is_none());
-    }
-
-    #[test]
-    fn test_mut_splitator() {
-        let mut xs = [0,1,0,2,3,0,0,4,5,0];
-        assert_eq!(xs.mut_split(|x| *x == 0).len(), 6);
-        for slice in xs.mut_split(|x| *x == 0) {
-            slice.reverse();
-        }
-        assert!(xs == [0,1,0,3,2,0,0,5,4,0]);
-
-        let mut xs = [0,1,0,2,3,0,0,4,5,0,6,7];
-        for slice in xs.mut_split(|x| *x == 0).take(5) {
-            slice.reverse();
-        }
-        assert!(xs == [0,1,0,3,2,0,0,5,4,0,6,7]);
-    }
-
-    #[test]
-    fn test_mut_splitator_rev() {
-        let mut xs = [1,2,0,3,4,0,0,5,6,0];
-        for slice in xs.mut_split(|x| *x == 0).rev().take(4) {
-            slice.reverse();
-        }
-        assert!(xs == [1,2,0,4,3,0,0,6,5,0]);
-    }
-
-    #[test]
-    fn test_mut_chunks() {
-        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
-        for (i, chunk) in v.mut_chunks(3).enumerate() {
-            for x in chunk.mut_iter() {
-                *x = i as u8;
-            }
-        }
-        let result = [0u8, 0, 0, 1, 1, 1, 2];
-        assert!(v == result);
-    }
-
-    #[test]
-    fn test_mut_chunks_rev() {
-        let mut v = [0u8, 1, 2, 3, 4, 5, 6];
-        for (i, chunk) in v.mut_chunks(3).rev().enumerate() {
-            for x in chunk.mut_iter() {
-                *x = i as u8;
-            }
-        }
-        let result = [2u8, 2, 2, 1, 1, 1, 0];
-        assert!(v == result);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_mut_chunks_0() {
-        let mut v = [1, 2, 3, 4];
-        let _it = v.mut_chunks(0);
-    }
-
-    #[test]
-    fn test_mut_shift_ref() {
-        let mut x: &mut [int] = [1, 2, 3, 4, 5];
-        let h = x.mut_shift_ref();
-        assert_eq!(*h.unwrap(), 1);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 2);
-        assert_eq!(x[3], 5);
-
-        let mut y: &mut [int] = [];
-        assert!(y.mut_shift_ref().is_none());
-    }
-
-    #[test]
-    fn test_mut_pop_ref() {
-        let mut x: &mut [int] = [1, 2, 3, 4, 5];
-        let h = x.mut_pop_ref();
-        assert_eq!(*h.unwrap(), 5);
-        assert_eq!(x.len(), 4);
-        assert_eq!(x[0], 1);
-        assert_eq!(x[3], 4);
-
-        let mut y: &mut [int] = [];
-        assert!(y.mut_pop_ref().is_none());
-    }
-
-    #[test]
-    fn test_mut_last() {
-        let mut x = [1, 2, 3, 4, 5];
-        let h = x.mut_last();
-        assert_eq!(*h.unwrap(), 5);
-
-        let y: &mut [int] = [];
-        assert!(y.mut_last().is_none());
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-    use mem;
-    use prelude::*;
-    use ptr;
-    use rand::{weak_rng, Rng};
-
-    #[bench]
-    fn iterator(b: &mut Bencher) {
-        // peculiar numbers to stop LLVM from optimising the summation
-        // out.
-        let v = Vec::from_fn(100, |i| i ^ (i << 1) ^ (i >> 1));
-
-        b.iter(|| {
-            let mut sum = 0;
-            for x in v.iter() {
-                sum += *x;
-            }
-            // sum == 11806, to stop dead code elimination.
-            if sum == 0 {fail!()}
-        })
-    }
-
-    #[bench]
-    fn mut_iterator(b: &mut Bencher) {
-        let mut v = Vec::from_elem(100, 0);
-
-        b.iter(|| {
-            let mut i = 0;
-            for x in v.mut_iter() {
-                *x = i;
-                i += 1;
-            }
-        })
-    }
-
-    #[bench]
-    fn concat(b: &mut Bencher) {
-        let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
-        b.iter(|| {
-            xss.as_slice().concat_vec()
-        });
-    }
-
-    #[bench]
-    fn connect(b: &mut Bencher) {
-        let xss: Vec<Vec<uint>> = Vec::from_fn(100, |i| range(0, i).collect());
-        b.iter(|| {
-            xss.as_slice().connect_vec(&0)
-        });
-    }
-
-    #[bench]
-    fn push(b: &mut Bencher) {
-        let mut vec: Vec<uint> = vec![];
-        b.iter(|| {
-            vec.push(0);
-            &vec
-        })
-    }
-
-    #[bench]
-    fn starts_with_same_vector(b: &mut Bencher) {
-        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
-        b.iter(|| {
-            vec.as_slice().starts_with(vec.as_slice())
-        })
-    }
-
-    #[bench]
-    fn starts_with_single_element(b: &mut Bencher) {
-        let vec: Vec<uint> = vec![0];
-        b.iter(|| {
-            vec.as_slice().starts_with(vec.as_slice())
-        })
-    }
-
-    #[bench]
-    fn starts_with_diff_one_element_at_end(b: &mut Bencher) {
-        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
-        let mut match_vec: Vec<uint> = Vec::from_fn(99, |i| i);
-        match_vec.push(0);
-        b.iter(|| {
-            vec.as_slice().starts_with(match_vec.as_slice())
-        })
-    }
-
-    #[bench]
-    fn ends_with_same_vector(b: &mut Bencher) {
-        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
-        b.iter(|| {
-            vec.as_slice().ends_with(vec.as_slice())
-        })
-    }
-
-    #[bench]
-    fn ends_with_single_element(b: &mut Bencher) {
-        let vec: Vec<uint> = vec![0];
-        b.iter(|| {
-            vec.as_slice().ends_with(vec.as_slice())
-        })
-    }
-
-    #[bench]
-    fn ends_with_diff_one_element_at_beginning(b: &mut Bencher) {
-        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
-        let mut match_vec: Vec<uint> = Vec::from_fn(100, |i| i);
-        match_vec.as_mut_slice()[0] = 200;
-        b.iter(|| {
-            vec.as_slice().starts_with(match_vec.as_slice())
-        })
-    }
-
-    #[bench]
-    fn contains_last_element(b: &mut Bencher) {
-        let vec: Vec<uint> = Vec::from_fn(100, |i| i);
-        b.iter(|| {
-            vec.contains(&99u)
-        })
-    }
-
-    #[bench]
-    fn zero_1kb_from_elem(b: &mut Bencher) {
-        b.iter(|| {
-            Vec::from_elem(1024, 0u8)
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_set_memory(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v: Vec<uint> = Vec::with_capacity(1024);
-            unsafe {
-                let vp = v.as_mut_ptr();
-                ptr::set_memory(vp, 0, 1024);
-                v.set_len(1024);
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_fixed_repeat(b: &mut Bencher) {
-        b.iter(|| {
-            box [0u8, ..1024]
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_loop_set(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v: Vec<uint> = Vec::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for i in range(0u, 1024) {
-                *v.get_mut(i) = 0;
-            }
-        });
-    }
-
-    #[bench]
-    fn zero_1kb_mut_iter(b: &mut Bencher) {
-        b.iter(|| {
-            let mut v = Vec::with_capacity(1024);
-            unsafe {
-                v.set_len(1024);
-            }
-            for x in v.mut_iter() {
-                *x = 0;
-            }
-            v
-        });
-    }
-
-    #[bench]
-    fn random_inserts(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-                let mut v = Vec::from_elem(30, (0u, 0u));
-                for _ in range(0, 100) {
-                    let l = v.len();
-                    v.insert(rng.gen::<uint>() % (l + 1),
-                             (1, 1));
-                }
-            })
-    }
-    #[bench]
-    fn random_removes(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-                let mut v = Vec::from_elem(130, (0u, 0u));
-                for _ in range(0, 100) {
-                    let l = v.len();
-                    v.remove(rng.gen::<uint>() % l);
-                }
-            })
-    }
-
-    #[bench]
-    fn sort_random_small(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<u64>().take(5).collect::<Vec<u64>>();
-            v.as_mut_slice().sort();
-        });
-        b.bytes = 5 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_medium(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<u64>().take(100).collect::<Vec<u64>>();
-            v.as_mut_slice().sort();
-        });
-        b.bytes = 100 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_random_large(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<u64>().take(10000).collect::<Vec<u64>>();
-            v.as_mut_slice().sort();
-        });
-        b.bytes = 10000 * mem::size_of::<u64>() as u64;
-    }
-
-    #[bench]
-    fn sort_sorted(b: &mut Bencher) {
-        let mut v = Vec::from_fn(10000, |i| i);
-        b.iter(|| {
-            v.sort();
-        });
-        b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
-    }
-
-    type BigSortable = (u64,u64,u64,u64);
-
-    #[bench]
-    fn sort_big_random_small(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(5)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_medium(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(100)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_random_large(b: &mut Bencher) {
-        let mut rng = weak_rng();
-        b.iter(|| {
-            let mut v = rng.gen_iter::<BigSortable>().take(10000)
-                           .collect::<Vec<BigSortable>>();
-            v.sort();
-        });
-        b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
-    }
-
-    #[bench]
-    fn sort_big_sorted(b: &mut Bencher) {
-        let mut v = Vec::from_fn(10000u, |i| (i, i, i, i));
-        b.iter(|| {
-            v.sort();
-        });
-        b.bytes = (v.len() * mem::size_of_val(v.get(0))) as u64;
-    }
-}
diff --git a/src/libstd/str.rs b/src/libstd/str.rs
deleted file mode 100644 (file)
index 3af3821..0000000
+++ /dev/null
@@ -1,2446 +0,0 @@
-// Copyright 2012-2014 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.
-
-/*!
-
-Unicode string manipulation (`str` type)
-
-# Basic Usage
-
-Rust's string type is one of the core primitive types of the language. While
-represented by the name `str`, the name `str` is not actually a valid type in
-Rust. Each string must also be decorated with a pointer. `String` is used
-for an owned string, so there is only one commonly-used `str` type in Rust:
-`&str`.
-
-`&str` is the borrowed string type. This type of string can only be created
-from other strings, unless it is a static string (see below). As the word
-"borrowed" implies, this type of string is owned elsewhere, and this string
-cannot be moved out of.
-
-As an example, here's some code that uses a string.
-
-```rust
-fn main() {
-    let borrowed_string = "This string is borrowed with the 'static lifetime";
-}
-```
-
-From the example above, you can see that Rust's string literals have the
-`'static` lifetime. This is akin to C's concept of a static string.
-
-String literals are allocated statically in the rodata of the
-executable/library. The string then has the type `&'static str` meaning that
-the string is valid for the `'static` lifetime, otherwise known as the
-lifetime of the entire program. As can be inferred from the type, these static
-strings are not mutable.
-
-# Mutability
-
-Many languages have immutable strings by default, and Rust has a particular
-flavor on this idea. As with the rest of Rust types, strings are immutable by
-default. If a string is declared as `mut`, however, it may be mutated. This
-works the same way as the rest of Rust's type system in the sense that if
-there's a mutable reference to a string, there may only be one mutable reference
-to that string. With these guarantees, strings can easily transition between
-being mutable/immutable with the same benefits of having mutable strings in
-other languages.
-
-# Representation
-
-Rust's string type, `str`, is a sequence of unicode codepoints encoded as a
-stream of UTF-8 bytes. All safely-created strings are guaranteed to be validly
-encoded UTF-8 sequences. Additionally, strings are not null-terminated
-and can contain null codepoints.
-
-The actual representation of strings have direct mappings to vectors: `&str`
-is the same as `&[u8]`.
-
-*/
-
-#![doc(primitive = "str")]
-
-use char::Char;
-use char;
-use clone::Clone;
-use cmp::{PartialEq, Eq, PartialOrd, Ord, Equiv, Ordering};
-use container::Container;
-use default::Default;
-use fmt;
-use io::Writer;
-use iter::{Iterator, range, AdditiveIterator};
-use mem::transmute;
-use mem;
-use option::{None, Option, Some};
-use result::Result;
-use slice::Vector;
-use slice::{ImmutableVector, MutableVector};
-use string::String;
-use vec::Vec;
-
-pub use core::str::{from_utf8, CharEq, Chars, CharOffsets};
-pub use core::str::{Bytes, CharSplits};
-pub use core::str::{CharSplitsN, Words, AnyLines, MatchIndices, StrSplits};
-pub use core::str::{eq_slice, is_utf8, is_utf16, Utf16Items};
-pub use core::str::{Utf16Item, ScalarValue, LoneSurrogate, utf16_items};
-pub use core::str::{truncate_utf16_at_nul, utf8_char_width, CharRange};
-pub use core::str::{Str, StrSlice};
-
-/*
-Section: Creating a string
-*/
-
-/// Consumes a vector of bytes to create a new utf-8 string.
-///
-/// Returns `Err` with the original vector if the vector contains invalid
-/// UTF-8.
-pub fn from_utf8_owned(vv: Vec<u8>) -> Result<String, Vec<u8>> {
-    String::from_utf8(vv)
-}
-
-/// Convert a byte to a UTF-8 string
-///
-/// # Failure
-///
-/// Fails if invalid UTF-8
-pub fn from_byte(b: u8) -> String {
-    assert!(b < 128u8);
-    String::from_char(1, b as char)
-}
-
-/// Convert a char to a string
-pub fn from_char(ch: char) -> String {
-    let mut buf = String::new();
-    buf.push_char(ch);
-    buf
-}
-
-/// Convert a vector of chars to a string
-pub fn from_chars(chs: &[char]) -> String {
-    chs.iter().map(|c| *c).collect()
-}
-
-/// Methods for vectors of strings
-pub trait StrVector {
-    /// Concatenate a vector of strings.
-    fn concat(&self) -> String;
-
-    /// Concatenate a vector of strings, placing a given separator between each.
-    fn connect(&self, sep: &str) -> String;
-}
-
-impl<'a, S: Str> StrVector for &'a [S] {
-    fn concat(&self) -> String {
-        if self.is_empty() {
-            return String::new();
-        }
-
-        // `len` calculation may overflow but push_str but will check boundaries
-        let len = self.iter().map(|s| s.as_slice().len()).sum();
-
-        let mut result = String::with_capacity(len);
-
-        for s in self.iter() {
-            result.push_str(s.as_slice())
-        }
-
-        result
-    }
-
-    fn connect(&self, sep: &str) -> String {
-        if self.is_empty() {
-            return String::new();
-        }
-
-        // concat is faster
-        if sep.is_empty() {
-            return self.concat();
-        }
-
-        // this is wrong without the guarantee that `self` is non-empty
-        // `len` calculation may overflow but push_str but will check boundaries
-        let len = sep.len() * (self.len() - 1)
-            + self.iter().map(|s| s.as_slice().len()).sum();
-        let mut result = String::with_capacity(len);
-        let mut first = true;
-
-        for s in self.iter() {
-            if first {
-                first = false;
-            } else {
-                result.push_str(sep);
-            }
-            result.push_str(s.as_slice());
-        }
-        result
-    }
-}
-
-impl<'a, S: Str> StrVector for Vec<S> {
-    #[inline]
-    fn concat(&self) -> String {
-        self.as_slice().concat()
-    }
-
-    #[inline]
-    fn connect(&self, sep: &str) -> String {
-        self.as_slice().connect(sep)
-    }
-}
-
-/*
-Section: Iterators
-*/
-
-// Helper functions used for Unicode normalization
-fn canonical_sort(comb: &mut [(char, u8)]) {
-    use iter::range;
-    use tuple::Tuple2;
-
-    let len = comb.len();
-    for i in range(0, len) {
-        let mut swapped = false;
-        for j in range(1, len-i) {
-            let class_a = *comb[j-1].ref1();
-            let class_b = *comb[j].ref1();
-            if class_a != 0 && class_b != 0 && class_a > class_b {
-                comb.swap(j-1, j);
-                swapped = true;
-            }
-        }
-        if !swapped { break; }
-    }
-}
-
-#[deriving(Clone)]
-enum DecompositionType {
-    Canonical,
-    Compatible
-}
-
-/// External iterator for a string's decomposition's characters.
-/// Use with the `std::iter` module.
-#[deriving(Clone)]
-pub struct Decompositions<'a> {
-    kind: DecompositionType,
-    iter: Chars<'a>,
-    buffer: Vec<(char, u8)>,
-    sorted: bool
-}
-
-impl<'a> Iterator<char> for Decompositions<'a> {
-    #[inline]
-    fn next(&mut self) -> Option<char> {
-        use unicode::normalization::canonical_combining_class;
-
-        match self.buffer.as_slice().head() {
-            Some(&(c, 0)) => {
-                self.sorted = false;
-                self.buffer.shift();
-                return Some(c);
-            }
-            Some(&(c, _)) if self.sorted => {
-                self.buffer.shift();
-                return Some(c);
-            }
-            _ => self.sorted = false
-        }
-
-        let decomposer = match self.kind {
-            Canonical => char::decompose_canonical,
-            Compatible => char::decompose_compatible
-        };
-
-        if !self.sorted {
-            for ch in self.iter {
-                let buffer = &mut self.buffer;
-                let sorted = &mut self.sorted;
-                decomposer(ch, |d| {
-                    let class = canonical_combining_class(d);
-                    if class == 0 && !*sorted {
-                        canonical_sort(buffer.as_mut_slice());
-                        *sorted = true;
-                    }
-                    buffer.push((d, class));
-                });
-                if *sorted { break }
-            }
-        }
-
-        if !self.sorted {
-            canonical_sort(self.buffer.as_mut_slice());
-            self.sorted = true;
-        }
-
-        match self.buffer.shift() {
-            Some((c, 0)) => {
-                self.sorted = false;
-                Some(c)
-            }
-            Some((c, _)) => Some(c),
-            None => None
-        }
-    }
-
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        let (lower, _) = self.iter.size_hint();
-        (lower, None)
-    }
-}
-
-/// Replace all occurrences of one string with another
-///
-/// # Arguments
-///
-/// * s - The string containing substrings to replace
-/// * from - The string to replace
-/// * to - The replacement string
-///
-/// # Return value
-///
-/// The original string with all occurrences of `from` replaced with `to`
-pub fn replace(s: &str, from: &str, to: &str) -> String {
-    let mut result = String::new();
-    let mut last_end = 0;
-    for (start, end) in s.match_indices(from) {
-        result.push_str(unsafe{raw::slice_bytes(s, last_end, start)});
-        result.push_str(to);
-        last_end = end;
-    }
-    result.push_str(unsafe{raw::slice_bytes(s, last_end, s.len())});
-    result
-}
-
-/*
-Section: Misc
-*/
-
-/// Decode a UTF-16 encoded vector `v` into a string, returning `None`
-/// if `v` contains any invalid data.
-///
-/// # Example
-///
-/// ```rust
-/// use std::str;
-///
-/// // 𝄞music
-/// let mut v = [0xD834, 0xDD1E, 0x006d, 0x0075,
-///              0x0073, 0x0069, 0x0063];
-/// assert_eq!(str::from_utf16(v), Some("𝄞music".to_string()));
-///
-/// // 𝄞mu<invalid>ic
-/// v[4] = 0xD800;
-/// assert_eq!(str::from_utf16(v), None);
-/// ```
-pub fn from_utf16(v: &[u16]) -> Option<String> {
-    let mut s = String::with_capacity(v.len() / 2);
-    for c in utf16_items(v) {
-        match c {
-            ScalarValue(c) => s.push_char(c),
-            LoneSurrogate(_) => return None
-        }
-    }
-    Some(s)
-}
-
-/// Decode a UTF-16 encoded vector `v` into a string, replacing
-/// invalid data with the replacement character (U+FFFD).
-///
-/// # Example
-/// ```rust
-/// use std::str;
-///
-/// // 𝄞mus<invalid>ic<invalid>
-/// let v = [0xD834, 0xDD1E, 0x006d, 0x0075,
-///          0x0073, 0xDD1E, 0x0069, 0x0063,
-///          0xD834];
-///
-/// assert_eq!(str::from_utf16_lossy(v),
-///            "𝄞mus\uFFFDic\uFFFD".to_string());
-/// ```
-pub fn from_utf16_lossy(v: &[u16]) -> String {
-    utf16_items(v).map(|c| c.to_char_lossy()).collect()
-}
-
-// Return the initial codepoint accumulator for the first byte.
-// The first byte is special, only want bottom 5 bits for width 2, 4 bits
-// for width 3, and 3 bits for width 4
-macro_rules! utf8_first_byte(
-    ($byte:expr, $width:expr) => (($byte & (0x7F >> $width)) as u32)
-)
-
-// return the value of $ch updated with continuation byte $byte
-macro_rules! utf8_acc_cont_byte(
-    ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
-)
-
-static TAG_CONT_U8: u8 = 128u8;
-
-/// Converts a vector of bytes to a new utf-8 string.
-/// Any invalid utf-8 sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
-///
-/// # Example
-///
-/// ```rust
-/// let input = bytes!("Hello ", 0xF0, 0x90, 0x80, "World");
-/// let output = std::str::from_utf8_lossy(input);
-/// assert_eq!(output.as_slice(), "Hello \uFFFDWorld");
-/// ```
-pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> {
-    if is_utf8(v) {
-        return Slice(unsafe { mem::transmute(v) })
-    }
-
-    static REPLACEMENT: &'static [u8] = bytes!(0xEF, 0xBF, 0xBD); // U+FFFD in UTF-8
-    let mut i = 0;
-    let total = v.len();
-    fn unsafe_get(xs: &[u8], i: uint) -> u8 {
-        unsafe { *xs.unsafe_ref(i) }
-    }
-    fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 {
-        if i >= total {
-            0
-        } else {
-            unsafe_get(xs, i)
-        }
-    }
-
-    let mut res = String::with_capacity(total);
-
-    if i > 0 {
-        unsafe {
-            res.push_bytes(v.slice_to(i))
-        };
-    }
-
-    // subseqidx is the index of the first byte of the subsequence we're looking at.
-    // It's used to copy a bunch of contiguous good codepoints at once instead of copying
-    // them one by one.
-    let mut subseqidx = 0;
-
-    while i < total {
-        let i_ = i;
-        let byte = unsafe_get(v, i);
-        i += 1;
-
-        macro_rules! error(() => ({
-            unsafe {
-                if subseqidx != i_ {
-                    res.push_bytes(v.slice(subseqidx, i_));
-                }
-                subseqidx = i;
-                res.push_bytes(REPLACEMENT);
-            }
-        }))
-
-        if byte < 128u8 {
-            // subseqidx handles this
-        } else {
-            let w = utf8_char_width(byte);
-
-            match w {
-                2 => {
-                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
-                        error!();
-                        continue;
-                    }
-                    i += 1;
-                }
-                3 => {
-                    match (byte, safe_get(v, i, total)) {
-                        (0xE0        , 0xA0 .. 0xBF) => (),
-                        (0xE1 .. 0xEC, 0x80 .. 0xBF) => (),
-                        (0xED        , 0x80 .. 0x9F) => (),
-                        (0xEE .. 0xEF, 0x80 .. 0xBF) => (),
-                        _ => {
-                            error!();
-                            continue;
-                        }
-                    }
-                    i += 1;
-                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
-                        error!();
-                        continue;
-                    }
-                    i += 1;
-                }
-                4 => {
-                    match (byte, safe_get(v, i, total)) {
-                        (0xF0        , 0x90 .. 0xBF) => (),
-                        (0xF1 .. 0xF3, 0x80 .. 0xBF) => (),
-                        (0xF4        , 0x80 .. 0x8F) => (),
-                        _ => {
-                            error!();
-                            continue;
-                        }
-                    }
-                    i += 1;
-                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
-                        error!();
-                        continue;
-                    }
-                    i += 1;
-                    if safe_get(v, i, total) & 192u8 != TAG_CONT_U8 {
-                        error!();
-                        continue;
-                    }
-                    i += 1;
-                }
-                _ => {
-                    error!();
-                    continue;
-                }
-            }
-        }
-    }
-    if subseqidx < total {
-        unsafe {
-            res.push_bytes(v.slice(subseqidx, total))
-        };
-    }
-    Owned(res.into_string())
-}
-
-/*
-Section: MaybeOwned
-*/
-
-/// A `MaybeOwned` is a string that can hold either a `String` or a `&str`.
-/// This can be useful as an optimization when an allocation is sometimes
-/// needed but not always.
-pub enum MaybeOwned<'a> {
-    /// A borrowed string
-    Slice(&'a str),
-    /// An owned string
-    Owned(String)
-}
-
-/// `SendStr` is a specialization of `MaybeOwned` to be sendable
-pub type SendStr = MaybeOwned<'static>;
-
-impl<'a> MaybeOwned<'a> {
-    /// Returns `true` if this `MaybeOwned` wraps an owned string
-    #[inline]
-    pub fn is_owned(&self) -> bool {
-        match *self {
-            Slice(_) => false,
-            Owned(_) => true
-        }
-    }
-
-    /// Returns `true` if this `MaybeOwned` wraps a borrowed string
-    #[inline]
-    pub fn is_slice(&self) -> bool {
-        match *self {
-            Slice(_) => true,
-            Owned(_) => false
-        }
-    }
-}
-
-/// Trait for moving into a `MaybeOwned`
-pub trait IntoMaybeOwned<'a> {
-    /// Moves self into a `MaybeOwned`
-    fn into_maybe_owned(self) -> MaybeOwned<'a>;
-}
-
-impl<'a> IntoMaybeOwned<'a> for String {
-    #[inline]
-    fn into_maybe_owned(self) -> MaybeOwned<'a> {
-        Owned(self)
-    }
-}
-
-impl<'a> IntoMaybeOwned<'a> for &'a str {
-    #[inline]
-    fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) }
-}
-
-impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> {
-    #[inline]
-    fn into_maybe_owned(self) -> MaybeOwned<'a> { self }
-}
-
-impl<'a> PartialEq for MaybeOwned<'a> {
-    #[inline]
-    fn eq(&self, other: &MaybeOwned) -> bool {
-        self.as_slice() == other.as_slice()
-    }
-}
-
-impl<'a> Eq for MaybeOwned<'a> {}
-
-impl<'a> PartialOrd for MaybeOwned<'a> {
-    #[inline]
-    fn lt(&self, other: &MaybeOwned) -> bool {
-        self.as_slice().lt(&other.as_slice())
-    }
-}
-
-impl<'a> Ord for MaybeOwned<'a> {
-    #[inline]
-    fn cmp(&self, other: &MaybeOwned) -> Ordering {
-        self.as_slice().cmp(&other.as_slice())
-    }
-}
-
-impl<'a, S: Str> Equiv<S> for MaybeOwned<'a> {
-    #[inline]
-    fn equiv(&self, other: &S) -> bool {
-        self.as_slice() == other.as_slice()
-    }
-}
-
-impl<'a> Str for MaybeOwned<'a> {
-    #[inline]
-    fn as_slice<'b>(&'b self) -> &'b str {
-        match *self {
-            Slice(s) => s,
-            Owned(ref s) => s.as_slice()
-        }
-    }
-}
-
-impl<'a> StrAllocating for MaybeOwned<'a> {
-    #[inline]
-    fn into_string(self) -> String {
-        match self {
-            Slice(s) => s.to_string(),
-            Owned(s) => s
-        }
-    }
-}
-
-impl<'a> Container for MaybeOwned<'a> {
-    #[inline]
-    fn len(&self) -> uint { self.as_slice().len() }
-}
-
-impl<'a> Clone for MaybeOwned<'a> {
-    #[inline]
-    fn clone(&self) -> MaybeOwned<'a> {
-        match *self {
-            Slice(s) => Slice(s),
-            Owned(ref s) => Owned(s.to_string())
-        }
-    }
-}
-
-impl<'a> Default for MaybeOwned<'a> {
-    #[inline]
-    fn default() -> MaybeOwned<'a> { Slice("") }
-}
-
-impl<'a, H: Writer> ::hash::Hash<H> for MaybeOwned<'a> {
-    #[inline]
-    fn hash(&self, hasher: &mut H) {
-        match *self {
-            Slice(s) => s.hash(hasher),
-            Owned(ref s) => s.as_slice().hash(hasher),
-        }
-    }
-}
-
-impl<'a> fmt::Show for MaybeOwned<'a> {
-    #[inline]
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Slice(ref s) => s.fmt(f),
-            Owned(ref s) => s.fmt(f)
-        }
-    }
-}
-
-/// Unsafe operations
-pub mod raw {
-    use c_str::CString;
-    use libc;
-    use mem;
-    use raw::Slice;
-    use string::String;
-    use vec::Vec;
-
-    pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes};
-    pub use core::str::raw::{slice_unchecked};
-
-    /// Create a Rust string from a *u8 buffer of the given length
-    pub unsafe fn from_buf_len(buf: *u8, len: uint) -> String {
-        let mut result = String::new();
-        result.push_bytes(mem::transmute(Slice {
-            data: buf,
-            len: len,
-        }));
-        result
-    }
-
-    /// Create a Rust string from a null-terminated C string
-    pub unsafe fn from_c_str(c_string: *libc::c_char) -> String {
-        let mut buf = String::new();
-        buf.push_bytes(CString::new(c_string, false).as_bytes_no_nul());
-        buf
-    }
-
-    /// Converts an owned vector of bytes to a new owned string. This assumes
-    /// that the utf-8-ness of the vector has already been validated
-    #[inline]
-    pub unsafe fn from_utf8_owned(v: Vec<u8>) -> String {
-        mem::transmute(v)
-    }
-
-    /// Converts a byte to a string.
-    pub unsafe fn from_byte(u: u8) -> String {
-        from_utf8_owned(vec![u])
-    }
-
-    /// Sets the length of a string
-    ///
-    /// This will explicitly set the size of the string, without actually
-    /// modifying its buffers, so it is up to the caller to ensure that
-    /// the string is actually the specified size.
-    #[test]
-    fn test_from_buf_len() {
-        use slice::ImmutableVector;
-        use str::StrAllocating;
-
-        unsafe {
-            let a = ~[65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 65u8, 0u8];
-            let b = a.as_ptr();
-            let c = from_buf_len(b, 3u);
-            assert_eq!(c, "AAA".to_string());
-        }
-    }
-}
-
-/*
-Section: Trait implementations
-*/
-
-/// Any string that can be represented as a slice
-pub trait StrAllocating: Str {
-    /// Convert `self` into a `String`, not making a copy if possible.
-    fn into_string(self) -> String;
-
-    /// Convert `self` into a `String`.
-    #[inline]
-    fn to_string(&self) -> String {
-        String::from_str(self.as_slice())
-    }
-
-    #[allow(missing_doc)]
-    #[deprecated = "replaced by .into_string()"]
-    fn into_owned(self) -> String {
-        self.into_string()
-    }
-
-    /// Escape each char in `s` with `char::escape_default`.
-    fn escape_default(&self) -> String {
-        let me = self.as_slice();
-        let mut out = String::with_capacity(me.len());
-        for c in me.chars() {
-            c.escape_default(|c| out.push_char(c));
-        }
-        out
-    }
-
-    /// Escape each char in `s` with `char::escape_unicode`.
-    fn escape_unicode(&self) -> String {
-        let me = self.as_slice();
-        let mut out = String::with_capacity(me.len());
-        for c in me.chars() {
-            c.escape_unicode(|c| out.push_char(c));
-        }
-        out
-    }
-
-    /// Replace all occurrences of one string with another.
-    ///
-    /// # Arguments
-    ///
-    /// * `from` - The string to replace
-    /// * `to` - The replacement string
-    ///
-    /// # Return value
-    ///
-    /// The original string with all occurrences of `from` replaced with `to`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let s = "Do you know the muffin man,
-    /// The muffin man, the muffin man, ...".to_string();
-    ///
-    /// assert_eq!(s.replace("muffin man", "little lamb"),
-    ///            "Do you know the little lamb,
-    /// The little lamb, the little lamb, ...".to_string());
-    ///
-    /// // not found, so no change.
-    /// assert_eq!(s.replace("cookie monster", "little lamb"), s);
-    /// ```
-    fn replace(&self, from: &str, to: &str) -> String {
-        let me = self.as_slice();
-        let mut result = String::new();
-        let mut last_end = 0;
-        for (start, end) in me.match_indices(from) {
-            result.push_str(unsafe{raw::slice_bytes(me, last_end, start)});
-            result.push_str(to);
-            last_end = end;
-        }
-        result.push_str(unsafe{raw::slice_bytes(me, last_end, me.len())});
-        result
-    }
-
-    #[allow(missing_doc)]
-    #[deprecated = "obsolete, use `to_string`"]
-    #[inline]
-    fn to_owned(&self) -> String {
-        use slice::Vector;
-
-        unsafe {
-            ::mem::transmute(Vec::from_slice(self.as_slice().as_bytes()))
-        }
-    }
-
-    /// Converts to a vector of `u16` encoded as UTF-16.
-    fn to_utf16(&self) -> Vec<u16> {
-        let me = self.as_slice();
-        let mut u = Vec::new();
-        for ch in me.chars() {
-            let mut buf = [0u16, ..2];
-            let n = ch.encode_utf16(buf /* as mut slice! */);
-            u.push_all(buf.slice_to(n));
-        }
-        u
-    }
-
-    /// Given a string, make a new string with repeated copies of it.
-    fn repeat(&self, nn: uint) -> String {
-        let me = self.as_slice();
-        let mut ret = String::with_capacity(nn * me.len());
-        for _ in range(0, nn) {
-            ret.push_str(me);
-        }
-        ret
-    }
-
-    /// Levenshtein Distance between two strings.
-    fn lev_distance(&self, t: &str) -> uint {
-        let me = self.as_slice();
-        let slen = me.len();
-        let tlen = t.len();
-
-        if slen == 0 { return tlen; }
-        if tlen == 0 { return slen; }
-
-        let mut dcol = Vec::from_fn(tlen + 1, |x| x);
-
-        for (i, sc) in me.chars().enumerate() {
-
-            let mut current = i;
-            *dcol.get_mut(0) = current + 1;
-
-            for (j, tc) in t.chars().enumerate() {
-
-                let next = *dcol.get(j + 1);
-
-                if sc == tc {
-                    *dcol.get_mut(j + 1) = current;
-                } else {
-                    *dcol.get_mut(j + 1) = ::cmp::min(current, next);
-                    *dcol.get_mut(j + 1) = ::cmp::min(*dcol.get(j + 1),
-                                                      *dcol.get(j)) + 1;
-                }
-
-                current = next;
-            }
-        }
-
-        return *dcol.get(tlen);
-    }
-
-    /// An Iterator over the string in Unicode Normalization Form D
-    /// (canonical decomposition).
-    #[inline]
-    fn nfd_chars<'a>(&'a self) -> Decompositions<'a> {
-        Decompositions {
-            iter: self.as_slice().chars(),
-            buffer: Vec::new(),
-            sorted: false,
-            kind: Canonical
-        }
-    }
-
-    /// An Iterator over the string in Unicode Normalization Form KD
-    /// (compatibility decomposition).
-    #[inline]
-    fn nfkd_chars<'a>(&'a self) -> Decompositions<'a> {
-        Decompositions {
-            iter: self.as_slice().chars(),
-            buffer: Vec::new(),
-            sorted: false,
-            kind: Compatible
-        }
-    }
-}
-
-impl<'a> StrAllocating for &'a str {
-    #[inline]
-    fn into_string(self) -> String {
-        self.to_string()
-    }
-}
-
-/// Methods for owned strings
-pub trait OwnedStr {
-    /// Consumes the string, returning the underlying byte buffer.
-    ///
-    /// The buffer does not have a null terminator.
-    fn into_bytes(self) -> Vec<u8>;
-
-    /// Pushes the given string onto this string, returning the concatenation of the two strings.
-    fn append(self, rhs: &str) -> String;
-}
-
-impl OwnedStr for String {
-    #[inline]
-    fn into_bytes(self) -> Vec<u8> {
-        unsafe { mem::transmute(self) }
-    }
-
-    #[inline]
-    fn append(mut self, rhs: &str) -> String {
-        self.push_str(rhs);
-        self
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use iter::AdditiveIterator;
-    use default::Default;
-    use prelude::*;
-    use str::*;
-    use string::String;
-
-    #[test]
-    fn test_eq_slice() {
-        assert!((eq_slice("foobar".slice(0, 3), "foo")));
-        assert!((eq_slice("barfoo".slice(3, 6), "foo")));
-        assert!((!eq_slice("foo1", "foo2")));
-    }
-
-    #[test]
-    fn test_le() {
-        assert!("" <= "");
-        assert!("" <= "foo");
-        assert!("foo" <= "foo");
-        assert!("foo" != "bar");
-    }
-
-    #[test]
-    fn test_len() {
-        assert_eq!("".len(), 0u);
-        assert_eq!("hello world".len(), 11u);
-        assert_eq!("\x63".len(), 1u);
-        assert_eq!("\xa2".len(), 2u);
-        assert_eq!("\u03c0".len(), 2u);
-        assert_eq!("\u2620".len(), 3u);
-        assert_eq!("\U0001d11e".len(), 4u);
-
-        assert_eq!("".char_len(), 0u);
-        assert_eq!("hello world".char_len(), 11u);
-        assert_eq!("\x63".char_len(), 1u);
-        assert_eq!("\xa2".char_len(), 1u);
-        assert_eq!("\u03c0".char_len(), 1u);
-        assert_eq!("\u2620".char_len(), 1u);
-        assert_eq!("\U0001d11e".char_len(), 1u);
-        assert_eq!("ประเทศไทย中华Việt Nam".char_len(), 19u);
-    }
-
-    #[test]
-    fn test_find() {
-        assert_eq!("hello".find('l'), Some(2u));
-        assert_eq!("hello".find(|c:char| c == 'o'), Some(4u));
-        assert!("hello".find('x').is_none());
-        assert!("hello".find(|c:char| c == 'x').is_none());
-        assert_eq!("ประเทศไทย中华Việt Nam".find('华'), Some(30u));
-        assert_eq!("ประเทศไทย中华Việt Nam".find(|c: char| c == '华'), Some(30u));
-    }
-
-    #[test]
-    fn test_rfind() {
-        assert_eq!("hello".rfind('l'), Some(3u));
-        assert_eq!("hello".rfind(|c:char| c == 'o'), Some(4u));
-        assert!("hello".rfind('x').is_none());
-        assert!("hello".rfind(|c:char| c == 'x').is_none());
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind('华'), Some(30u));
-        assert_eq!("ประเทศไทย中华Việt Nam".rfind(|c: char| c == '华'), Some(30u));
-    }
-
-    #[test]
-    fn test_collect() {
-        let empty = "".to_string();
-        let s: String = empty.as_slice().chars().collect();
-        assert_eq!(empty, s);
-        let data = "ประเทศไทย中".to_string();
-        let s: String = data.as_slice().chars().collect();
-        assert_eq!(data, s);
-    }
-
-    #[test]
-    fn test_into_bytes() {
-        let data = "asdf".to_string();
-        let buf = data.into_bytes();
-        assert_eq!(bytes!("asdf"), buf.as_slice());
-    }
-
-    #[test]
-    fn test_find_str() {
-        // byte positions
-        assert_eq!("".find_str(""), Some(0u));
-        assert!("banana".find_str("apple pie").is_none());
-
-        let data = "abcabc";
-        assert_eq!(data.slice(0u, 6u).find_str("ab"), Some(0u));
-        assert_eq!(data.slice(2u, 6u).find_str("ab"), Some(3u - 2u));
-        assert!(data.slice(2u, 4u).find_str("ab").is_none());
-
-        let string = "ประเทศไทย中华Việt Nam";
-        let mut data = string.to_string();
-        data.push_str(string);
-        assert!(data.as_slice().find_str("ไท华").is_none());
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str(""), Some(0u));
-        assert_eq!(data.as_slice().slice(6u, 43u).find_str(""), Some(6u - 6u));
-
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ประ"), Some( 0u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ทศไ"), Some(12u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("ย中"), Some(24u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("iệt"), Some(34u));
-        assert_eq!(data.as_slice().slice(0u, 43u).find_str("Nam"), Some(40u));
-
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ประ"), Some(43u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ทศไ"), Some(55u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("ย中"), Some(67u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("iệt"), Some(77u - 43u));
-        assert_eq!(data.as_slice().slice(43u, 86u).find_str("Nam"), Some(83u - 43u));
-    }
-
-    #[test]
-    fn test_slice_chars() {
-        fn t(a: &str, b: &str, start: uint) {
-            assert_eq!(a.slice_chars(start, start + b.char_len()), b);
-        }
-        t("", "", 0);
-        t("hello", "llo", 2);
-        t("hello", "el", 1);
-        t("αβλ", "β", 1);
-        t("αβλ", "", 3);
-        assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8));
-    }
-
-    #[test]
-    fn test_concat() {
-        fn t(v: &[String], s: &str) {
-            assert_eq!(v.concat(), s.to_str().into_string());
-        }
-        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
-          "no".to_string(), "good".to_string()], "youknowI'mnogood");
-        let v: &[String] = [];
-        t(v, "");
-        t(["hi".to_string()], "hi");
-    }
-
-    #[test]
-    fn test_connect() {
-        fn t(v: &[String], sep: &str, s: &str) {
-            assert_eq!(v.connect(sep), s.to_str().into_string());
-        }
-        t(["you".to_string(), "know".to_string(), "I'm".to_string(),
-           "no".to_string(), "good".to_string()],
-          " ", "you know I'm no good");
-        let v: &[String] = [];
-        t(v, " ", "");
-        t(["hi".to_string()], " ", "hi");
-    }
-
-    #[test]
-    fn test_concat_slices() {
-        fn t(v: &[&str], s: &str) {
-            assert_eq!(v.concat(), s.to_str().into_string());
-        }
-        t(["you", "know", "I'm", "no", "good"], "youknowI'mnogood");
-        let v: &[&str] = [];
-        t(v, "");
-        t(["hi"], "hi");
-    }
-
-    #[test]
-    fn test_connect_slices() {
-        fn t(v: &[&str], sep: &str, s: &str) {
-            assert_eq!(v.connect(sep), s.to_str().into_string());
-        }
-        t(["you", "know", "I'm", "no", "good"],
-          " ", "you know I'm no good");
-        t([], " ", "");
-        t(["hi"], " ", "hi");
-    }
-
-    #[test]
-    fn test_repeat() {
-        assert_eq!("x".repeat(4), "xxxx".to_string());
-        assert_eq!("hi".repeat(4), "hihihihi".to_string());
-        assert_eq!("ไท华".repeat(3), "ไท华ไท华ไท华".to_string());
-        assert_eq!("".repeat(4), "".to_string());
-        assert_eq!("hi".repeat(0), "".to_string());
-    }
-
-    #[test]
-    fn test_unsafe_slice() {
-        assert_eq!("ab", unsafe {raw::slice_bytes("abc", 0, 2)});
-        assert_eq!("bc", unsafe {raw::slice_bytes("abc", 1, 3)});
-        assert_eq!("", unsafe {raw::slice_bytes("abc", 1, 1)});
-        fn a_million_letter_a() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("aaaaaaaaaa");
-                i += 1;
-            }
-            rs
-        }
-        fn half_a_million_letter_a() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("aaaaa");
-                i += 1;
-            }
-            rs
-        }
-        let letters = a_million_letter_a();
-        assert!(half_a_million_letter_a() ==
-            unsafe {raw::slice_bytes(letters.as_slice(),
-                                     0u,
-                                     500000)}.to_owned());
-    }
-
-    #[test]
-    fn test_starts_with() {
-        assert!(("".starts_with("")));
-        assert!(("abc".starts_with("")));
-        assert!(("abc".starts_with("a")));
-        assert!((!"a".starts_with("abc")));
-        assert!((!"".starts_with("abc")));
-        assert!((!"ödd".starts_with("-")));
-        assert!(("ödd".starts_with("öd")));
-    }
-
-    #[test]
-    fn test_ends_with() {
-        assert!(("".ends_with("")));
-        assert!(("abc".ends_with("")));
-        assert!(("abc".ends_with("c")));
-        assert!((!"a".ends_with("abc")));
-        assert!((!"".ends_with("abc")));
-        assert!((!"ddö".ends_with("-")));
-        assert!(("ddö".ends_with("dö")));
-    }
-
-    #[test]
-    fn test_is_empty() {
-        assert!("".is_empty());
-        assert!(!"a".is_empty());
-    }
-
-    #[test]
-    fn test_replace() {
-        let a = "a";
-        assert_eq!("".replace(a, "b"), "".to_string());
-        assert_eq!("a".replace(a, "b"), "b".to_string());
-        assert_eq!("ab".replace(a, "b"), "bb".to_string());
-        let test = "test";
-        assert!(" test test ".replace(test, "toast") ==
-            " toast toast ".to_string());
-        assert_eq!(" test test ".replace(test, ""), "   ".to_string());
-    }
-
-    #[test]
-    fn test_replace_2a() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let a = "ประเ";
-        let a2 = "دولة الكويتทศไทย中华";
-        assert_eq!(data.replace(a, repl).as_slice(), a2);
-    }
-
-    #[test]
-    fn test_replace_2b() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let b = "ะเ";
-        let b2 = "ปรدولة الكويتทศไทย中华";
-        assert_eq!(data.replace(b, repl).as_slice(), b2);
-    }
-
-    #[test]
-    fn test_replace_2c() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let c = "中华";
-        let c2 = "ประเทศไทยدولة الكويت";
-        assert_eq!(data.replace(c, repl).as_slice(), c2);
-    }
-
-    #[test]
-    fn test_replace_2d() {
-        let data = "ประเทศไทย中华";
-        let repl = "دولة الكويت";
-
-        let d = "ไท华";
-        assert_eq!(data.replace(d, repl).as_slice(), data);
-    }
-
-    #[test]
-    fn test_slice() {
-        assert_eq!("ab", "abc".slice(0, 2));
-        assert_eq!("bc", "abc".slice(1, 3));
-        assert_eq!("", "abc".slice(1, 1));
-        assert_eq!("\u65e5", "\u65e5\u672c".slice(0, 3));
-
-        let data = "ประเทศไทย中华";
-        assert_eq!("ป", data.slice(0, 3));
-        assert_eq!("ร", data.slice(3, 6));
-        assert_eq!("", data.slice(3, 3));
-        assert_eq!("华", data.slice(30, 33));
-
-        fn a_million_letter_X() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("华华华华华华华华华华");
-                i += 1;
-            }
-            rs
-        }
-        fn half_a_million_letter_X() -> String {
-            let mut i = 0;
-            let mut rs = String::new();
-            while i < 100000 {
-                rs.push_str("华华华华华");
-                i += 1;
-            }
-            rs
-        }
-        let letters = a_million_letter_X();
-        assert!(half_a_million_letter_X() ==
-            letters.as_slice().slice(0u, 3u * 500000u).to_owned());
-    }
-
-    #[test]
-    fn test_slice_2() {
-        let ss = "中华Việt Nam";
-
-        assert_eq!("华", ss.slice(3u, 6u));
-        assert_eq!("Việt Nam", ss.slice(6u, 16u));
-
-        assert_eq!("ab", "abc".slice(0u, 2u));
-        assert_eq!("bc", "abc".slice(1u, 3u));
-        assert_eq!("", "abc".slice(1u, 1u));
-
-        assert_eq!("中", ss.slice(0u, 3u));
-        assert_eq!("华V", ss.slice(3u, 7u));
-        assert_eq!("", ss.slice(3u, 3u));
-        /*0: 中
-          3: 华
-          6: V
-          7: i
-          8: ệ
-         11: t
-         12:
-         13: N
-         14: a
-         15: m */
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_slice_fail() {
-        "中华Việt Nam".slice(0u, 2u);
-    }
-
-    #[test]
-    fn test_slice_from() {
-        assert_eq!("abcd".slice_from(0), "abcd");
-        assert_eq!("abcd".slice_from(2), "cd");
-        assert_eq!("abcd".slice_from(4), "");
-    }
-    #[test]
-    fn test_slice_to() {
-        assert_eq!("abcd".slice_to(0), "");
-        assert_eq!("abcd".slice_to(2), "ab");
-        assert_eq!("abcd".slice_to(4), "abcd");
-    }
-
-    #[test]
-    fn test_trim_left_chars() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_left_chars(v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
-        assert_eq!(" ***  *** ".trim_left_chars(&['*', ' ']), "");
-        assert_eq!("foo *** ".trim_left_chars(&['*', ' ']), "foo *** ");
-
-        assert_eq!("11foo1bar11".trim_left_chars('1'), "foo1bar11");
-        assert_eq!("12foo1bar12".trim_left_chars(&['1', '2']), "foo1bar12");
-        assert_eq!("123foo1bar123".trim_left_chars(|c: char| c.is_digit()), "foo1bar123");
-    }
-
-    #[test]
-    fn test_trim_right_chars() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_right_chars(v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_right_chars(&['*', ' ']), " *** foo");
-        assert_eq!(" ***  *** ".trim_right_chars(&['*', ' ']), "");
-        assert_eq!(" *** foo".trim_right_chars(&['*', ' ']), " *** foo");
-
-        assert_eq!("11foo1bar11".trim_right_chars('1'), "11foo1bar");
-        assert_eq!("12foo1bar12".trim_right_chars(&['1', '2']), "12foo1bar");
-        assert_eq!("123foo1bar123".trim_right_chars(|c: char| c.is_digit()), "123foo1bar");
-    }
-
-    #[test]
-    fn test_trim_chars() {
-        let v: &[char] = &[];
-        assert_eq!(" *** foo *** ".trim_chars(v), " *** foo *** ");
-        assert_eq!(" *** foo *** ".trim_chars(&['*', ' ']), "foo");
-        assert_eq!(" ***  *** ".trim_chars(&['*', ' ']), "");
-        assert_eq!("foo".trim_chars(&['*', ' ']), "foo");
-
-        assert_eq!("11foo1bar11".trim_chars('1'), "foo1bar");
-        assert_eq!("12foo1bar12".trim_chars(&['1', '2']), "foo1bar");
-        assert_eq!("123foo1bar123".trim_chars(|c: char| c.is_digit()), "foo1bar");
-    }
-
-    #[test]
-    fn test_trim_left() {
-        assert_eq!("".trim_left(), "");
-        assert_eq!("a".trim_left(), "a");
-        assert_eq!("    ".trim_left(), "");
-        assert_eq!("     blah".trim_left(), "blah");
-        assert_eq!("   \u3000  wut".trim_left(), "wut");
-        assert_eq!("hey ".trim_left(), "hey ");
-    }
-
-    #[test]
-    fn test_trim_right() {
-        assert_eq!("".trim_right(), "");
-        assert_eq!("a".trim_right(), "a");
-        assert_eq!("    ".trim_right(), "");
-        assert_eq!("blah     ".trim_right(), "blah");
-        assert_eq!("wut   \u3000  ".trim_right(), "wut");
-        assert_eq!(" hey".trim_right(), " hey");
-    }
-
-    #[test]
-    fn test_trim() {
-        assert_eq!("".trim(), "");
-        assert_eq!("a".trim(), "a");
-        assert_eq!("    ".trim(), "");
-        assert_eq!("    blah     ".trim(), "blah");
-        assert_eq!("\nwut   \u3000  ".trim(), "wut");
-        assert_eq!(" hey dude ".trim(), "hey dude");
-    }
-
-    #[test]
-    fn test_is_whitespace() {
-        assert!("".is_whitespace());
-        assert!(" ".is_whitespace());
-        assert!("\u2009".is_whitespace()); // Thin space
-        assert!("  \n\t   ".is_whitespace());
-        assert!(!"   _   ".is_whitespace());
-    }
-
-    #[test]
-    fn test_slice_shift_char() {
-        let data = "ประเทศไทย中";
-        assert_eq!(data.slice_shift_char(), (Some('ป'), "ระเทศไทย中"));
-    }
-
-    #[test]
-    fn test_slice_shift_char_2() {
-        let empty = "";
-        assert_eq!(empty.slice_shift_char(), (None, ""));
-    }
-
-    #[test]
-    fn test_is_utf8() {
-        // deny overlong encodings
-        assert!(!is_utf8([0xc0, 0x80]));
-        assert!(!is_utf8([0xc0, 0xae]));
-        assert!(!is_utf8([0xe0, 0x80, 0x80]));
-        assert!(!is_utf8([0xe0, 0x80, 0xaf]));
-        assert!(!is_utf8([0xe0, 0x81, 0x81]));
-        assert!(!is_utf8([0xf0, 0x82, 0x82, 0xac]));
-        assert!(!is_utf8([0xf4, 0x90, 0x80, 0x80]));
-
-        // deny surrogates
-        assert!(!is_utf8([0xED, 0xA0, 0x80]));
-        assert!(!is_utf8([0xED, 0xBF, 0xBF]));
-
-        assert!(is_utf8([0xC2, 0x80]));
-        assert!(is_utf8([0xDF, 0xBF]));
-        assert!(is_utf8([0xE0, 0xA0, 0x80]));
-        assert!(is_utf8([0xED, 0x9F, 0xBF]));
-        assert!(is_utf8([0xEE, 0x80, 0x80]));
-        assert!(is_utf8([0xEF, 0xBF, 0xBF]));
-        assert!(is_utf8([0xF0, 0x90, 0x80, 0x80]));
-        assert!(is_utf8([0xF4, 0x8F, 0xBF, 0xBF]));
-    }
-
-    #[test]
-    fn test_is_utf16() {
-        macro_rules! pos ( ($($e:expr),*) => { { $(assert!(is_utf16($e));)* } });
-
-        // non-surrogates
-        pos!([0x0000],
-             [0x0001, 0x0002],
-             [0xD7FF],
-             [0xE000]);
-
-        // surrogate pairs (randomly generated with Python 3's
-        // .encode('utf-16be'))
-        pos!([0xdb54, 0xdf16, 0xd880, 0xdee0, 0xdb6a, 0xdd45],
-             [0xd91f, 0xdeb1, 0xdb31, 0xdd84, 0xd8e2, 0xde14],
-             [0xdb9f, 0xdc26, 0xdb6f, 0xde58, 0xd850, 0xdfae]);
-
-        // mixtures (also random)
-        pos!([0xd921, 0xdcc2, 0x002d, 0x004d, 0xdb32, 0xdf65],
-             [0xdb45, 0xdd2d, 0x006a, 0xdacd, 0xddfe, 0x0006],
-             [0x0067, 0xd8ff, 0xddb7, 0x000f, 0xd900, 0xdc80]);
-
-        // negative tests
-        macro_rules! neg ( ($($e:expr),*) => { { $(assert!(!is_utf16($e));)* } });
-
-        neg!(
-            // surrogate + regular unit
-            [0xdb45, 0x0000],
-            // surrogate + lead surrogate
-            [0xd900, 0xd900],
-            // unterminated surrogate
-            [0xd8ff],
-            // trail surrogate without a lead
-            [0xddb7]);
-
-        // random byte sequences that Python 3's .decode('utf-16be')
-        // failed on
-        neg!([0x5b3d, 0x0141, 0xde9e, 0x8fdc, 0xc6e7],
-             [0xdf5a, 0x82a5, 0x62b9, 0xb447, 0x92f3],
-             [0xda4e, 0x42bc, 0x4462, 0xee98, 0xc2ca],
-             [0xbe00, 0xb04a, 0x6ecb, 0xdd89, 0xe278],
-             [0x0465, 0xab56, 0xdbb6, 0xa893, 0x665e],
-             [0x6b7f, 0x0a19, 0x40f4, 0xa657, 0xdcc5],
-             [0x9b50, 0xda5e, 0x24ec, 0x03ad, 0x6dee],
-             [0x8d17, 0xcaa7, 0xf4ae, 0xdf6e, 0xbed7],
-             [0xdaee, 0x2584, 0x7d30, 0xa626, 0x121a],
-             [0xd956, 0x4b43, 0x7570, 0xccd6, 0x4f4a],
-             [0x9dcf, 0x1b49, 0x4ba5, 0xfce9, 0xdffe],
-             [0x6572, 0xce53, 0xb05a, 0xf6af, 0xdacf],
-             [0x1b90, 0x728c, 0x9906, 0xdb68, 0xf46e],
-             [0x1606, 0xbeca, 0xbe76, 0x860f, 0xdfa5],
-             [0x8b4f, 0xde7a, 0xd220, 0x9fac, 0x2b6f],
-             [0xb8fe, 0xebbe, 0xda32, 0x1a5f, 0x8b8b],
-             [0x934b, 0x8956, 0xc434, 0x1881, 0xddf7],
-             [0x5a95, 0x13fc, 0xf116, 0xd89b, 0x93f9],
-             [0xd640, 0x71f1, 0xdd7d, 0x77eb, 0x1cd8],
-             [0x348b, 0xaef0, 0xdb2c, 0xebf1, 0x1282],
-             [0x50d7, 0xd824, 0x5010, 0xb369, 0x22ea]);
-    }
-
-    #[test]
-    fn test_raw_from_c_str() {
-        unsafe {
-            let a = box [65, 65, 65, 65, 65, 65, 65, 0];
-            let b = a.as_ptr();
-            let c = raw::from_c_str(b);
-            assert_eq!(c, "AAAAAAA".to_string());
-        }
-    }
-
-    #[test]
-    fn test_as_bytes() {
-        // no null
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        assert_eq!("".as_bytes(), &[]);
-        assert_eq!("abc".as_bytes(), &['a' as u8, 'b' as u8, 'c' as u8]);
-        assert_eq!("ศไทย中华Việt Nam".as_bytes(), v.as_slice());
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_as_bytes_fail() {
-        // Don't double free. (I'm not sure if this exercises the
-        // original problem code path anymore.)
-        let s = "".to_string();
-        let _bytes = s.as_bytes();
-        fail!();
-    }
-
-    #[test]
-    fn test_as_ptr() {
-        let buf = "hello".as_ptr();
-        unsafe {
-            assert_eq!(*buf.offset(0), 'h' as u8);
-            assert_eq!(*buf.offset(1), 'e' as u8);
-            assert_eq!(*buf.offset(2), 'l' as u8);
-            assert_eq!(*buf.offset(3), 'l' as u8);
-            assert_eq!(*buf.offset(4), 'o' as u8);
-        }
-    }
-
-    #[test]
-    fn test_subslice_offset() {
-        let a = "kernelsprite";
-        let b = a.slice(7, a.len());
-        let c = a.slice(0, a.len() - 6);
-        assert_eq!(a.subslice_offset(b), 7);
-        assert_eq!(a.subslice_offset(c), 0);
-
-        let string = "a\nb\nc";
-        let lines: Vec<&str> = string.lines().collect();
-        let lines = lines.as_slice();
-        assert_eq!(string.subslice_offset(lines[0]), 0);
-        assert_eq!(string.subslice_offset(lines[1]), 2);
-        assert_eq!(string.subslice_offset(lines[2]), 4);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_subslice_offset_2() {
-        let a = "alchemiter";
-        let b = "cruxtruder";
-        a.subslice_offset(b);
-    }
-
-    #[test]
-    fn vec_str_conversions() {
-        let s1: String = "All mimsy were the borogoves".to_string();
-
-        let v: Vec<u8> = Vec::from_slice(s1.as_bytes());
-        let s2: String = from_utf8(v.as_slice()).unwrap().to_string();
-        let mut i: uint = 0u;
-        let n1: uint = s1.len();
-        let n2: uint = v.len();
-        assert_eq!(n1, n2);
-        while i < n1 {
-            let a: u8 = s1.as_slice()[i];
-            let b: u8 = s2.as_slice()[i];
-            debug!("{}", a);
-            debug!("{}", b);
-            assert_eq!(a, b);
-            i += 1u;
-        }
-    }
-
-    #[test]
-    fn test_contains() {
-        assert!("abcde".contains("bcd"));
-        assert!("abcde".contains("abcd"));
-        assert!("abcde".contains("bcde"));
-        assert!("abcde".contains(""));
-        assert!("".contains(""));
-        assert!(!"abcde".contains("def"));
-        assert!(!"".contains("a"));
-
-        let data = "ประเทศไทย中华Việt Nam";
-        assert!(data.contains("ประเ"));
-        assert!(data.contains("ะเ"));
-        assert!(data.contains("中华"));
-        assert!(!data.contains("ไท华"));
-    }
-
-    #[test]
-    fn test_contains_char() {
-        assert!("abc".contains_char('b'));
-        assert!("a".contains_char('a'));
-        assert!(!"abc".contains_char('d'));
-        assert!(!"".contains_char('a'));
-    }
-
-    #[test]
-    fn test_utf16() {
-        let pairs =
-            [("𐍅𐌿𐌻𐍆𐌹𐌻𐌰\n".to_string(),
-              vec![0xd800_u16, 0xdf45_u16, 0xd800_u16, 0xdf3f_u16,
-                0xd800_u16, 0xdf3b_u16, 0xd800_u16, 0xdf46_u16,
-                0xd800_u16, 0xdf39_u16, 0xd800_u16, 0xdf3b_u16,
-                0xd800_u16, 0xdf30_u16, 0x000a_u16]),
-
-             ("𐐒𐑉𐐮𐑀𐐲𐑋 𐐏𐐲𐑍\n".to_string(),
-              vec![0xd801_u16, 0xdc12_u16, 0xd801_u16,
-                0xdc49_u16, 0xd801_u16, 0xdc2e_u16, 0xd801_u16,
-                0xdc40_u16, 0xd801_u16, 0xdc32_u16, 0xd801_u16,
-                0xdc4b_u16, 0x0020_u16, 0xd801_u16, 0xdc0f_u16,
-                0xd801_u16, 0xdc32_u16, 0xd801_u16, 0xdc4d_u16,
-                0x000a_u16]),
-
-             ("𐌀𐌖𐌋𐌄𐌑𐌉·𐌌𐌄𐌕𐌄𐌋𐌉𐌑\n".to_string(),
-              vec![0xd800_u16, 0xdf00_u16, 0xd800_u16, 0xdf16_u16,
-                0xd800_u16, 0xdf0b_u16, 0xd800_u16, 0xdf04_u16,
-                0xd800_u16, 0xdf11_u16, 0xd800_u16, 0xdf09_u16,
-                0x00b7_u16, 0xd800_u16, 0xdf0c_u16, 0xd800_u16,
-                0xdf04_u16, 0xd800_u16, 0xdf15_u16, 0xd800_u16,
-                0xdf04_u16, 0xd800_u16, 0xdf0b_u16, 0xd800_u16,
-                0xdf09_u16, 0xd800_u16, 0xdf11_u16, 0x000a_u16 ]),
-
-             ("𐒋𐒘𐒈𐒑𐒛𐒒 𐒕𐒓 𐒈𐒚𐒍 𐒏𐒜𐒒𐒖𐒆 𐒕𐒆\n".to_string(),
-              vec![0xd801_u16, 0xdc8b_u16, 0xd801_u16, 0xdc98_u16,
-                0xd801_u16, 0xdc88_u16, 0xd801_u16, 0xdc91_u16,
-                0xd801_u16, 0xdc9b_u16, 0xd801_u16, 0xdc92_u16,
-                0x0020_u16, 0xd801_u16, 0xdc95_u16, 0xd801_u16,
-                0xdc93_u16, 0x0020_u16, 0xd801_u16, 0xdc88_u16,
-                0xd801_u16, 0xdc9a_u16, 0xd801_u16, 0xdc8d_u16,
-                0x0020_u16, 0xd801_u16, 0xdc8f_u16, 0xd801_u16,
-                0xdc9c_u16, 0xd801_u16, 0xdc92_u16, 0xd801_u16,
-                0xdc96_u16, 0xd801_u16, 0xdc86_u16, 0x0020_u16,
-                0xd801_u16, 0xdc95_u16, 0xd801_u16, 0xdc86_u16,
-                0x000a_u16 ]),
-             // Issue #12318, even-numbered non-BMP planes
-             ("\U00020000".to_string(),
-              vec![0xD840, 0xDC00])];
-
-        for p in pairs.iter() {
-            let (s, u) = (*p).clone();
-            assert!(is_utf16(u.as_slice()));
-            assert_eq!(s.to_utf16(), u);
-
-            assert_eq!(from_utf16(u.as_slice()).unwrap(), s);
-            assert_eq!(from_utf16_lossy(u.as_slice()), s);
-
-            assert_eq!(from_utf16(s.to_utf16().as_slice()).unwrap(), s);
-            assert_eq!(from_utf16(u.as_slice()).unwrap().to_utf16(), u);
-        }
-    }
-
-    #[test]
-    fn test_utf16_invalid() {
-        // completely positive cases tested above.
-        // lead + eof
-        assert_eq!(from_utf16([0xD800]), None);
-        // lead + lead
-        assert_eq!(from_utf16([0xD800, 0xD800]), None);
-
-        // isolated trail
-        assert_eq!(from_utf16([0x0061, 0xDC00]), None);
-
-        // general
-        assert_eq!(from_utf16([0xD800, 0xd801, 0xdc8b, 0xD800]), None);
-    }
-
-    #[test]
-    fn test_utf16_lossy() {
-        // completely positive cases tested above.
-        // lead + eof
-        assert_eq!(from_utf16_lossy([0xD800]), "\uFFFD".to_string());
-        // lead + lead
-        assert_eq!(from_utf16_lossy([0xD800, 0xD800]), "\uFFFD\uFFFD".to_string());
-
-        // isolated trail
-        assert_eq!(from_utf16_lossy([0x0061, 0xDC00]), "a\uFFFD".to_string());
-
-        // general
-        assert_eq!(from_utf16_lossy([0xD800, 0xd801, 0xdc8b, 0xD800]),
-                   "\uFFFD𐒋\uFFFD".to_string());
-    }
-
-    #[test]
-    fn test_truncate_utf16_at_nul() {
-        let v = [];
-        assert_eq!(truncate_utf16_at_nul(v), &[]);
-
-        let v = [0, 2, 3];
-        assert_eq!(truncate_utf16_at_nul(v), &[]);
-
-        let v = [1, 0, 3];
-        assert_eq!(truncate_utf16_at_nul(v), &[1]);
-
-        let v = [1, 2, 0];
-        assert_eq!(truncate_utf16_at_nul(v), &[1, 2]);
-
-        let v = [1, 2, 3];
-        assert_eq!(truncate_utf16_at_nul(v), &[1, 2, 3]);
-    }
-
-    #[test]
-    fn test_char_at() {
-        let s = "ศไทย中华Việt Nam";
-        let v = box ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = 0;
-        for ch in v.iter() {
-            assert!(s.char_at(pos) == *ch);
-            pos += from_char(*ch).len();
-        }
-    }
-
-    #[test]
-    fn test_char_at_reverse() {
-        let s = "ศไทย中华Việt Nam";
-        let v = box ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-        let mut pos = s.len();
-        for ch in v.iter().rev() {
-            assert!(s.char_at_reverse(pos) == *ch);
-            pos -= from_char(*ch).len();
-        }
-    }
-
-    #[test]
-    fn test_escape_unicode() {
-        assert_eq!("abc".escape_unicode(), "\\x61\\x62\\x63".to_string());
-        assert_eq!("a c".escape_unicode(), "\\x61\\x20\\x63".to_string());
-        assert_eq!("\r\n\t".escape_unicode(), "\\x0d\\x0a\\x09".to_string());
-        assert_eq!("'\"\\".escape_unicode(), "\\x27\\x22\\x5c".to_string());
-        assert_eq!("\x00\x01\xfe\xff".escape_unicode(), "\\x00\\x01\\xfe\\xff".to_string());
-        assert_eq!("\u0100\uffff".escape_unicode(), "\\u0100\\uffff".to_string());
-        assert_eq!("\U00010000\U0010ffff".escape_unicode(), "\\U00010000\\U0010ffff".to_string());
-        assert_eq!("ab\ufb00".escape_unicode(), "\\x61\\x62\\ufb00".to_string());
-        assert_eq!("\U0001d4ea\r".escape_unicode(), "\\U0001d4ea\\x0d".to_string());
-    }
-
-    #[test]
-    fn test_escape_default() {
-        assert_eq!("abc".escape_default(), "abc".to_string());
-        assert_eq!("a c".escape_default(), "a c".to_string());
-        assert_eq!("\r\n\t".escape_default(), "\\r\\n\\t".to_string());
-        assert_eq!("'\"\\".escape_default(), "\\'\\\"\\\\".to_string());
-        assert_eq!("\u0100\uffff".escape_default(), "\\u0100\\uffff".to_string());
-        assert_eq!("\U00010000\U0010ffff".escape_default(), "\\U00010000\\U0010ffff".to_string());
-        assert_eq!("ab\ufb00".escape_default(), "ab\\ufb00".to_string());
-        assert_eq!("\U0001d4ea\r".escape_default(), "\\U0001d4ea\\r".to_string());
-    }
-
-    #[test]
-    fn test_total_ord() {
-        "1234".cmp(&("123")) == Greater;
-        "123".cmp(&("1234")) == Less;
-        "1234".cmp(&("1234")) == Equal;
-        "12345555".cmp(&("123456")) == Less;
-        "22".cmp(&("1234")) == Greater;
-    }
-
-    #[test]
-    fn test_char_range_at() {
-        let data = "b¢€𤭢𤭢€¢b";
-        assert_eq!('b', data.char_range_at(0).ch);
-        assert_eq!('¢', data.char_range_at(1).ch);
-        assert_eq!('€', data.char_range_at(3).ch);
-        assert_eq!('𤭢', data.char_range_at(6).ch);
-        assert_eq!('𤭢', data.char_range_at(10).ch);
-        assert_eq!('€', data.char_range_at(14).ch);
-        assert_eq!('¢', data.char_range_at(17).ch);
-        assert_eq!('b', data.char_range_at(19).ch);
-    }
-
-    #[test]
-    fn test_char_range_at_reverse_underflow() {
-        assert_eq!("abc".char_range_at_reverse(0).next, 0);
-    }
-
-    #[test]
-    fn test_iterator() {
-        use iter::*;
-        let s = "ศไทย中华Việt Nam";
-        let v = box ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
-        let mut pos = 0;
-        let mut it = s.chars();
-
-        for c in it {
-            assert_eq!(c, v[pos]);
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-    }
-
-    #[test]
-    fn test_rev_iterator() {
-        use iter::*;
-        let s = "ศไทย中华Việt Nam";
-        let v = box ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
-        let mut pos = 0;
-        let mut it = s.chars().rev();
-
-        for c in it {
-            assert_eq!(c, v[pos]);
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-    }
-
-    #[test]
-    fn test_iterator_clone() {
-        let s = "ศไทย中华Việt Nam";
-        let mut it = s.chars();
-        it.next();
-        assert!(it.zip(it.clone()).all(|(x,y)| x == y));
-    }
-
-    #[test]
-    fn test_bytesator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = 0;
-
-        for b in s.bytes() {
-            assert_eq!(b, v[pos]);
-            pos += 1;
-        }
-    }
-
-    #[test]
-    fn test_bytes_revator() {
-        let s = "ศไทย中华Việt Nam";
-        let v = [
-            224, 184, 168, 224, 185, 132, 224, 184, 151, 224, 184, 162, 228,
-            184, 173, 229, 141, 142, 86, 105, 225, 187, 135, 116, 32, 78, 97,
-            109
-        ];
-        let mut pos = v.len();
-
-        for b in s.bytes().rev() {
-            pos -= 1;
-            assert_eq!(b, v[pos]);
-        }
-    }
-
-    #[test]
-    fn test_char_indicesator() {
-        use iter::*;
-        let s = "ศไทย中华Việt Nam";
-        let p = [0, 3, 6, 9, 12, 15, 18, 19, 20, 23, 24, 25, 26, 27];
-        let v = ['ศ','ไ','ท','ย','中','华','V','i','ệ','t',' ','N','a','m'];
-
-        let mut pos = 0;
-        let mut it = s.char_indices();
-
-        for c in it {
-            assert_eq!(c, (p[pos], v[pos]));
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-        assert_eq!(pos, p.len());
-    }
-
-    #[test]
-    fn test_char_indices_revator() {
-        use iter::*;
-        let s = "ศไทย中华Việt Nam";
-        let p = [27, 26, 25, 24, 23, 20, 19, 18, 15, 12, 9, 6, 3, 0];
-        let v = ['m', 'a', 'N', ' ', 't', 'ệ','i','V','华','中','ย','ท','ไ','ศ'];
-
-        let mut pos = 0;
-        let mut it = s.char_indices().rev();
-
-        for c in it {
-            assert_eq!(c, (p[pos], v[pos]));
-            pos += 1;
-        }
-        assert_eq!(pos, v.len());
-        assert_eq!(pos, p.len());
-    }
-
-    #[test]
-    fn test_split_char_iterator() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.split(' ').collect();
-        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-        let mut rsplit: Vec<&str> = data.split(' ').rev().collect();
-        rsplit.reverse();
-        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-        let split: Vec<&str> = data.split(|c: char| c == ' ').collect();
-        assert_eq!( split, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-        let mut rsplit: Vec<&str> = data.split(|c: char| c == ' ').rev().collect();
-        rsplit.reverse();
-        assert_eq!(rsplit, vec!["\nMäry", "häd", "ä", "little", "lämb\nLittle", "lämb\n"]);
-
-        // Unicode
-        let split: Vec<&str> = data.split('ä').collect();
-        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
-        let mut rsplit: Vec<&str> = data.split('ä').rev().collect();
-        rsplit.reverse();
-        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
-        let split: Vec<&str> = data.split(|c: char| c == 'ä').collect();
-        assert_eq!( split, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-
-        let mut rsplit: Vec<&str> = data.split(|c: char| c == 'ä').rev().collect();
-        rsplit.reverse();
-        assert_eq!(rsplit, vec!["\nM", "ry h", "d ", " little l", "mb\nLittle l", "mb\n"]);
-    }
-
-    #[test]
-    fn test_splitn_char_iterator() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.splitn(' ', 3).collect();
-        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-        let split: Vec<&str> = data.splitn(|c: char| c == ' ', 3).collect();
-        assert_eq!(split, vec!["\nMäry", "häd", "ä", "little lämb\nLittle lämb\n"]);
-
-        // Unicode
-        let split: Vec<&str> = data.splitn('ä', 3).collect();
-        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-
-        let split: Vec<&str> = data.splitn(|c: char| c == 'ä', 3).collect();
-        assert_eq!(split, vec!["\nM", "ry h", "d ", " little lämb\nLittle lämb\n"]);
-    }
-
-    #[test]
-    fn test_rsplitn_char_iterator() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let mut split: Vec<&str> = data.rsplitn(' ', 3).collect();
-        split.reverse();
-        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
-
-        let mut split: Vec<&str> = data.rsplitn(|c: char| c == ' ', 3).collect();
-        split.reverse();
-        assert_eq!(split, vec!["\nMäry häd ä", "little", "lämb\nLittle", "lämb\n"]);
-
-        // Unicode
-        let mut split: Vec<&str> = data.rsplitn('ä', 3).collect();
-        split.reverse();
-        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
-
-        let mut split: Vec<&str> = data.rsplitn(|c: char| c == 'ä', 3).collect();
-        split.reverse();
-        assert_eq!(split, vec!["\nMäry häd ", " little l", "mb\nLittle l", "mb\n"]);
-    }
-
-    #[test]
-    fn test_split_char_iterator_no_trailing() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let split: Vec<&str> = data.split('\n').collect();
-        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
-
-        let split: Vec<&str> = data.split_terminator('\n').collect();
-        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
-    }
-
-    #[test]
-    fn test_rev_split_char_iterator_no_trailing() {
-        let data = "\nMäry häd ä little lämb\nLittle lämb\n";
-
-        let mut split: Vec<&str> = data.split('\n').rev().collect();
-        split.reverse();
-        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb", ""]);
-
-        let mut split: Vec<&str> = data.split_terminator('\n').rev().collect();
-        split.reverse();
-        assert_eq!(split, vec!["", "Märy häd ä little lämb", "Little lämb"]);
-    }
-
-    #[test]
-    fn test_words() {
-        let data = "\n \tMäry   häd\tä  little lämb\nLittle lämb\n";
-        let words: Vec<&str> = data.words().collect();
-        assert_eq!(words, vec!["Märy", "häd", "ä", "little", "lämb", "Little", "lämb"])
-    }
-
-    #[test]
-    fn test_nfd_chars() {
-        assert_eq!("abc".nfd_chars().collect::<String>(), "abc".to_string());
-        assert_eq!("\u1e0b\u01c4".nfd_chars().collect::<String>(), "d\u0307\u01c4".to_string());
-        assert_eq!("\u2026".nfd_chars().collect::<String>(), "\u2026".to_string());
-        assert_eq!("\u2126".nfd_chars().collect::<String>(), "\u03a9".to_string());
-        assert_eq!("\u1e0b\u0323".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("\u1e0d\u0307".nfd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("a\u0301".nfd_chars().collect::<String>(), "a\u0301".to_string());
-        assert_eq!("\u0301a".nfd_chars().collect::<String>(), "\u0301a".to_string());
-        assert_eq!("\ud4db".nfd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
-        assert_eq!("\uac1c".nfd_chars().collect::<String>(), "\u1100\u1162".to_string());
-    }
-
-    #[test]
-    fn test_nfkd_chars() {
-        assert_eq!("abc".nfkd_chars().collect::<String>(), "abc".to_string());
-        assert_eq!("\u1e0b\u01c4".nfkd_chars().collect::<String>(), "d\u0307DZ\u030c".to_string());
-        assert_eq!("\u2026".nfkd_chars().collect::<String>(), "...".to_string());
-        assert_eq!("\u2126".nfkd_chars().collect::<String>(), "\u03a9".to_string());
-        assert_eq!("\u1e0b\u0323".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("\u1e0d\u0307".nfkd_chars().collect::<String>(), "d\u0323\u0307".to_string());
-        assert_eq!("a\u0301".nfkd_chars().collect::<String>(), "a\u0301".to_string());
-        assert_eq!("\u0301a".nfkd_chars().collect::<String>(), "\u0301a".to_string());
-        assert_eq!("\ud4db".nfkd_chars().collect::<String>(), "\u1111\u1171\u11b6".to_string());
-        assert_eq!("\uac1c".nfkd_chars().collect::<String>(), "\u1100\u1162".to_string());
-    }
-
-    #[test]
-    fn test_lines() {
-        let data = "\nMäry häd ä little lämb\n\nLittle lämb\n";
-        let lines: Vec<&str> = data.lines().collect();
-        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
-
-        let data = "\nMäry häd ä little lämb\n\nLittle lämb"; // no trailing \n
-        let lines: Vec<&str> = data.lines().collect();
-        assert_eq!(lines, vec!["", "Märy häd ä little lämb", "", "Little lämb"]);
-    }
-
-    #[test]
-    fn test_split_strator() {
-        fn t(s: &str, sep: &str, u: &[&str]) {
-            let v: Vec<&str> = s.split_str(sep).collect();
-            assert_eq!(v.as_slice(), u.as_slice());
-        }
-        t("--1233345--", "12345", ["--1233345--"]);
-        t("abc::hello::there", "::", ["abc", "hello", "there"]);
-        t("::hello::there", "::", ["", "hello", "there"]);
-        t("hello::there::", "::", ["hello", "there", ""]);
-        t("::hello::there::", "::", ["", "hello", "there", ""]);
-        t("ประเทศไทย中华Việt Nam", "中华", ["ประเทศไทย", "Việt Nam"]);
-        t("zzXXXzzYYYzz", "zz", ["", "XXX", "YYY", ""]);
-        t("zzXXXzYYYz", "XXX", ["zz", "zYYYz"]);
-        t(".XXX.YYY.", ".", ["", "XXX", "YYY", ""]);
-        t("", ".", [""]);
-        t("zz", "zz", ["",""]);
-        t("ok", "z", ["ok"]);
-        t("zzz", "zz", ["","z"]);
-        t("zzzzz", "zz", ["","","z"]);
-    }
-
-    #[test]
-    fn test_str_default() {
-        use default::Default;
-        fn t<S: Default + Str>() {
-            let s: S = Default::default();
-            assert_eq!(s.as_slice(), "");
-        }
-
-        t::<&str>();
-        t::<String>();
-    }
-
-    #[test]
-    fn test_str_container() {
-        fn sum_len<S: Container>(v: &[S]) -> uint {
-            v.iter().map(|x| x.len()).sum()
-        }
-
-        let s = "01234".to_string();
-        assert_eq!(5, sum_len(["012", "", "34"]));
-        assert_eq!(5, sum_len(["01".to_string(), "2".to_string(),
-                               "34".to_string(), "".to_string()]));
-        assert_eq!(5, sum_len([s.as_slice()]));
-    }
-
-    #[test]
-    fn test_str_from_utf8() {
-        let xs = bytes!("hello");
-        assert_eq!(from_utf8(xs), Some("hello"));
-
-        let xs = bytes!("ศไทย中华Việt Nam");
-        assert_eq!(from_utf8(xs), Some("ศไทย中华Việt Nam"));
-
-        let xs = bytes!("hello", 0xff);
-        assert_eq!(from_utf8(xs), None);
-    }
-
-    #[test]
-    fn test_str_from_utf8_owned() {
-        let xs = Vec::from_slice(bytes!("hello"));
-        assert_eq!(from_utf8_owned(xs), Ok("hello".to_string()));
-
-        let xs = Vec::from_slice(bytes!("ศไทย中华Việt Nam"));
-        assert_eq!(from_utf8_owned(xs), Ok("ศไทย中华Việt Nam".to_string()));
-
-        let xs = Vec::from_slice(bytes!("hello", 0xff));
-        assert_eq!(from_utf8_owned(xs),
-                   Err(Vec::from_slice(bytes!("hello", 0xff))));
-    }
-
-    #[test]
-    fn test_str_from_utf8_lossy() {
-        let xs = bytes!("hello");
-        assert_eq!(from_utf8_lossy(xs), Slice("hello"));
-
-        let xs = bytes!("ศไทย中华Việt Nam");
-        assert_eq!(from_utf8_lossy(xs), Slice("ศไทย中华Việt Nam"));
-
-        let xs = bytes!("Hello", 0xC2, " There", 0xFF, " Goodbye");
-        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD There\uFFFD Goodbye".to_string()));
-
-        let xs = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
-        assert_eq!(from_utf8_lossy(xs), Owned("Hello\uFFFD\uFFFD There\uFFFD Goodbye".to_string()));
-
-        let xs = bytes!(0xF5, "foo", 0xF5, 0x80, "bar");
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFD\uFFFDbar".to_string()));
-
-        let xs = bytes!(0xF1, "foo", 0xF1, 0x80, "bar", 0xF1, 0x80, 0x80, "baz");
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFDbaz".to_string()));
-
-        let xs = bytes!(0xF4, "foo", 0xF4, 0x80, "bar", 0xF4, 0xBF, "baz");
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz".to_string()));
-
-        let xs = bytes!(0xF0, 0x80, 0x80, 0x80, "foo", 0xF0, 0x90, 0x80, 0x80, "bar");
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFD\uFFFD\
-                                               foo\U00010000bar".to_string()));
-
-        // surrogates
-        let xs = bytes!(0xED, 0xA0, 0x80, "foo", 0xED, 0xBF, 0xBF, "bar");
-        assert_eq!(from_utf8_lossy(xs), Owned("\uFFFD\uFFFD\uFFFDfoo\
-                                               \uFFFD\uFFFD\uFFFDbar".to_string()));
-    }
-
-    #[test]
-    fn test_from_str() {
-      let owned: Option<String> = from_str("string");
-      assert_eq!(owned, Some("string".to_string()));
-    }
-
-    #[test]
-    fn test_maybe_owned_traits() {
-        let s = Slice("abcde");
-        assert_eq!(s.len(), 5);
-        assert_eq!(s.as_slice(), "abcde");
-        assert_eq!(s.to_str(), "abcde".to_string());
-        assert_eq!(format!("{}", s), "abcde".to_string());
-        assert!(s.lt(&Owned("bcdef".to_string())));
-        assert_eq!(Slice(""), Default::default());
-
-        let o = Owned("abcde".to_string());
-        assert_eq!(o.len(), 5);
-        assert_eq!(o.as_slice(), "abcde");
-        assert_eq!(o.to_str(), "abcde".to_string());
-        assert_eq!(format!("{}", o), "abcde".to_string());
-        assert!(o.lt(&Slice("bcdef")));
-        assert_eq!(Owned("".to_string()), Default::default());
-
-        assert!(s.cmp(&o) == Equal);
-        assert!(s.equiv(&o));
-
-        assert!(o.cmp(&s) == Equal);
-        assert!(o.equiv(&s));
-    }
-
-    #[test]
-    fn test_maybe_owned_methods() {
-        let s = Slice("abcde");
-        assert!(s.is_slice());
-        assert!(!s.is_owned());
-
-        let o = Owned("abcde".to_string());
-        assert!(!o.is_slice());
-        assert!(o.is_owned());
-    }
-
-    #[test]
-    fn test_maybe_owned_clone() {
-        assert_eq!(Owned("abcde".to_string()), Slice("abcde").clone());
-        assert_eq!(Owned("abcde".to_string()), Owned("abcde".to_string()).clone());
-        assert_eq!(Slice("abcde"), Slice("abcde").clone());
-        assert_eq!(Slice("abcde"), Owned("abcde".to_string()).clone());
-    }
-
-    #[test]
-    fn test_maybe_owned_into_string() {
-        assert_eq!(Slice("abcde").into_string(), "abcde".to_string());
-        assert_eq!(Owned("abcde".to_string()).into_string(), "abcde".to_string());
-    }
-
-    #[test]
-    fn test_into_maybe_owned() {
-        assert_eq!("abcde".into_maybe_owned(), Slice("abcde"));
-        assert_eq!(("abcde".to_string()).into_maybe_owned(), Slice("abcde"));
-        assert_eq!("abcde".into_maybe_owned(), Owned("abcde".to_string()));
-        assert_eq!(("abcde".to_string()).into_maybe_owned(), Owned("abcde".to_string()));
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-    use super::*;
-    use prelude::*;
-
-    #[bench]
-    fn char_iterator(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.char_len();
-
-        b.iter(|| assert_eq!(s.chars().len(), len));
-    }
-
-    #[bench]
-    fn char_iterator_ascii(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb
-        Mary had a little lamb, Little lamb";
-        let len = s.char_len();
-
-        b.iter(|| assert_eq!(s.chars().len(), len));
-    }
-
-    #[bench]
-    fn char_iterator_rev(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.char_len();
-
-        b.iter(|| assert_eq!(s.chars().rev().len(), len));
-    }
-
-    #[bench]
-    fn char_indicesator(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.char_len();
-
-        b.iter(|| assert_eq!(s.char_indices().len(), len));
-    }
-
-    #[bench]
-    fn char_indicesator_rev(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let len = s.char_len();
-
-        b.iter(|| assert_eq!(s.char_indices().rev().len(), len));
-    }
-
-    #[bench]
-    fn split_unicode_ascii(b: &mut Bencher) {
-        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
-        b.iter(|| assert_eq!(s.split('V').len(), 3));
-    }
-
-    #[bench]
-    fn split_unicode_not_ascii(b: &mut Bencher) {
-        struct NotAscii(char);
-        impl CharEq for NotAscii {
-            fn matches(&mut self, c: char) -> bool {
-                let NotAscii(cc) = *self;
-                cc == c
-            }
-            fn only_ascii(&self) -> bool { false }
-        }
-        let s = "ประเทศไทย中华Việt Namประเทศไทย中华Việt Nam";
-
-        b.iter(|| assert_eq!(s.split(NotAscii('V')).len(), 3));
-    }
-
-
-    #[bench]
-    fn split_ascii(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').len();
-
-        b.iter(|| assert_eq!(s.split(' ').len(), len));
-    }
-
-    #[bench]
-    fn split_not_ascii(b: &mut Bencher) {
-        struct NotAscii(char);
-        impl CharEq for NotAscii {
-            #[inline]
-            fn matches(&mut self, c: char) -> bool {
-                let NotAscii(cc) = *self;
-                cc == c
-            }
-            fn only_ascii(&self) -> bool { false }
-        }
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').len();
-
-        b.iter(|| assert_eq!(s.split(NotAscii(' ')).len(), len));
-    }
-
-    #[bench]
-    fn split_extern_fn(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').len();
-        fn pred(c: char) -> bool { c == ' ' }
-
-        b.iter(|| assert_eq!(s.split(pred).len(), len));
-    }
-
-    #[bench]
-    fn split_closure(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').len();
-
-        b.iter(|| assert_eq!(s.split(|c: char| c == ' ').len(), len));
-    }
-
-    #[bench]
-    fn split_slice(b: &mut Bencher) {
-        let s = "Mary had a little lamb, Little lamb, little-lamb.";
-        let len = s.split(' ').len();
-
-        b.iter(|| assert_eq!(s.split(&[' ']).len(), len));
-    }
-
-    #[bench]
-    fn is_utf8_100_ascii(b: &mut Bencher) {
-
-        let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
-                        Lorem ipsum dolor sit amet, consectetur. ");
-
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            is_utf8(s)
-        });
-    }
-
-    #[bench]
-    fn is_utf8_100_multibyte(b: &mut Bencher) {
-        let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            is_utf8(s)
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_ascii(b: &mut Bencher) {
-        let s = bytes!("Hello there, the quick brown fox jumped over the lazy dog! \
-                        Lorem ipsum dolor sit amet, consectetur. ");
-
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            let _ = from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_multibyte(b: &mut Bencher) {
-        let s = bytes!("𐌀𐌖𐌋𐌄𐌑𐌉ปรدولة الكويتทศไทย中华𐍅𐌿𐌻𐍆𐌹𐌻𐌰");
-        assert_eq!(100, s.len());
-        b.iter(|| {
-            let _ = from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_invalid(b: &mut Bencher) {
-        let s = bytes!("Hello", 0xC0, 0x80, " There", 0xE6, 0x83, " Goodbye");
-        b.iter(|| {
-            let _ = from_utf8_lossy(s);
-        });
-    }
-
-    #[bench]
-    fn from_utf8_lossy_100_invalid(b: &mut Bencher) {
-        let s = Vec::from_elem(100, 0xF5u8);
-        b.iter(|| {
-            let _ = from_utf8_lossy(s.as_slice());
-        });
-    }
-
-    #[bench]
-    fn bench_connect(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        let sep = "→";
-        let v = [s, s, s, s, s, s, s, s, s, s];
-        b.iter(|| {
-            assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9);
-        })
-    }
-
-    #[bench]
-    fn bench_contains_short_short(b: &mut Bencher) {
-        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-        let needle = "sit";
-
-        b.iter(|| {
-            assert!(haystack.contains(needle));
-        })
-    }
-
-    #[bench]
-    fn bench_contains_short_long(b: &mut Bencher) {
-        let haystack = "\
-Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
-ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
-eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
-sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
-tempus vel, gravida nec quam.
-
-In est dui, tincidunt sed tempus interdum, adipiscing laoreet ante. Etiam tempor, tellus quis \
-sagittis interdum, nulla purus mattis sem, quis auctor erat odio ac tellus. In nec nunc sit amet \
-diam volutpat molestie at sed ipsum. Vestibulum laoreet consequat vulputate. Integer accumsan \
-lorem ac dignissim placerat. Suspendisse convallis faucibus lorem. Aliquam erat volutpat. In vel \
-eleifend felis. Sed suscipit nulla lorem, sed mollis est sollicitudin et. Nam fermentum egestas \
-interdum. Curabitur ut nisi justo.
-
-Sed sollicitudin ipsum tellus, ut condimentum leo eleifend nec. Cras ut velit ante. Phasellus nec \
-mollis odio. Mauris molestie erat in arcu mattis, at aliquet dolor vehicula. Quisque malesuada \
-lectus sit amet nisi pretium, a condimentum ipsum porta. Morbi at dapibus diam. Praesent egestas \
-est sed risus elementum, eu rutrum metus ultrices. Etiam fermentum consectetur magna, id rutrum \
-felis accumsan a. Aliquam ut pellentesque libero. Sed mi nulla, lobortis eu tortor id, suscipit \
-ultricies neque. Morbi iaculis sit amet risus at iaculis. Praesent eget ligula quis turpis \
-feugiat suscipit vel non arcu. Interdum et malesuada fames ac ante ipsum primis in faucibus. \
-Aliquam sit amet placerat lorem.
-
-Cras a lacus vel ante posuere elementum. Nunc est leo, bibendum ut facilisis vel, bibendum at \
-mauris. Nullam adipiscing diam vel odio ornare, luctus adipiscing mi luctus. Nulla facilisi. \
-Mauris adipiscing bibendum neque, quis adipiscing lectus tempus et. Sed feugiat erat et nisl \
-lobortis pharetra. Donec vitae erat enim. Nullam sit amet felis et quam lacinia tincidunt. Aliquam \
-suscipit dapibus urna. Sed volutpat urna in magna pulvinar volutpat. Phasellus nec tellus ac diam \
-cursus accumsan.
-
-Nam lectus enim, dapibus non nisi tempor, consectetur convallis massa. Maecenas eleifend dictum \
-feugiat. Etiam quis mauris vel risus luctus mattis a a nunc. Nullam orci quam, imperdiet id \
-vehicula in, porttitor ut nibh. Duis sagittis adipiscing nisl vitae congue. Donec mollis risus eu \
-leo suscipit, varius porttitor nulla porta. Pellentesque ut sem nec nisi euismod vehicula. Nulla \
-malesuada sollicitudin quam eu fermentum.";
-        let needle = "english";
-
-        b.iter(|| {
-            assert!(!haystack.contains(needle));
-        })
-    }
-
-    #[bench]
-    fn bench_contains_bad_naive(b: &mut Bencher) {
-        let haystack = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
-        let needle = "aaaaaaaab";
-
-        b.iter(|| {
-            assert!(!haystack.contains(needle));
-        })
-    }
-
-    #[bench]
-    fn bench_contains_equal(b: &mut Bencher) {
-        let haystack = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-        let needle = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.";
-
-        b.iter(|| {
-            assert!(haystack.contains(needle));
-        })
-    }
-}
diff --git a/src/libstd/string.rs b/src/libstd/string.rs
deleted file mode 100644 (file)
index 80973bb..0000000
+++ /dev/null
@@ -1,480 +0,0 @@
-// Copyright 2014 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.
-
-//! An owned, growable string that enforces that its contents are valid UTF-8.
-
-use c_vec::CVec;
-use char::Char;
-use cmp::Equiv;
-use container::{Container, Mutable};
-use default::Default;
-use fmt;
-use from_str::FromStr;
-use io::Writer;
-use iter::{Extendable, FromIterator, Iterator, range};
-use mem;
-use option::{None, Option, Some};
-use ptr::RawPtr;
-use ptr;
-use result::{Result, Ok, Err};
-use slice::Vector;
-use str::{CharRange, Str, StrSlice, StrAllocating};
-use str;
-use vec::Vec;
-
-/// A growable string stored as a UTF-8 encoded buffer.
-#[deriving(Clone, PartialEq, PartialOrd, Eq, Ord)]
-pub struct String {
-    vec: Vec<u8>,
-}
-
-impl String {
-    /// Creates a new string buffer initialized with the empty string.
-    #[inline]
-    pub fn new() -> String {
-        String {
-            vec: Vec::new(),
-        }
-    }
-
-    /// Creates a new string buffer with the given capacity.
-    #[inline]
-    pub fn with_capacity(capacity: uint) -> String {
-        String {
-            vec: Vec::with_capacity(capacity),
-        }
-    }
-
-    /// Creates a new string buffer from length, capacity, and a pointer.
-    #[inline]
-    pub unsafe fn from_raw_parts(length: uint, capacity: uint, ptr: *mut u8) -> String {
-        String {
-            vec: Vec::from_raw_parts(length, capacity, ptr),
-        }
-    }
-
-    /// Creates a new string buffer from the given string.
-    #[inline]
-    pub fn from_str(string: &str) -> String {
-        String {
-            vec: Vec::from_slice(string.as_bytes())
-        }
-    }
-
-    #[allow(missing_doc)]
-    #[deprecated = "obsoleted by the removal of ~str"]
-    #[inline]
-    pub fn from_owned_str(string: String) -> String {
-        string
-    }
-
-    /// Returns the vector as a string buffer, if possible, taking care not to
-    /// copy it.
-    ///
-    /// Returns `Err` with the original vector if the vector contains invalid
-    /// UTF-8.
-    #[inline]
-    pub fn from_utf8(vec: Vec<u8>) -> Result<String, Vec<u8>> {
-        if str::is_utf8(vec.as_slice()) {
-            Ok(String { vec: vec })
-        } else {
-            Err(vec)
-        }
-    }
-
-    /// Return the underlying byte buffer, encoded as UTF-8.
-    #[inline]
-    pub fn into_bytes(self) -> Vec<u8> {
-        self.vec
-    }
-
-    /// Pushes the given string onto this buffer; then, returns `self` so that it can be used
-    /// again.
-    #[inline]
-    pub fn append(mut self, second: &str) -> String {
-        self.push_str(second);
-        self
-    }
-
-    /// Creates a string buffer by repeating a character `length` times.
-    #[inline]
-    pub fn from_char(length: uint, ch: char) -> String {
-        if length == 0 {
-            return String::new()
-        }
-
-        let mut buf = String::new();
-        buf.push_char(ch);
-        let size = buf.len() * length;
-        buf.reserve(size);
-        for _ in range(1, length) {
-            buf.push_char(ch)
-        }
-        buf
-    }
-
-    /// Pushes the given string onto this string buffer.
-    #[inline]
-    pub fn push_str(&mut self, string: &str) {
-        self.vec.push_all(string.as_bytes())
-    }
-
-    /// Push `ch` onto the given string `count` times.
-    #[inline]
-    pub fn grow(&mut self, count: uint, ch: char) {
-        for _ in range(0, count) {
-            self.push_char(ch)
-        }
-    }
-
-    /// Returns the number of bytes that this string buffer can hold without reallocating.
-    #[inline]
-    pub fn byte_capacity(&self) -> uint {
-        self.vec.capacity()
-    }
-
-    /// Reserves capacity for at least `extra` additional bytes in this string buffer.
-    #[inline]
-    pub fn reserve_additional(&mut self, extra: uint) {
-        self.vec.reserve_additional(extra)
-    }
-
-    /// Reserves capacity for at least `capacity` bytes in this string buffer.
-    #[inline]
-    pub fn reserve(&mut self, capacity: uint) {
-        self.vec.reserve(capacity)
-    }
-
-    /// Reserves capacity for exactly `capacity` bytes in this string buffer.
-    #[inline]
-    pub fn reserve_exact(&mut self, capacity: uint) {
-        self.vec.reserve_exact(capacity)
-    }
-
-    /// Shrinks the capacity of this string buffer to match its length.
-    #[inline]
-    pub fn shrink_to_fit(&mut self) {
-        self.vec.shrink_to_fit()
-    }
-
-    /// Adds the given character to the end of the string.
-    #[inline]
-    pub fn push_char(&mut self, ch: char) {
-        let cur_len = self.len();
-        unsafe {
-            // This may use up to 4 bytes.
-            self.vec.reserve_additional(4);
-
-            // Attempt to not use an intermediate buffer by just pushing bytes
-            // directly onto this string.
-            let mut c_vector = CVec::new(self.vec.as_mut_ptr().offset(cur_len as int), 4);
-            let used = ch.encode_utf8(c_vector.as_mut_slice());
-            self.vec.set_len(cur_len + used);
-        }
-    }
-
-    /// Pushes the given bytes onto this string buffer. This is unsafe because it does not check
-    /// to ensure that the resulting string will be valid UTF-8.
-    #[inline]
-    pub unsafe fn push_bytes(&mut self, bytes: &[u8]) {
-        self.vec.push_all(bytes)
-    }
-
-    /// Works with the underlying buffer as a byte slice.
-    #[inline]
-    pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
-        self.vec.as_slice()
-    }
-
-    /// Works with the underlying buffer as a mutable byte slice. Unsafe
-    /// because this can be used to violate the UTF-8 property.
-    #[inline]
-    pub unsafe fn as_mut_bytes<'a>(&'a mut self) -> &'a mut [u8] {
-        self.vec.as_mut_slice()
-    }
-
-    /// Shorten a string to the specified length (which must be <= the current length)
-    #[inline]
-    pub fn truncate(&mut self, len: uint) {
-        assert!(self.as_slice().is_char_boundary(len));
-        self.vec.truncate(len)
-    }
-
-    /// Appends a byte to this string buffer. The caller must preserve the valid UTF-8 property.
-    #[inline]
-    pub unsafe fn push_byte(&mut self, byte: u8) {
-        self.push_bytes([byte])
-    }
-
-    /// Removes the last byte from the string buffer and returns it. Returns `None` if this string
-    /// buffer is empty.
-    ///
-    /// The caller must preserve the valid UTF-8 property.
-    #[inline]
-    pub unsafe fn pop_byte(&mut self) -> Option<u8> {
-        let len = self.len();
-        if len == 0 {
-            return None
-        }
-
-        let byte = self.as_slice()[len - 1];
-        self.vec.set_len(len - 1);
-        Some(byte)
-    }
-
-    /// Removes the last character from the string buffer and returns it. Returns `None` if this
-    /// string buffer is empty.
-    #[inline]
-    pub fn pop_char(&mut self) -> Option<char> {
-        let len = self.len();
-        if len == 0 {
-            return None
-        }
-
-        let CharRange {ch, next} = self.as_slice().char_range_at_reverse(len);
-        unsafe {
-            self.vec.set_len(next);
-        }
-        Some(ch)
-    }
-
-    /// Removes the first byte from the string buffer and returns it. Returns `None` if this string
-    /// buffer is empty.
-    ///
-    /// The caller must preserve the valid UTF-8 property.
-    pub unsafe fn shift_byte(&mut self) -> Option<u8> {
-        self.vec.shift()
-    }
-
-    /// Removes the first character from the string buffer and returns it. Returns `None` if this
-    /// string buffer is empty.
-    ///
-    /// # Warning
-    ///
-    /// This is a O(n) operation as it requires copying every element in the buffer.
-    pub fn shift_char (&mut self) -> Option<char> {
-        let len = self.len();
-        if len == 0 {
-            return None
-        }
-
-        let CharRange {ch, next} = self.as_slice().char_range_at(0);
-        let new_len = len - next;
-        unsafe {
-            ptr::copy_memory(self.vec.as_mut_ptr(), self.vec.as_ptr().offset(next as int), new_len);
-            self.vec.set_len(new_len);
-        }
-        Some(ch)
-    }
-
-    /// Views the string buffer as a mutable sequence of bytes.
-    ///
-    /// Callers must preserve the valid UTF-8 property.
-    pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
-        &mut self.vec
-    }
-}
-
-impl Container for String {
-    #[inline]
-    fn len(&self) -> uint {
-        self.vec.len()
-    }
-}
-
-impl Mutable for String {
-    #[inline]
-    fn clear(&mut self) {
-        self.vec.clear()
-    }
-}
-
-impl FromIterator<char> for String {
-    fn from_iter<I:Iterator<char>>(iterator: I) -> String {
-        let mut buf = String::new();
-        buf.extend(iterator);
-        buf
-    }
-}
-
-impl Extendable<char> for String {
-    fn extend<I:Iterator<char>>(&mut self, mut iterator: I) {
-        for ch in iterator {
-            self.push_char(ch)
-        }
-    }
-}
-
-impl Str for String {
-    #[inline]
-    fn as_slice<'a>(&'a self) -> &'a str {
-        unsafe {
-            mem::transmute(self.vec.as_slice())
-        }
-    }
-}
-
-impl StrAllocating for String {
-    #[inline]
-    fn into_string(self) -> String {
-        self
-    }
-}
-
-impl Default for String {
-    fn default() -> String {
-        String::new()
-    }
-}
-
-impl fmt::Show for String {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.as_slice().fmt(f)
-    }
-}
-
-impl<H:Writer> ::hash::Hash<H> for String {
-    #[inline]
-    fn hash(&self, hasher: &mut H) {
-        self.as_slice().hash(hasher)
-    }
-}
-
-impl<'a, S: Str> Equiv<S> for String {
-    #[inline]
-    fn equiv(&self, other: &S) -> bool {
-        self.as_slice() == other.as_slice()
-    }
-}
-
-impl FromStr for String {
-    #[inline]
-    fn from_str(s: &str) -> Option<String> {
-        Some(s.to_string())
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    extern crate test;
-    use container::{Container, Mutable};
-    use self::test::Bencher;
-    use str::{Str, StrSlice};
-    use super::String;
-
-    #[bench]
-    fn bench_with_capacity(b: &mut Bencher) {
-        b.iter(|| {
-            String::with_capacity(100)
-        });
-    }
-
-    #[bench]
-    fn bench_push_str(b: &mut Bencher) {
-        let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb";
-        b.iter(|| {
-            let mut r = String::new();
-            r.push_str(s);
-        });
-    }
-
-    #[test]
-    fn test_push_bytes() {
-        let mut s = String::from_str("ABC");
-        unsafe {
-            s.push_bytes([ 'D' as u8 ]);
-        }
-        assert_eq!(s.as_slice(), "ABCD");
-    }
-
-    #[test]
-    fn test_push_str() {
-        let mut s = String::new();
-        s.push_str("");
-        assert_eq!(s.as_slice().slice_from(0), "");
-        s.push_str("abc");
-        assert_eq!(s.as_slice().slice_from(0), "abc");
-        s.push_str("ประเทศไทย中华Việt Nam");
-        assert_eq!(s.as_slice().slice_from(0), "abcประเทศไทย中华Việt Nam");
-    }
-
-    #[test]
-    fn test_push_char() {
-        let mut data = String::from_str("ประเทศไทย中");
-        data.push_char('华');
-        data.push_char('b'); // 1 byte
-        data.push_char('¢'); // 2 byte
-        data.push_char('€'); // 3 byte
-        data.push_char('𤭢'); // 4 byte
-        assert_eq!(data.as_slice(), "ประเทศไทย中华b¢€𤭢");
-    }
-
-    #[test]
-    fn test_pop_char() {
-        let mut data = String::from_str("ประเทศไทย中华b¢€𤭢");
-        assert_eq!(data.pop_char().unwrap(), '𤭢'); // 4 bytes
-        assert_eq!(data.pop_char().unwrap(), '€'); // 3 bytes
-        assert_eq!(data.pop_char().unwrap(), '¢'); // 2 bytes
-        assert_eq!(data.pop_char().unwrap(), 'b'); // 1 bytes
-        assert_eq!(data.pop_char().unwrap(), '华');
-        assert_eq!(data.as_slice(), "ประเทศไทย中");
-    }
-
-    #[test]
-    fn test_shift_char() {
-        let mut data = String::from_str("𤭢€¢b华ประเทศไทย中");
-        assert_eq!(data.shift_char().unwrap(), '𤭢'); // 4 bytes
-        assert_eq!(data.shift_char().unwrap(), '€'); // 3 bytes
-        assert_eq!(data.shift_char().unwrap(), '¢'); // 2 bytes
-        assert_eq!(data.shift_char().unwrap(), 'b'); // 1 bytes
-        assert_eq!(data.shift_char().unwrap(), '华');
-        assert_eq!(data.as_slice(), "ประเทศไทย中");
-    }
-
-    #[test]
-    fn test_str_truncate() {
-        let mut s = String::from_str("12345");
-        s.truncate(5);
-        assert_eq!(s.as_slice(), "12345");
-        s.truncate(3);
-        assert_eq!(s.as_slice(), "123");
-        s.truncate(0);
-        assert_eq!(s.as_slice(), "");
-
-        let mut s = String::from_str("12345");
-        let p = s.as_slice().as_ptr();
-        s.truncate(3);
-        s.push_str("6");
-        let p_ = s.as_slice().as_ptr();
-        assert_eq!(p_, p);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_str_truncate_invalid_len() {
-        let mut s = String::from_str("12345");
-        s.truncate(6);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_str_truncate_split_codepoint() {
-        let mut s = String::from_str("\u00FC"); // ü
-        s.truncate(1);
-    }
-
-    #[test]
-    fn test_str_clear() {
-        let mut s = String::from_str("12345");
-        s.clear();
-        assert_eq!(s.len(), 0);
-        assert_eq!(s.as_slice(), "");
-    }
-}
diff --git a/src/libstd/unicode.rs b/src/libstd/unicode.rs
deleted file mode 100644 (file)
index 03c960e..0000000
+++ /dev/null
@@ -1,185 +0,0 @@
-// Copyright 2012-2014 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.
-
-// NOTE: The following code was generated by "src/etc/unicode.py", do not edit directly
-
-#![allow(missing_doc, non_uppercase_statics)]
-
-pub mod normalization {
-    use option::{Some, None};
-    use slice::ImmutableVector;
-
-    fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 {
-        use cmp::{Equal, Less, Greater};
-        match r.bsearch(|&(lo, hi, _)| {
-            if lo <= c && c <= hi { Equal }
-            else if hi < c { Less }
-            else { Greater }
-        }) {
-            Some(idx) => {
-                let (_, _, result) = r[idx];
-                result
-            }
-            None => 0
-        }
-    }
-
-
-    static combining_class_table : &'static [(char, char, u8)] = &[
-        ('\u0300', '\u0314', 230), ('\u0315', '\u0315', 232),
-        ('\u0316', '\u0319', 220), ('\u031a', '\u031a', 232),
-        ('\u031b', '\u031b', 216), ('\u031c', '\u0320', 220),
-        ('\u0321', '\u0322', 202), ('\u0323', '\u0326', 220),
-        ('\u0327', '\u0328', 202), ('\u0329', '\u0333', 220),
-        ('\u0334', '\u0338', 1), ('\u0339', '\u033c', 220),
-        ('\u033d', '\u0344', 230), ('\u0345', '\u0345', 240),
-        ('\u0346', '\u0346', 230), ('\u0347', '\u0349', 220),
-        ('\u034a', '\u034c', 230), ('\u034d', '\u034e', 220),
-        ('\u0350', '\u0352', 230), ('\u0353', '\u0356', 220),
-        ('\u0357', '\u0357', 230), ('\u0358', '\u0358', 232),
-        ('\u0359', '\u035a', 220), ('\u035b', '\u035b', 230),
-        ('\u035c', '\u035c', 233), ('\u035d', '\u035e', 234),
-        ('\u035f', '\u035f', 233), ('\u0360', '\u0361', 234),
-        ('\u0362', '\u0362', 233), ('\u0363', '\u036f', 230),
-        ('\u0483', '\u0487', 230), ('\u0591', '\u0591', 220),
-        ('\u0592', '\u0595', 230), ('\u0596', '\u0596', 220),
-        ('\u0597', '\u0599', 230), ('\u059a', '\u059a', 222),
-        ('\u059b', '\u059b', 220), ('\u059c', '\u05a1', 230),
-        ('\u05a2', '\u05a7', 220), ('\u05a8', '\u05a9', 230),
-        ('\u05aa', '\u05aa', 220), ('\u05ab', '\u05ac', 230),
-        ('\u05ad', '\u05ad', 222), ('\u05ae', '\u05ae', 228),
-        ('\u05af', '\u05af', 230), ('\u05b0', '\u05b0', 10),
-        ('\u05b1', '\u05b1', 11), ('\u05b2', '\u05b2', 12),
-        ('\u05b3', '\u05b3', 13), ('\u05b4', '\u05b4', 14),
-        ('\u05b5', '\u05b5', 15), ('\u05b6', '\u05b6', 16),
-        ('\u05b7', '\u05b7', 17), ('\u05b8', '\u05b8', 18),
-        ('\u05b9', '\u05ba', 19), ('\u05bb', '\u05bb', 20),
-        ('\u05bc', '\u05bc', 21), ('\u05bd', '\u05bd', 22),
-        ('\u05bf', '\u05bf', 23), ('\u05c1', '\u05c1', 24),
-        ('\u05c2', '\u05c2', 25), ('\u05c4', '\u05c4', 230),
-        ('\u05c5', '\u05c5', 220), ('\u05c7', '\u05c7', 18),
-        ('\u0610', '\u0617', 230), ('\u0618', '\u0618', 30),
-        ('\u0619', '\u0619', 31), ('\u061a', '\u061a', 32),
-        ('\u064b', '\u064b', 27), ('\u064c', '\u064c', 28),
-        ('\u064d', '\u064d', 29), ('\u064e', '\u064e', 30),
-        ('\u064f', '\u064f', 31), ('\u0650', '\u0650', 32),
-        ('\u0651', '\u0651', 33), ('\u0652', '\u0652', 34),
-        ('\u0653', '\u0654', 230), ('\u0655', '\u0656', 220),
-        ('\u0657', '\u065b', 230), ('\u065c', '\u065c', 220),
-        ('\u065d', '\u065e', 230), ('\u065f', '\u065f', 220),
-        ('\u0670', '\u0670', 35), ('\u06d6', '\u06dc', 230),
-        ('\u06df', '\u06e2', 230), ('\u06e3', '\u06e3', 220),
-        ('\u06e4', '\u06e4', 230), ('\u06e7', '\u06e8', 230),
-        ('\u06ea', '\u06ea', 220), ('\u06eb', '\u06ec', 230),
-        ('\u06ed', '\u06ed', 220), ('\u0711', '\u0711', 36),
-        ('\u0730', '\u0730', 230), ('\u0731', '\u0731', 220),
-        ('\u0732', '\u0733', 230), ('\u0734', '\u0734', 220),
-        ('\u0735', '\u0736', 230), ('\u0737', '\u0739', 220),
-        ('\u073a', '\u073a', 230), ('\u073b', '\u073c', 220),
-        ('\u073d', '\u073d', 230), ('\u073e', '\u073e', 220),
-        ('\u073f', '\u0741', 230), ('\u0742', '\u0742', 220),
-        ('\u0743', '\u0743', 230), ('\u0744', '\u0744', 220),
-        ('\u0745', '\u0745', 230), ('\u0746', '\u0746', 220),
-        ('\u0747', '\u0747', 230), ('\u0748', '\u0748', 220),
-        ('\u0749', '\u074a', 230), ('\u07eb', '\u07f1', 230),
-        ('\u07f2', '\u07f2', 220), ('\u07f3', '\u07f3', 230),
-        ('\u0816', '\u0819', 230), ('\u081b', '\u0823', 230),
-        ('\u0825', '\u0827', 230), ('\u0829', '\u082d', 230),
-        ('\u0859', '\u085b', 220), ('\u08e4', '\u08e5', 230),
-        ('\u08e6', '\u08e6', 220), ('\u08e7', '\u08e8', 230),
-        ('\u08e9', '\u08e9', 220), ('\u08ea', '\u08ec', 230),
-        ('\u08ed', '\u08ef', 220), ('\u08f0', '\u08f0', 27),
-        ('\u08f1', '\u08f1', 28), ('\u08f2', '\u08f2', 29),
-        ('\u08f3', '\u08f5', 230), ('\u08f6', '\u08f6', 220),
-        ('\u08f7', '\u08f8', 230), ('\u08f9', '\u08fa', 220),
-        ('\u08fb', '\u08fe', 230), ('\u093c', '\u093c', 7),
-        ('\u094d', '\u094d', 9), ('\u0951', '\u0951', 230),
-        ('\u0952', '\u0952', 220), ('\u0953', '\u0954', 230),
-        ('\u09bc', '\u09bc', 7), ('\u09cd', '\u09cd', 9),
-        ('\u0a3c', '\u0a3c', 7), ('\u0a4d', '\u0a4d', 9),
-        ('\u0abc', '\u0abc', 7), ('\u0acd', '\u0acd', 9),
-        ('\u0b3c', '\u0b3c', 7), ('\u0b4d', '\u0b4d', 9),
-        ('\u0bcd', '\u0bcd', 9), ('\u0c4d', '\u0c4d', 9),
-        ('\u0c55', '\u0c55', 84), ('\u0c56', '\u0c56', 91),
-        ('\u0cbc', '\u0cbc', 7), ('\u0ccd', '\u0ccd', 9),
-        ('\u0d4d', '\u0d4d', 9), ('\u0dca', '\u0dca', 9),
-        ('\u0e38', '\u0e39', 103), ('\u0e3a', '\u0e3a', 9),
-        ('\u0e48', '\u0e4b', 107), ('\u0eb8', '\u0eb9', 118),
-        ('\u0ec8', '\u0ecb', 122), ('\u0f18', '\u0f19', 220),
-        ('\u0f35', '\u0f35', 220), ('\u0f37', '\u0f37', 220),
-        ('\u0f39', '\u0f39', 216), ('\u0f71', '\u0f71', 129),
-        ('\u0f72', '\u0f72', 130), ('\u0f74', '\u0f74', 132),
-        ('\u0f7a', '\u0f7d', 130), ('\u0f80', '\u0f80', 130),
-        ('\u0f82', '\u0f83', 230), ('\u0f84', '\u0f84', 9),
-        ('\u0f86', '\u0f87', 230), ('\u0fc6', '\u0fc6', 220),
-        ('\u1037', '\u1037', 7), ('\u1039', '\u103a', 9),
-        ('\u108d', '\u108d', 220), ('\u135d', '\u135f', 230),
-        ('\u1714', '\u1714', 9), ('\u1734', '\u1734', 9),
-        ('\u17d2', '\u17d2', 9), ('\u17dd', '\u17dd', 230),
-        ('\u18a9', '\u18a9', 228), ('\u1939', '\u1939', 222),
-        ('\u193a', '\u193a', 230), ('\u193b', '\u193b', 220),
-        ('\u1a17', '\u1a17', 230), ('\u1a18', '\u1a18', 220),
-        ('\u1a60', '\u1a60', 9), ('\u1a75', '\u1a7c', 230),
-        ('\u1a7f', '\u1a7f', 220), ('\u1b34', '\u1b34', 7),
-        ('\u1b44', '\u1b44', 9), ('\u1b6b', '\u1b6b', 230),
-        ('\u1b6c', '\u1b6c', 220), ('\u1b6d', '\u1b73', 230),
-        ('\u1baa', '\u1bab', 9), ('\u1be6', '\u1be6', 7),
-        ('\u1bf2', '\u1bf3', 9), ('\u1c37', '\u1c37', 7),
-        ('\u1cd0', '\u1cd2', 230), ('\u1cd4', '\u1cd4', 1),
-        ('\u1cd5', '\u1cd9', 220), ('\u1cda', '\u1cdb', 230),
-        ('\u1cdc', '\u1cdf', 220), ('\u1ce0', '\u1ce0', 230),
-        ('\u1ce2', '\u1ce8', 1), ('\u1ced', '\u1ced', 220),
-        ('\u1cf4', '\u1cf4', 230), ('\u1dc0', '\u1dc1', 230),
-        ('\u1dc2', '\u1dc2', 220), ('\u1dc3', '\u1dc9', 230),
-        ('\u1dca', '\u1dca', 220), ('\u1dcb', '\u1dcc', 230),
-        ('\u1dcd', '\u1dcd', 234), ('\u1dce', '\u1dce', 214),
-        ('\u1dcf', '\u1dcf', 220), ('\u1dd0', '\u1dd0', 202),
-        ('\u1dd1', '\u1de6', 230), ('\u1dfc', '\u1dfc', 233),
-        ('\u1dfd', '\u1dfd', 220), ('\u1dfe', '\u1dfe', 230),
-        ('\u1dff', '\u1dff', 220), ('\u20d0', '\u20d1', 230),
-        ('\u20d2', '\u20d3', 1), ('\u20d4', '\u20d7', 230),
-        ('\u20d8', '\u20da', 1), ('\u20db', '\u20dc', 230),
-        ('\u20e1', '\u20e1', 230), ('\u20e5', '\u20e6', 1),
-        ('\u20e7', '\u20e7', 230), ('\u20e8', '\u20e8', 220),
-        ('\u20e9', '\u20e9', 230), ('\u20ea', '\u20eb', 1),
-        ('\u20ec', '\u20ef', 220), ('\u20f0', '\u20f0', 230),
-        ('\u2cef', '\u2cf1', 230), ('\u2d7f', '\u2d7f', 9),
-        ('\u2de0', '\u2dff', 230), ('\u302a', '\u302a', 218),
-        ('\u302b', '\u302b', 228), ('\u302c', '\u302c', 232),
-        ('\u302d', '\u302d', 222), ('\u302e', '\u302f', 224),
-        ('\u3099', '\u309a', 8), ('\ua66f', '\ua66f', 230),
-        ('\ua674', '\ua67d', 230), ('\ua69f', '\ua69f', 230),
-        ('\ua6f0', '\ua6f1', 230), ('\ua806', '\ua806', 9),
-        ('\ua8c4', '\ua8c4', 9), ('\ua8e0', '\ua8f1', 230),
-        ('\ua92b', '\ua92d', 220), ('\ua953', '\ua953', 9),
-        ('\ua9b3', '\ua9b3', 7), ('\ua9c0', '\ua9c0', 9),
-        ('\uaab0', '\uaab0', 230), ('\uaab2', '\uaab3', 230),
-        ('\uaab4', '\uaab4', 220), ('\uaab7', '\uaab8', 230),
-        ('\uaabe', '\uaabf', 230), ('\uaac1', '\uaac1', 230),
-        ('\uaaf6', '\uaaf6', 9), ('\uabed', '\uabed', 9),
-        ('\ufb1e', '\ufb1e', 26), ('\ufe20', '\ufe26', 230),
-        ('\U000101fd', '\U000101fd', 220), ('\U00010a0d', '\U00010a0d', 220),
-        ('\U00010a0f', '\U00010a0f', 230), ('\U00010a38', '\U00010a38', 230),
-        ('\U00010a39', '\U00010a39', 1), ('\U00010a3a', '\U00010a3a', 220),
-        ('\U00010a3f', '\U00010a3f', 9), ('\U00011046', '\U00011046', 9),
-        ('\U000110b9', '\U000110b9', 9), ('\U000110ba', '\U000110ba', 7),
-        ('\U00011100', '\U00011102', 230), ('\U00011133', '\U00011134', 9),
-        ('\U000111c0', '\U000111c0', 9), ('\U000116b6', '\U000116b6', 9),
-        ('\U000116b7', '\U000116b7', 7), ('\U0001d165', '\U0001d166', 216),
-        ('\U0001d167', '\U0001d169', 1), ('\U0001d16d', '\U0001d16d', 226),
-        ('\U0001d16e', '\U0001d172', 216), ('\U0001d17b', '\U0001d182', 220),
-        ('\U0001d185', '\U0001d189', 230), ('\U0001d18a', '\U0001d18b', 220),
-        ('\U0001d1aa', '\U0001d1ad', 230), ('\U0001d242', '\U0001d244', 230)
-    ];
-
-    pub fn canonical_combining_class(c: char) -> u8 {
-        bsearch_range_value_table(c, combining_class_table)
-    }
-}
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
deleted file mode 100644 (file)
index cdcee94..0000000
+++ /dev/null
@@ -1,1903 +0,0 @@
-// Copyright 2014 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.
-
-//! An owned, growable vector.
-
-use RawVec = raw::Vec;
-use clone::Clone;
-use cmp::{PartialOrd, PartialEq, Ordering, Eq, Ord, max};
-use container::{Container, Mutable};
-use default::Default;
-use fmt;
-use iter::{DoubleEndedIterator, FromIterator, Extendable, Iterator, range};
-use mem;
-use num::{CheckedMul, CheckedAdd};
-use num;
-use ops::{Add, Drop};
-use option::{None, Option, Some};
-use ptr::RawPtr;
-use ptr;
-use raw::Slice;
-use rt::heap::{allocate, reallocate, deallocate};
-use slice::{ImmutableEqVector, ImmutableVector, Items, MutItems, MutableVector};
-use slice::{MutableOrdVector, OwnedVector, Vector};
-use slice::{MutableVectorAllocating};
-
-/// An owned, growable vector.
-///
-/// # Examples
-///
-/// ```rust
-/// # use std::vec::Vec;
-/// let mut vec = Vec::new();
-/// vec.push(1);
-/// vec.push(2);
-///
-/// assert_eq!(vec.len(), 2);
-/// assert_eq!(vec.get(0), &1);
-///
-/// assert_eq!(vec.pop(), Some(2));
-/// assert_eq!(vec.len(), 1);
-/// ```
-///
-/// The `vec!` macro is provided to make initialization more convenient:
-///
-/// ```rust
-/// let mut vec = vec!(1, 2, 3);
-/// vec.push(4);
-/// assert_eq!(vec, vec!(1, 2, 3, 4));
-/// ```
-#[unsafe_no_drop_flag]
-pub struct Vec<T> {
-    len: uint,
-    cap: uint,
-    ptr: *mut T
-}
-
-impl<T> Vec<T> {
-    /// Constructs a new, empty `Vec`.
-    ///
-    /// The vector will not allocate until elements are pushed onto it.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let mut vec: Vec<int> = Vec::new();
-    /// ```
-    #[inline]
-    pub fn new() -> Vec<T> {
-        Vec { len: 0, cap: 0, ptr: 0 as *mut T }
-    }
-
-    /// Constructs a new, empty `Vec` with the specified capacity.
-    ///
-    /// The vector will be able to hold exactly `capacity` elements without
-    /// reallocating. If `capacity` is 0, the vector will not allocate.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let vec: Vec<int> = Vec::with_capacity(10);
-    /// ```
-    pub fn with_capacity(capacity: uint) -> Vec<T> {
-        if mem::size_of::<T>() == 0 {
-            Vec { len: 0, cap: ::uint::MAX, ptr: 0 as *mut T }
-        } else if capacity == 0 {
-            Vec::new()
-        } else {
-            let size = capacity.checked_mul(&mem::size_of::<T>())
-                               .expect("capacity overflow");
-            let ptr = unsafe { allocate(size, mem::min_align_of::<T>()) };
-            Vec { len: 0, cap: capacity, ptr: ptr as *mut T }
-        }
-    }
-
-    /// Creates and initializes a `Vec`.
-    ///
-    /// Creates a `Vec` of size `length` and initializes the elements to the
-    /// value returned by the closure `op`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let vec = Vec::from_fn(3, |idx| idx * 2);
-    /// assert_eq!(vec, vec!(0, 2, 4));
-    /// ```
-    pub fn from_fn(length: uint, op: |uint| -> T) -> Vec<T> {
-        unsafe {
-            let mut xs = Vec::with_capacity(length);
-            while xs.len < length {
-                mem::overwrite(xs.as_mut_slice().unsafe_mut_ref(xs.len),
-                                   op(xs.len));
-                xs.len += 1;
-            }
-            xs
-        }
-    }
-
-    /// Create a `Vec<T>` directly from the raw constituents.
-    ///
-    /// This is highly unsafe:
-    ///
-    /// - if `ptr` is null, then `length` and `capacity` should be 0
-    /// - `ptr` must point to an allocation of size `capacity`
-    /// - there must be `length` valid instances of type `T` at the
-    ///   beginning of that allocation
-    /// - `ptr` must be allocated by the default `Vec` allocator
-    pub unsafe fn from_raw_parts(length: uint, capacity: uint,
-                                 ptr: *mut T) -> Vec<T> {
-        Vec { len: length, cap: capacity, ptr: ptr }
-    }
-
-    /// Consumes the `Vec`, partitioning it based on a predicate.
-    ///
-    /// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A`
-    /// satisfy `f` and all elements of `B` do not. The order of elements is
-    /// preserved.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// let (even, odd) = vec.partition(|&n| n % 2 == 0);
-    /// assert_eq!(even, vec!(2, 4));
-    /// assert_eq!(odd, vec!(1, 3));
-    /// ```
-    #[inline]
-    pub fn partition(self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
-        let mut lefts  = Vec::new();
-        let mut rights = Vec::new();
-
-        for elt in self.move_iter() {
-            if f(&elt) {
-                lefts.push(elt);
-            } else {
-                rights.push(elt);
-            }
-        }
-
-        (lefts, rights)
-    }
-}
-
-impl<T: Clone> Vec<T> {
-    /// Iterates over the `second` vector, copying each element and appending it to
-    /// the `first`. Afterwards, the `first` is then returned for use again.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2);
-    /// let vec = vec.append([3, 4]);
-    /// assert_eq!(vec, vec!(1, 2, 3, 4));
-    /// ```
-    #[inline]
-    pub fn append(mut self, second: &[T]) -> Vec<T> {
-        self.push_all(second);
-        self
-    }
-
-    /// Constructs a `Vec` by cloning elements of a slice.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let slice = [1, 2, 3];
-    /// let vec = Vec::from_slice(slice);
-    /// ```
-    pub fn from_slice(values: &[T]) -> Vec<T> {
-        values.iter().map(|x| x.clone()).collect()
-    }
-
-    /// Constructs a `Vec` with copies of a value.
-    ///
-    /// Creates a `Vec` with `length` copies of `value`.
-    ///
-    /// # Example
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let vec = Vec::from_elem(3, "hi");
-    /// println!("{}", vec); // prints [hi, hi, hi]
-    /// ```
-    pub fn from_elem(length: uint, value: T) -> Vec<T> {
-        unsafe {
-            let mut xs = Vec::with_capacity(length);
-            while xs.len < length {
-                mem::overwrite(xs.as_mut_slice().unsafe_mut_ref(xs.len),
-                                   value.clone());
-                xs.len += 1;
-            }
-            xs
-        }
-    }
-
-    /// Appends all elements in a slice to the `Vec`.
-    ///
-    /// Iterates over the slice `other`, clones each element, and then appends
-    /// it to this `Vec`. The `other` vector is traversed in-order.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1);
-    /// vec.push_all([2, 3, 4]);
-    /// assert_eq!(vec, vec!(1, 2, 3, 4));
-    /// ```
-    #[inline]
-    pub fn push_all(&mut self, other: &[T]) {
-        self.extend(other.iter().map(|e| e.clone()));
-    }
-
-    /// Grows the `Vec` in-place.
-    ///
-    /// Adds `n` copies of `value` to the `Vec`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!("hello");
-    /// vec.grow(2, &("world"));
-    /// assert_eq!(vec, vec!("hello", "world", "world"));
-    /// ```
-    pub fn grow(&mut self, n: uint, value: &T) {
-        let new_len = self.len() + n;
-        self.reserve(new_len);
-        let mut i: uint = 0u;
-
-        while i < n {
-            self.push((*value).clone());
-            i += 1u;
-        }
-    }
-
-    /// Sets the value of a vector element at a given index, growing the vector
-    /// as needed.
-    ///
-    /// Sets the element at position `index` to `value`. If `index` is past the
-    /// end of the vector, expands the vector by replicating `initval` to fill
-    /// the intervening space.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!("a", "b", "c");
-    /// vec.grow_set(1, &("fill"), "d");
-    /// vec.grow_set(4, &("fill"), "e");
-    /// assert_eq!(vec, vec!("a", "d", "c", "fill", "e"));
-    /// ```
-    pub fn grow_set(&mut self, index: uint, initval: &T, value: T) {
-        let l = self.len();
-        if index >= l {
-            self.grow(index - l + 1u, initval);
-        }
-        *self.get_mut(index) = value;
-    }
-
-    /// Partitions a vector based on a predicate.
-    ///
-    /// Clones the elements of the vector, partitioning them into two `Vec`s
-    /// `(A,B)`, where all elements of `A` satisfy `f` and all elements of `B`
-    /// do not. The order of elements is preserved.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// let (even, odd) = vec.partitioned(|&n| n % 2 == 0);
-    /// assert_eq!(even, vec!(2, 4));
-    /// assert_eq!(odd, vec!(1, 3));
-    /// ```
-    pub fn partitioned(&self, f: |&T| -> bool) -> (Vec<T>, Vec<T>) {
-        let mut lefts = Vec::new();
-        let mut rights = Vec::new();
-
-        for elt in self.iter() {
-            if f(elt) {
-                lefts.push(elt.clone());
-            } else {
-                rights.push(elt.clone());
-            }
-        }
-
-        (lefts, rights)
-    }
-}
-
-impl<T:Clone> Clone for Vec<T> {
-    fn clone(&self) -> Vec<T> {
-        let len = self.len;
-        let mut vector = Vec::with_capacity(len);
-        // Unsafe code so this can be optimised to a memcpy (or something
-        // similarly fast) when T is Copy. LLVM is easily confused, so any
-        // extra operations during the loop can prevent this optimisation
-        {
-            let this_slice = self.as_slice();
-            while vector.len < len {
-                unsafe {
-                    mem::overwrite(
-                        vector.as_mut_slice().unsafe_mut_ref(vector.len),
-                        this_slice.unsafe_ref(vector.len).clone());
-                }
-                vector.len += 1;
-            }
-        }
-        vector
-    }
-
-    fn clone_from(&mut self, other: &Vec<T>) {
-        // drop anything in self that will not be overwritten
-        if self.len() > other.len() {
-            self.truncate(other.len())
-        }
-
-        // reuse the contained values' allocations/resources.
-        for (place, thing) in self.mut_iter().zip(other.iter()) {
-            place.clone_from(thing)
-        }
-
-        // self.len <= other.len due to the truncate above, so the
-        // slice here is always in-bounds.
-        let len = self.len();
-        self.extend(other.slice_from(len).iter().map(|x| x.clone()));
-    }
-}
-
-impl<T> FromIterator<T> for Vec<T> {
-    fn from_iter<I:Iterator<T>>(mut iterator: I) -> Vec<T> {
-        let (lower, _) = iterator.size_hint();
-        let mut vector = Vec::with_capacity(lower);
-        for element in iterator {
-            vector.push(element)
-        }
-        vector
-    }
-}
-
-impl<T> Extendable<T> for Vec<T> {
-    fn extend<I: Iterator<T>>(&mut self, mut iterator: I) {
-        let (lower, _) = iterator.size_hint();
-        self.reserve_additional(lower);
-        for element in iterator {
-            self.push(element)
-        }
-    }
-}
-
-impl<T: PartialEq> PartialEq for Vec<T> {
-    #[inline]
-    fn eq(&self, other: &Vec<T>) -> bool {
-        self.as_slice() == other.as_slice()
-    }
-}
-
-impl<T: PartialOrd> PartialOrd for Vec<T> {
-    #[inline]
-    fn lt(&self, other: &Vec<T>) -> bool {
-        self.as_slice() < other.as_slice()
-    }
-}
-
-impl<T: Eq> Eq for Vec<T> {}
-
-impl<T: Ord> Ord for Vec<T> {
-    #[inline]
-    fn cmp(&self, other: &Vec<T>) -> Ordering {
-        self.as_slice().cmp(&other.as_slice())
-    }
-}
-
-impl<T> Container for Vec<T> {
-    #[inline]
-    fn len(&self) -> uint {
-        self.len
-    }
-}
-
-// FIXME: #13996: need a way to mark the return value as `noalias`
-#[inline(never)]
-unsafe fn alloc_or_realloc<T>(ptr: *mut T, size: uint, old_size: uint) -> *mut T {
-    if old_size == 0 {
-        allocate(size, mem::min_align_of::<T>()) as *mut T
-    } else {
-        reallocate(ptr as *mut u8, size,
-                   mem::min_align_of::<T>(), old_size) as *mut T
-    }
-}
-
-#[inline]
-unsafe fn dealloc<T>(ptr: *mut T, len: uint) {
-    if mem::size_of::<T>() != 0 {
-        deallocate(ptr as *mut u8,
-                   len * mem::size_of::<T>(),
-                   mem::min_align_of::<T>())
-    }
-}
-
-impl<T> Vec<T> {
-    /// Returns the number of elements the vector can hold without
-    /// reallocating.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let vec: Vec<int> = Vec::with_capacity(10);
-    /// assert_eq!(vec.capacity(), 10);
-    /// ```
-    #[inline]
-    pub fn capacity(&self) -> uint {
-        self.cap
-    }
-
-     /// Reserves capacity for at least `n` additional elements in the given
-     /// vector.
-     ///
-     /// # Failure
-     ///
-     /// Fails if the new capacity overflows `uint`.
-     ///
-     /// # Example
-     ///
-     /// ```rust
-     /// # use std::vec::Vec;
-     /// let mut vec: Vec<int> = vec!(1);
-     /// vec.reserve_additional(10);
-     /// assert!(vec.capacity() >= 11);
-     /// ```
-    pub fn reserve_additional(&mut self, extra: uint) {
-        if self.cap - self.len < extra {
-            match self.len.checked_add(&extra) {
-                None => fail!("Vec::reserve_additional: `uint` overflow"),
-                Some(new_cap) => self.reserve(new_cap)
-            }
-        }
-    }
-
-    /// Reserves capacity for at least `n` elements in the given vector.
-    ///
-    /// This function will over-allocate in order to amortize the allocation
-    /// costs in scenarios where the caller may need to repeatedly reserve
-    /// additional space.
-    ///
-    /// If the capacity for `self` is already equal to or greater than the
-    /// requested capacity, then no action is taken.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.reserve(10);
-    /// assert!(vec.capacity() >= 10);
-    /// ```
-    pub fn reserve(&mut self, capacity: uint) {
-        if capacity >= self.len {
-            self.reserve_exact(num::next_power_of_two(capacity))
-        }
-    }
-
-    /// Reserves capacity for exactly `capacity` elements in the given vector.
-    ///
-    /// If the capacity for `self` is already equal to or greater than the
-    /// requested capacity, then no action is taken.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// # use std::vec::Vec;
-    /// let mut vec: Vec<int> = Vec::with_capacity(10);
-    /// vec.reserve_exact(11);
-    /// assert_eq!(vec.capacity(), 11);
-    /// ```
-    pub fn reserve_exact(&mut self, capacity: uint) {
-        if mem::size_of::<T>() == 0 { return }
-
-        if capacity > self.cap {
-            let size = capacity.checked_mul(&mem::size_of::<T>())
-                               .expect("capacity overflow");
-            unsafe {
-                self.ptr = alloc_or_realloc(self.ptr, size,
-                                            self.cap * mem::size_of::<T>());
-            }
-            self.cap = capacity;
-        }
-    }
-
-    /// Shrink the capacity of the vector as much as possible
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.shrink_to_fit();
-    /// ```
-    pub fn shrink_to_fit(&mut self) {
-        if mem::size_of::<T>() == 0 { return }
-
-        if self.len == 0 {
-            if self.cap != 0 {
-                unsafe {
-                    dealloc(self.ptr, self.cap)
-                }
-                self.cap = 0;
-            }
-        } else {
-            unsafe {
-                // Overflow check is unnecessary as the vector is already at
-                // least this large.
-                self.ptr = reallocate(self.ptr as *mut u8,
-                                      self.len * mem::size_of::<T>(),
-                                      mem::min_align_of::<T>(),
-                                      self.cap * mem::size_of::<T>()) as *mut T;
-            }
-            self.cap = self.len;
-        }
-    }
-
-    /// Remove the last element from a vector and return it, or `None` if it is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// assert_eq!(vec.pop(), Some(3));
-    /// assert_eq!(vec, vec!(1, 2));
-    /// ```
-    #[inline]
-    pub fn pop(&mut self) -> Option<T> {
-        if self.len == 0 {
-            None
-        } else {
-            unsafe {
-                self.len -= 1;
-                Some(ptr::read(self.as_slice().unsafe_ref(self.len())))
-            }
-        }
-    }
-
-    /// Append an element to a vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the number of elements in the vector overflows a `uint`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2);
-    /// vec.push(3);
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    #[inline]
-    pub fn push(&mut self, value: T) {
-        if mem::size_of::<T>() == 0 {
-            // zero-size types consume no memory, so we can't rely on the address space running out
-            self.len = self.len.checked_add(&1).expect("length overflow");
-            unsafe { mem::forget(value); }
-            return
-        }
-        if self.len == self.cap {
-            let old_size = self.cap * mem::size_of::<T>();
-            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
-            if old_size > size { fail!("capacity overflow") }
-            unsafe {
-                self.ptr = alloc_or_realloc(self.ptr, size,
-                                            self.cap * mem::size_of::<T>());
-            }
-            self.cap = max(self.cap, 2) * 2;
-        }
-
-        unsafe {
-            let end = (self.ptr as *T).offset(self.len as int) as *mut T;
-            mem::overwrite(&mut *end, value);
-            self.len += 1;
-        }
-    }
-
-    /// Appends one element to the vector provided. The vector itself is then
-    /// returned for use again.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2);
-    /// let vec = vec.append_one(3);
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    #[inline]
-    pub fn append_one(mut self, x: T) -> Vec<T> {
-        self.push(x);
-        self
-    }
-
-    /// Shorten a vector, dropping excess elements.
-    ///
-    /// If `len` is greater than the vector's current length, this has no
-    /// effect.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4);
-    /// vec.truncate(2);
-    /// assert_eq!(vec, vec!(1, 2));
-    /// ```
-    pub fn truncate(&mut self, len: uint) {
-        unsafe {
-            // drop any extra elements
-            while len < self.len {
-                // decrement len before the read(), so a failure on Drop doesn't
-                // re-drop the just-failed value.
-                self.len -= 1;
-                ptr::read(self.as_slice().unsafe_ref(self.len));
-            }
-        }
-    }
-
-    /// Work with `self` as a mutable slice.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// fn foo(slice: &mut [int]) {}
-    ///
-    /// let mut vec = vec!(1, 2);
-    /// foo(vec.as_mut_slice());
-    /// ```
-    #[inline]
-    pub fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] {
-        unsafe {
-            mem::transmute(Slice { data: self.as_mut_ptr() as *T, len: self.len })
-        }
-    }
-
-    /// Creates a consuming iterator, that is, one that moves each
-    /// value out of the vector (from start to end). The vector cannot
-    /// be used after calling this.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let v = vec!("a".to_string(), "b".to_string());
-    /// for s in v.move_iter() {
-    ///     // s has type String, not &String
-    ///     println!("{}", s);
-    /// }
-    /// ```
-    #[inline]
-    pub fn move_iter(self) -> MoveItems<T> {
-        unsafe {
-            let iter = mem::transmute(self.as_slice().iter());
-            let ptr = self.ptr;
-            let cap = self.cap;
-            mem::forget(self);
-            MoveItems { allocation: ptr, cap: cap, iter: iter }
-        }
-    }
-
-
-    /// Sets the length of a vector.
-    ///
-    /// This will explicitly set the size of the vector, without actually
-    /// modifying its buffers, so it is up to the caller to ensure that the
-    /// vector is actually the specified size.
-    #[inline]
-    pub unsafe fn set_len(&mut self, len: uint) {
-        self.len = len;
-    }
-
-    /// Returns a reference to the value at index `index`.
-    ///
-    /// # Failure
-    ///
-    /// Fails if `index` is out of bounds
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.get(1) == &2);
-    /// ```
-    #[inline]
-    pub fn get<'a>(&'a self, index: uint) -> &'a T {
-        &self.as_slice()[index]
-    }
-
-    /// Returns a mutable reference to the value at index `index`.
-    ///
-    /// # Failure
-    ///
-    /// Fails if `index` is out of bounds
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// *vec.get_mut(1) = 4;
-    /// assert_eq!(vec, vec!(1, 4, 3));
-    /// ```
-    #[inline]
-    pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T {
-        &mut self.as_mut_slice()[index]
-    }
-
-    /// Returns an iterator over references to the elements of the vector in
-    /// order.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// for num in vec.iter() {
-    ///     println!("{}", *num);
-    /// }
-    /// ```
-    #[inline]
-    pub fn iter<'a>(&'a self) -> Items<'a,T> {
-        self.as_slice().iter()
-    }
-
-
-    /// Returns an iterator over mutable references to the elements of the
-    /// vector in order.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// for num in vec.mut_iter() {
-    ///     *num = 0;
-    /// }
-    /// ```
-    #[inline]
-    pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a,T> {
-        self.as_mut_slice().mut_iter()
-    }
-
-    /// Sort the vector, in place, using `compare` to compare elements.
-    ///
-    /// This sort is `O(n log n)` worst-case and stable, but allocates
-    /// approximately `2 * n`, where `n` is the length of `self`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = vec!(5i, 4, 1, 3, 2);
-    /// v.sort_by(|a, b| a.cmp(b));
-    /// assert_eq!(v, vec!(1, 2, 3, 4, 5));
-    ///
-    /// // reverse sorting
-    /// v.sort_by(|a, b| b.cmp(a));
-    /// assert_eq!(v, vec!(5, 4, 3, 2, 1));
-    /// ```
-    #[inline]
-    pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) {
-        self.as_mut_slice().sort_by(compare)
-    }
-
-    /// Returns a slice of `self` between `start` and `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` or `end` point outside the bounds of `self`, or when
-    /// `start` > `end`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.slice(0, 2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] {
-        self.as_slice().slice(start, end)
-    }
-
-    /// Returns a slice containing all but the first element of the vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails when the vector is empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.tail() == [2, 3]);
-    /// ```
-    #[inline]
-    pub fn tail<'a>(&'a self) -> &'a [T] {
-        self.as_slice().tail()
-    }
-
-    /// Returns all but the first `n' elements of a vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails when there are fewer than `n` elements in the vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.tailn(2) == [3, 4]);
-    /// ```
-    #[inline]
-    pub fn tailn<'a>(&'a self, n: uint) -> &'a [T] {
-        self.as_slice().tailn(n)
-    }
-
-    /// Returns a reference to the last element of a vector, or `None` if it is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.last() == Some(&3));
-    /// ```
-    #[inline]
-    pub fn last<'a>(&'a self) -> Option<&'a T> {
-        self.as_slice().last()
-    }
-
-    /// Returns a mutable reference to the last element of a vector, or `None`
-    /// if it is empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// *vec.mut_last().unwrap() = 4;
-    /// assert_eq!(vec, vec!(1, 2, 4));
-    /// ```
-    #[inline]
-    pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> {
-        self.as_mut_slice().mut_last()
-    }
-
-    /// Remove an element from anywhere in the vector and return it, replacing
-    /// it with the last element. This does not preserve ordering, but is O(1).
-    ///
-    /// Returns `None` if `index` is out of bounds.
-    ///
-    /// # Example
-    /// ```rust
-    /// let mut v = vec!("foo".to_string(), "bar".to_string(),
-    ///                  "baz".to_string(), "qux".to_string());
-    ///
-    /// assert_eq!(v.swap_remove(1), Some("bar".to_string()));
-    /// assert_eq!(v, vec!("foo".to_string(), "qux".to_string(), "baz".to_string()));
-    ///
-    /// assert_eq!(v.swap_remove(0), Some("foo".to_string()));
-    /// assert_eq!(v, vec!("baz".to_string(), "qux".to_string()));
-    ///
-    /// assert_eq!(v.swap_remove(2), None);
-    /// ```
-    #[inline]
-    pub fn swap_remove(&mut self, index: uint) -> Option<T> {
-        let length = self.len();
-        if index < length - 1 {
-            self.as_mut_slice().swap(index, length - 1);
-        } else if index >= length {
-            return None
-        }
-        self.pop()
-    }
-
-    /// Prepend an element to the vector.
-    ///
-    /// # Warning
-    ///
-    /// This is an O(n) operation as it requires copying every element in the
-    /// vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.unshift(4);
-    /// assert_eq!(vec, vec!(4, 1, 2, 3));
-    /// ```
-    #[inline]
-    pub fn unshift(&mut self, element: T) {
-        self.insert(0, element)
-    }
-
-    /// Removes the first element from a vector and returns it, or `None` if
-    /// the vector is empty.
-    ///
-    /// # Warning
-    ///
-    /// This is an O(n) operation as it requires copying every element in the
-    /// vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// assert!(vec.shift() == Some(1));
-    /// assert_eq!(vec, vec!(2, 3));
-    /// ```
-    #[inline]
-    pub fn shift(&mut self) -> Option<T> {
-        self.remove(0)
-    }
-
-    /// Insert an element at position `index` within the vector, shifting all
-    /// elements after position i one position to the right.
-    ///
-    /// # Failure
-    ///
-    /// Fails if `index` is out of bounds of the vector.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3);
-    /// vec.insert(1, 4);
-    /// assert_eq!(vec, vec!(1, 4, 2, 3));
-    /// ```
-    pub fn insert(&mut self, index: uint, element: T) {
-        let len = self.len();
-        assert!(index <= len);
-        // space for the new element
-        self.reserve(len + 1);
-
-        unsafe { // infallible
-            // The spot to put the new value
-            {
-                let p = self.as_mut_ptr().offset(index as int);
-                // Shift everything over to make space. (Duplicating the
-                // `index`th element into two consecutive places.)
-                ptr::copy_memory(p.offset(1), &*p, len - index);
-                // Write it in, overwriting the first copy of the `index`th
-                // element.
-                mem::overwrite(&mut *p, element);
-            }
-            self.set_len(len + 1);
-        }
-    }
-
-    /// Remove and return the element at position `index` within the vector,
-    /// shifting all elements after position `index` one position to the left.
-    /// Returns `None` if `i` is out of bounds.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = vec!(1, 2, 3);
-    /// assert_eq!(v.remove(1), Some(2));
-    /// assert_eq!(v, vec!(1, 3));
-    ///
-    /// assert_eq!(v.remove(4), None);
-    /// // v is unchanged:
-    /// assert_eq!(v, vec!(1, 3));
-    /// ```
-    pub fn remove(&mut self, index: uint) -> Option<T> {
-        let len = self.len();
-        if index < len {
-            unsafe { // infallible
-                let ret;
-                {
-                    // the place we are taking from.
-                    let ptr = self.as_mut_ptr().offset(index as int);
-                    // copy it out, unsafely having a copy of the value on
-                    // the stack and in the vector at the same time.
-                    ret = Some(ptr::read(ptr as *T));
-
-                    // Shift everything down to fill in that spot.
-                    ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1);
-                }
-                self.set_len(len - 1);
-                ret
-            }
-        } else {
-            None
-        }
-    }
-
-    /// Takes ownership of the vector `other`, moving all elements into
-    /// the current vector. This does not copy any elements, and it is
-    /// illegal to use the `other` vector after calling this method
-    /// (because it is moved here).
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(box 1);
-    /// vec.push_all_move(vec!(box 2, box 3, box 4));
-    /// assert_eq!(vec, vec!(box 1, box 2, box 3, box 4));
-    /// ```
-    pub fn push_all_move(&mut self, other: Vec<T>) {
-        self.extend(other.move_iter());
-    }
-
-    /// Returns a mutable slice of `self` between `start` and `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` or `end` point outside the bounds of `self`, or when
-    /// `start` > `end`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.mut_slice(0, 2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn mut_slice<'a>(&'a mut self, start: uint, end: uint)
-                         -> &'a mut [T] {
-        self.as_mut_slice().mut_slice(start, end)
-    }
-
-    /// Returns a mutable slice of self from `start` to the end of the vec.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` points outside the bounds of self.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.mut_slice_from(2) == [3, 4]);
-    /// ```
-    #[inline]
-    pub fn mut_slice_from<'a>(&'a mut self, start: uint) -> &'a mut [T] {
-        self.as_mut_slice().mut_slice_from(start)
-    }
-
-    /// Returns a mutable slice of self from the start of the vec to `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `end` points outside the bounds of self.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4);
-    /// assert!(vec.mut_slice_to(2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn mut_slice_to<'a>(&'a mut self, end: uint) -> &'a mut [T] {
-        self.as_mut_slice().mut_slice_to(end)
-    }
-
-    /// Returns a pair of mutable slices that divides the vec at an index.
-    ///
-    /// The first will contain all indices from `[0, mid)` (excluding
-    /// the index `mid` itself) and the second will contain all
-    /// indices from `[mid, len)` (excluding the index `len` itself).
-    ///
-    /// # Failure
-    ///
-    /// Fails if `mid > len`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 3, 4, 5, 6);
-    ///
-    /// // scoped to restrict the lifetime of the borrows
-    /// {
-    ///    let (left, right) = vec.mut_split_at(0);
-    ///    assert!(left == &mut []);
-    ///    assert!(right == &mut [1, 2, 3, 4, 5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = vec.mut_split_at(2);
-    ///     assert!(left == &mut [1, 2]);
-    ///     assert!(right == &mut [3, 4, 5, 6]);
-    /// }
-    ///
-    /// {
-    ///     let (left, right) = vec.mut_split_at(6);
-    ///     assert!(left == &mut [1, 2, 3, 4, 5, 6]);
-    ///     assert!(right == &mut []);
-    /// }
-    /// ```
-    #[inline]
-    pub fn mut_split_at<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) {
-        self.as_mut_slice().mut_split_at(mid)
-    }
-
-    /// Reverse the order of elements in a vector, in place.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut v = vec!(1, 2, 3);
-    /// v.reverse();
-    /// assert_eq!(v, vec!(3, 2, 1));
-    /// ```
-    #[inline]
-    pub fn reverse(&mut self) {
-        self.as_mut_slice().reverse()
-    }
-
-    /// Returns a slice of `self` from `start` to the end of the vec.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `start` points outside the bounds of self.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.slice_from(1) == [2, 3]);
-    /// ```
-    #[inline]
-    pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] {
-        self.as_slice().slice_from(start)
-    }
-
-    /// Returns a slice of self from the start of the vec to `end`.
-    ///
-    /// # Failure
-    ///
-    /// Fails when `end` points outside the bounds of self.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.slice_to(2) == [1, 2]);
-    /// ```
-    #[inline]
-    pub fn slice_to<'a>(&'a self, end: uint) -> &'a [T] {
-        self.as_slice().slice_to(end)
-    }
-
-    /// Returns a slice containing all but the last element of the vector.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the vector is empty
-    #[inline]
-    pub fn init<'a>(&'a self) -> &'a [T] {
-        self.slice(0, self.len() - 1)
-    }
-
-
-    /// Returns an unsafe pointer to the vector's buffer.
-    ///
-    /// The caller must ensure that the vector outlives the pointer this
-    /// function returns, or else it will end up pointing to garbage.
-    ///
-    /// Modifying the vector may cause its buffer to be reallocated, which
-    /// would also make any pointers to it invalid.
-    #[inline]
-    pub fn as_ptr(&self) -> *T {
-        // If we have a 0-sized vector, then the base pointer should not be NULL
-        // because an iterator over the slice will attempt to yield the base
-        // pointer as the first element in the vector, but this will end up
-        // being Some(NULL) which is optimized to None.
-        if mem::size_of::<T>() == 0 {
-            1 as *T
-        } else {
-            self.ptr as *T
-        }
-    }
-
-    /// Returns a mutable unsafe pointer to the vector's buffer.
-    ///
-    /// The caller must ensure that the vector outlives the pointer this
-    /// function returns, or else it will end up pointing to garbage.
-    ///
-    /// Modifying the vector may cause its buffer to be reallocated, which
-    /// would also make any pointers to it invalid.
-    #[inline]
-    pub fn as_mut_ptr(&mut self) -> *mut T {
-        // see above for the 0-size check
-        if mem::size_of::<T>() == 0 {
-            1 as *mut T
-        } else {
-            self.ptr
-        }
-    }
-
-    /// Retains only the elements specified by the predicate.
-    ///
-    /// In other words, remove all elements `e` such that `f(&e)` returns false.
-    /// This method operates in place and preserves the order the retained elements.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1i, 2, 3, 4);
-    /// vec.retain(|x| x%2 == 0);
-    /// assert_eq!(vec, vec!(2, 4));
-    /// ```
-    pub fn retain(&mut self, f: |&T| -> bool) {
-        let len = self.len();
-        let mut del = 0u;
-        {
-            let v = self.as_mut_slice();
-
-            for i in range(0u, len) {
-                if !f(&v[i]) {
-                    del += 1;
-                } else if del > 0 {
-                    v.swap(i-del, i);
-                }
-            }
-        }
-        if del > 0 {
-            self.truncate(len - del);
-        }
-    }
-
-    /// Expands a vector in place, initializing the new elements to the result of a function.
-    ///
-    /// The vector is grown by `n` elements. The i-th new element are initialized to the value
-    /// returned by `f(i)` where `i` is in the range [0, n).
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(0u, 1);
-    /// vec.grow_fn(3, |i| i);
-    /// assert_eq!(vec, vec!(0, 1, 0, 1, 2));
-    /// ```
-    pub fn grow_fn(&mut self, n: uint, f: |uint| -> T) {
-        self.reserve_additional(n);
-        for i in range(0u, n) {
-            self.push(f(i));
-        }
-    }
-}
-
-impl<T:Ord> Vec<T> {
-    /// Sorts the vector in place.
-    ///
-    /// This sort is `O(n log n)` worst-case and stable, but allocates
-    /// approximately `2 * n`, where `n` is the length of `self`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(3i, 1, 2);
-    /// vec.sort();
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    pub fn sort(&mut self) {
-        self.as_mut_slice().sort()
-    }
-}
-
-impl<T> Mutable for Vec<T> {
-    #[inline]
-    fn clear(&mut self) {
-        self.truncate(0)
-    }
-}
-
-impl<T:PartialEq> Vec<T> {
-    /// Return true if a vector contains an element with the given value
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let vec = vec!(1, 2, 3);
-    /// assert!(vec.contains(&1));
-    /// ```
-    pub fn contains(&self, x: &T) -> bool {
-        self.as_slice().contains(x)
-    }
-
-    /// Remove consecutive repeated elements in the vector.
-    ///
-    /// If the vector is sorted, this removes all duplicates.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1, 2, 2, 3, 2);
-    /// vec.dedup();
-    /// assert_eq!(vec, vec!(1, 2, 3, 2));
-    /// ```
-    pub fn dedup(&mut self) {
-        unsafe {
-            // Although we have a mutable reference to `self`, we cannot make
-            // *arbitrary* changes. The `PartialEq` comparisons could fail, so we
-            // must ensure that the vector is in a valid state at all time.
-            //
-            // The way that we handle this is by using swaps; we iterate
-            // over all the elements, swapping as we go so that at the end
-            // the elements we wish to keep are in the front, and those we
-            // wish to reject are at the back. We can then truncate the
-            // vector. This operation is still O(n).
-            //
-            // Example: We start in this state, where `r` represents "next
-            // read" and `w` represents "next_write`.
-            //
-            //           r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //           w
-            //
-            // Comparing self[r] against self[w-1], this is not a duplicate, so
-            // we swap self[r] and self[w] (no effect as r==w) and then increment both
-            // r and w, leaving us with:
-            //
-            //               r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //               w
-            //
-            // Comparing self[r] against self[w-1], this value is a duplicate,
-            // so we increment `r` but leave everything else unchanged:
-            //
-            //                   r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //               w
-            //
-            // Comparing self[r] against self[w-1], this is not a duplicate,
-            // so swap self[r] and self[w] and advance r and w:
-            //
-            //                       r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 2 | 1 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //                   w
-            //
-            // Not a duplicate, repeat:
-            //
-            //                           r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 2 | 3 | 1 | 3 |
-            //     +---+---+---+---+---+---+
-            //                       w
-            //
-            // Duplicate, advance r. End of vec. Truncate to w.
-
-            let ln = self.len();
-            if ln < 1 { return; }
-
-            // Avoid bounds checks by using unsafe pointers.
-            let p = self.as_mut_slice().as_mut_ptr();
-            let mut r = 1;
-            let mut w = 1;
-
-            while r < ln {
-                let p_r = p.offset(r as int);
-                let p_wm1 = p.offset((w - 1) as int);
-                if *p_r != *p_wm1 {
-                    if r != w {
-                        let p_w = p_wm1.offset(1);
-                        mem::swap(&mut *p_r, &mut *p_w);
-                    }
-                    w += 1;
-                }
-                r += 1;
-            }
-
-            self.truncate(w);
-        }
-    }
-}
-
-impl<T> Vector<T> for Vec<T> {
-    /// Work with `self` as a slice.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// fn foo(slice: &[int]) {}
-    ///
-    /// let vec = vec!(1, 2);
-    /// foo(vec.as_slice());
-    /// ```
-    #[inline]
-    fn as_slice<'a>(&'a self) -> &'a [T] {
-        unsafe { mem::transmute(Slice { data: self.as_ptr(), len: self.len }) }
-    }
-}
-
-impl<T: Clone, V: Vector<T>> Add<V, Vec<T>> for Vec<T> {
-    #[inline]
-    fn add(&self, rhs: &V) -> Vec<T> {
-        let mut res = Vec::with_capacity(self.len() + rhs.as_slice().len());
-        res.push_all(self.as_slice());
-        res.push_all(rhs.as_slice());
-        res
-    }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for Vec<T> {
-    fn drop(&mut self) {
-        // This is (and should always remain) a no-op if the fields are
-        // zeroed (when moving out, because of #[unsafe_no_drop_flag]).
-        if self.cap != 0 {
-            unsafe {
-                for x in self.as_mut_slice().iter() {
-                    ptr::read(x);
-                }
-                dealloc(self.ptr, self.cap)
-            }
-        }
-    }
-}
-
-impl<T> Default for Vec<T> {
-    fn default() -> Vec<T> {
-        Vec::new()
-    }
-}
-
-impl<T:fmt::Show> fmt::Show for Vec<T> {
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        self.as_slice().fmt(f)
-    }
-}
-
-/// An iterator that moves out of a vector.
-pub struct MoveItems<T> {
-    allocation: *mut T, // the block of memory allocated for the vector
-    cap: uint, // the capacity of the vector
-    iter: Items<'static, T>
-}
-
-impl<T> Iterator<T> for MoveItems<T> {
-    #[inline]
-    fn next(&mut self) -> Option<T> {
-        unsafe {
-            self.iter.next().map(|x| ptr::read(x))
-        }
-    }
-
-    #[inline]
-    fn size_hint(&self) -> (uint, Option<uint>) {
-        self.iter.size_hint()
-    }
-}
-
-impl<T> DoubleEndedIterator<T> for MoveItems<T> {
-    #[inline]
-    fn next_back(&mut self) -> Option<T> {
-        unsafe {
-            self.iter.next_back().map(|x| ptr::read(x))
-        }
-    }
-}
-
-#[unsafe_destructor]
-impl<T> Drop for MoveItems<T> {
-    fn drop(&mut self) {
-        // destroy the remaining elements
-        if self.cap != 0 {
-            for _x in *self {}
-            unsafe {
-                dealloc(self.allocation, self.cap);
-            }
-        }
-    }
-}
-
-/**
- * Convert an iterator of pairs into a pair of vectors.
- *
- * Returns a tuple containing two vectors where the i-th element of the first
- * vector contains the first element of the i-th tuple of the input iterator,
- * and the i-th element of the second vector contains the second element
- * of the i-th tuple of the input iterator.
- */
-pub fn unzip<T, U, V: Iterator<(T, U)>>(mut iter: V) -> (Vec<T>, Vec<U>) {
-    let (lo, _) = iter.size_hint();
-    let mut ts = Vec::with_capacity(lo);
-    let mut us = Vec::with_capacity(lo);
-    for (t, u) in iter {
-        ts.push(t);
-        us.push(u);
-    }
-    (ts, us)
-}
-
-/// Mechanism to convert from a `Vec<T>` to a `[T]`.
-///
-/// In a post-DST world this will be used to convert to any `Ptr<[T]>`.
-///
-/// This could be implemented on more types than just pointers to vectors, but
-/// the recommended approach for those types is to implement `FromIterator`.
-// FIXME(#12938): Update doc comment when DST lands
-pub trait FromVec<T> {
-    /// Convert a `Vec<T>` into the receiver type.
-    fn from_vec(v: Vec<T>) -> Self;
-}
-
-impl<T> FromVec<T> for ~[T] {
-    fn from_vec(mut v: Vec<T>) -> ~[T] {
-        let len = v.len();
-        let data_size = len.checked_mul(&mem::size_of::<T>());
-        let data_size = data_size.expect("overflow in from_vec()");
-        let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
-        let size = size.expect("overflow in from_vec()");
-
-        // In a post-DST world, we can attempt to reuse the Vec allocation by calling
-        // shrink_to_fit() on it. That may involve a reallocation+memcpy, but that's no
-        // diffrent than what we're doing manually here.
-
-        let vp = v.as_mut_ptr();
-
-        unsafe {
-            let ret = allocate(size, 8) as *mut RawVec<()>;
-
-            let a_size = mem::size_of::<T>();
-            let a_size = if a_size == 0 {1} else {a_size};
-            (*ret).fill = len * a_size;
-            (*ret).alloc = len * a_size;
-
-            ptr::copy_nonoverlapping_memory(&mut (*ret).data as *mut _ as *mut u8,
-                                            vp as *u8, data_size);
-
-            // we've transferred ownership of the contents from v, but we can't drop it
-            // as it still needs to free its own allocation.
-            v.set_len(0);
-
-            mem::transmute(ret)
-        }
-    }
-}
-
-/// Unsafe operations
-pub mod raw {
-    use super::Vec;
-    use ptr;
-
-    /// Constructs a vector from an unsafe pointer to a buffer.
-    ///
-    /// The elements of the buffer are copied into the vector without cloning,
-    /// as if `ptr::read()` were called on them.
-    #[inline]
-    pub unsafe fn from_buf<T>(ptr: *T, elts: uint) -> Vec<T> {
-        let mut dst = Vec::with_capacity(elts);
-        dst.set_len(elts);
-        ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(), ptr, elts);
-        dst
-    }
-}
-
-
-#[cfg(test)]
-mod tests {
-    use prelude::*;
-    use mem::size_of;
-    use kinds::marker;
-    use super::{unzip, raw, FromVec};
-
-    #[test]
-    fn test_small_vec_struct() {
-        assert!(size_of::<Vec<u8>>() == size_of::<uint>() * 3);
-    }
-
-    #[test]
-    fn test_double_drop() {
-        struct TwoVec<T> {
-            x: Vec<T>,
-            y: Vec<T>
-        }
-
-        struct DropCounter<'a> {
-            count: &'a mut int
-        }
-
-        #[unsafe_destructor]
-        impl<'a> Drop for DropCounter<'a> {
-            fn drop(&mut self) {
-                *self.count += 1;
-            }
-        }
-
-        let mut count_x @ mut count_y = 0;
-        {
-            let mut tv = TwoVec {
-                x: Vec::new(),
-                y: Vec::new()
-            };
-            tv.x.push(DropCounter {count: &mut count_x});
-            tv.y.push(DropCounter {count: &mut count_y});
-
-            // If Vec had a drop flag, here is where it would be zeroed.
-            // Instead, it should rely on its internal state to prevent
-            // doing anything significant when dropped multiple times.
-            drop(tv.x);
-
-            // Here tv goes out of scope, tv.y should be dropped, but not tv.x.
-        }
-
-        assert_eq!(count_x, 1);
-        assert_eq!(count_y, 1);
-    }
-
-    #[test]
-    fn test_reserve_additional() {
-        let mut v = Vec::new();
-        assert_eq!(v.capacity(), 0);
-
-        v.reserve_additional(2);
-        assert!(v.capacity() >= 2);
-
-        for i in range(0, 16) {
-            v.push(i);
-        }
-
-        assert!(v.capacity() >= 16);
-        v.reserve_additional(16);
-        assert!(v.capacity() >= 32);
-
-        v.push(16);
-
-        v.reserve_additional(16);
-        assert!(v.capacity() >= 33)
-    }
-
-    #[test]
-    fn test_extend() {
-        let mut v = Vec::new();
-        let mut w = Vec::new();
-
-        v.extend(range(0, 3));
-        for i in range(0, 3) { w.push(i) }
-
-        assert_eq!(v, w);
-
-        v.extend(range(3, 10));
-        for i in range(3, 10) { w.push(i) }
-
-        assert_eq!(v, w);
-    }
-
-    #[test]
-    fn test_mut_slice_from() {
-        let mut values = Vec::from_slice([1u8,2,3,4,5]);
-        {
-            let slice = values.mut_slice_from(2);
-            assert!(slice == [3, 4, 5]);
-            for p in slice.mut_iter() {
-                *p += 2;
-            }
-        }
-
-        assert!(values.as_slice() == [1, 2, 5, 6, 7]);
-    }
-
-    #[test]
-    fn test_mut_slice_to() {
-        let mut values = Vec::from_slice([1u8,2,3,4,5]);
-        {
-            let slice = values.mut_slice_to(2);
-            assert!(slice == [1, 2]);
-            for p in slice.mut_iter() {
-                *p += 1;
-            }
-        }
-
-        assert!(values.as_slice() == [2, 3, 3, 4, 5]);
-    }
-
-    #[test]
-    fn test_mut_split_at() {
-        let mut values = Vec::from_slice([1u8,2,3,4,5]);
-        {
-            let (left, right) = values.mut_split_at(2);
-            assert!(left.slice(0, left.len()) == [1, 2]);
-            for p in left.mut_iter() {
-                *p += 1;
-            }
-
-            assert!(right.slice(0, right.len()) == [3, 4, 5]);
-            for p in right.mut_iter() {
-                *p += 2;
-            }
-        }
-
-        assert!(values == Vec::from_slice([2u8, 3, 5, 6, 7]));
-    }
-
-    #[test]
-    fn test_clone() {
-        let v: Vec<int> = vec!();
-        let w = vec!(1, 2, 3);
-
-        assert_eq!(v, v.clone());
-
-        let z = w.clone();
-        assert_eq!(w, z);
-        // they should be disjoint in memory.
-        assert!(w.as_ptr() != z.as_ptr())
-    }
-
-    #[test]
-    fn test_clone_from() {
-        let mut v = vec!();
-        let three = vec!(box 1, box 2, box 3);
-        let two = vec!(box 4, box 5);
-        // zero, long
-        v.clone_from(&three);
-        assert_eq!(v, three);
-
-        // equal
-        v.clone_from(&three);
-        assert_eq!(v, three);
-
-        // long, short
-        v.clone_from(&two);
-        assert_eq!(v, two);
-
-        // short, long
-        v.clone_from(&three);
-        assert_eq!(v, three)
-    }
-
-    #[test]
-    fn test_grow_fn() {
-        let mut v = Vec::from_slice([0u, 1]);
-        v.grow_fn(3, |i| i);
-        assert!(v == Vec::from_slice([0u, 1, 0, 1, 2]));
-    }
-
-    #[test]
-    fn test_retain() {
-        let mut vec = Vec::from_slice([1u, 2, 3, 4]);
-        vec.retain(|x| x%2 == 0);
-        assert!(vec == Vec::from_slice([2u, 4]));
-    }
-
-    #[test]
-    fn zero_sized_values() {
-        let mut v = Vec::new();
-        assert_eq!(v.len(), 0);
-        v.push(());
-        assert_eq!(v.len(), 1);
-        v.push(());
-        assert_eq!(v.len(), 2);
-        assert_eq!(v.pop(), Some(()));
-        assert_eq!(v.pop(), Some(()));
-        assert_eq!(v.pop(), None);
-
-        assert_eq!(v.iter().len(), 0);
-        v.push(());
-        assert_eq!(v.iter().len(), 1);
-        v.push(());
-        assert_eq!(v.iter().len(), 2);
-
-        for &() in v.iter() {}
-
-        assert_eq!(v.mut_iter().len(), 2);
-        v.push(());
-        assert_eq!(v.mut_iter().len(), 3);
-        v.push(());
-        assert_eq!(v.mut_iter().len(), 4);
-
-        for &() in v.mut_iter() {}
-        unsafe { v.set_len(0); }
-        assert_eq!(v.mut_iter().len(), 0);
-    }
-
-    #[test]
-    fn test_partition() {
-        assert_eq!(vec![].partition(|x: &int| *x < 3), (vec![], vec![]));
-        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
-        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 2), (vec![1], vec![2, 3]));
-        assert_eq!(vec![1, 2, 3].partition(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
-    }
-
-    #[test]
-    fn test_partitioned() {
-        assert_eq!(vec![].partitioned(|x: &int| *x < 3), (vec![], vec![]))
-        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 4), (vec![1, 2, 3], vec![]));
-        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 2), (vec![1], vec![2, 3]));
-        assert_eq!(vec![1, 2, 3].partitioned(|x: &int| *x < 0), (vec![], vec![1, 2, 3]));
-    }
-
-    #[test]
-    fn test_zip_unzip() {
-        let z1 = vec![(1, 4), (2, 5), (3, 6)];
-
-        let (left, right) = unzip(z1.iter().map(|&x| x));
-
-        let (left, right) = (left.as_slice(), right.as_slice());
-        assert_eq!((1, 4), (left[0], right[0]));
-        assert_eq!((2, 5), (left[1], right[1]));
-        assert_eq!((3, 6), (left[2], right[2]));
-    }
-
-    #[test]
-    fn test_unsafe_ptrs() {
-        unsafe {
-            // Test on-stack copy-from-buf.
-            let a = [1, 2, 3];
-            let ptr = a.as_ptr();
-            let b = raw::from_buf(ptr, 3u);
-            assert_eq!(b, vec![1, 2, 3]);
-
-            // Test on-heap copy-from-buf.
-            let c = box [1, 2, 3, 4, 5];
-            let ptr = c.as_ptr();
-            let d = raw::from_buf(ptr, 5u);
-            assert_eq!(d, vec![1, 2, 3, 4, 5]);
-        }
-    }
-
-    #[test]
-    fn test_from_vec() {
-        let a = vec![1u, 2, 3];
-        let b: ~[uint] = FromVec::from_vec(a);
-        assert_eq!(b.as_slice(), &[1u, 2, 3]);
-
-        let a = vec![];
-        let b: ~[u8] = FromVec::from_vec(a);
-        assert_eq!(b.as_slice(), &[]);
-
-        let a = vec!["one".to_string(), "two".to_string()];
-        let b: ~[String] = FromVec::from_vec(a);
-        assert_eq!(b.as_slice(), &["one".to_string(), "two".to_string()]);
-
-        struct Foo {
-            x: uint,
-            nocopy: marker::NoCopy
-        }
-
-        let a = vec![Foo{x: 42, nocopy: marker::NoCopy}, Foo{x: 84, nocopy: marker::NoCopy}];
-        let b: ~[Foo] = FromVec::from_vec(a);
-        assert_eq!(b.len(), 2);
-        assert_eq!(b[0].x, 42);
-        assert_eq!(b[1].x, 84);
-    }
-
-    #[test]
-    fn test_vec_truncate_drop() {
-        static mut drops: uint = 0;
-        struct Elem(int);
-        impl Drop for Elem {
-            fn drop(&mut self) {
-                unsafe { drops += 1; }
-            }
-        }
-
-        let mut v = vec![Elem(1), Elem(2), Elem(3), Elem(4), Elem(5)];
-        assert_eq!(unsafe { drops }, 0);
-        v.truncate(3);
-        assert_eq!(unsafe { drops }, 2);
-        v.truncate(0);
-        assert_eq!(unsafe { drops }, 5);
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_vec_truncate_fail() {
-        struct BadElem(int);
-        impl Drop for BadElem {
-            fn drop(&mut self) {
-                let BadElem(ref mut x) = *self;
-                if *x == 0xbadbeef {
-                    fail!("BadElem failure: 0xbadbeef")
-                }
-            }
-        }
-
-        let mut v = vec![BadElem(1), BadElem(2), BadElem(0xbadbeef), BadElem(4)];
-        v.truncate(0);
-    }
-}