std: Recreate a collections
module
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]
This commit is contained in:
parent
d70a9b93d0
commit
6a585375a0
23
mk/crates.mk
23
mk/crates.mk
@ -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
|
||||
|
@ -10,14 +10,17 @@
|
||||
|
||||
#![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 {
|
||||
|
@ -18,8 +18,13 @@
|
||||
///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> {
|
||||
|
@ -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 {
|
||||
|
@ -21,9 +21,12 @@
|
||||
// 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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -63,22 +63,17 @@
|
||||
|
||||
#![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 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 use Writer = io::Writer;
|
||||
|
||||
pub mod sip;
|
||||
|
||||
/// A trait that represents a hashable type. The `S` type parameter is an
|
||||
@ -96,33 +91,29 @@ pub trait Hasher<S> {
|
||||
fn hash<T: Hash<S>>(&self, value: &T) -> u64;
|
||||
}
|
||||
|
||||
pub trait Writer {
|
||||
fn write(&mut self, bytes: &[u8]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
macro_rules! impl_hash(
|
||||
( $( $ty:ty => $method:ident;)* ) => (
|
||||
( $($ty:ident)* ) => (
|
||||
$(
|
||||
impl<S: Writer> Hash<S> for $ty {
|
||||
#[inline]
|
||||
fn hash(&self, state: &mut S) {
|
||||
state.$method(*self);
|
||||
let a: [u8, ..::core::$ty::BYTES] = unsafe {
|
||||
::core::mem::transmute(*self)
|
||||
};
|
||||
state.write(a.as_slice())
|
||||
}
|
||||
}
|
||||
)*
|
||||
)
|
||||
)
|
||||
|
||||
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_hash!( u8 u16 u32 u64 uint i8 i16 i32 i64 int )
|
||||
|
||||
impl<S: Writer> Hash<S> for bool {
|
||||
#[inline]
|
||||
@ -142,7 +133,7 @@ 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);
|
||||
0xffu8.hash(state)
|
||||
}
|
||||
}
|
||||
|
@ -24,17 +24,11 @@
|
||||
* 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 core::prelude::*;
|
||||
|
||||
use super::{Hash, Hasher};
|
||||
use core::default::Default;
|
||||
|
||||
use super::{Hash, Hasher, Writer};
|
||||
|
||||
/// `SipState` computes a SipHash 2-4 hash over a stream of bytes.
|
||||
pub struct SipState {
|
||||
@ -151,41 +145,11 @@ impl SipState {
|
||||
|
||||
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<()> {
|
||||
fn write(&mut self, msg: &[u8]) {
|
||||
let length = msg.len();
|
||||
self.length += length;
|
||||
|
||||
@ -196,7 +160,7 @@ impl Writer for SipState {
|
||||
if length < needed {
|
||||
self.tail |= u8to64_le!(msg, 0, length) << 8*self.ntail;
|
||||
self.ntail += length;
|
||||
return Ok(());
|
||||
return
|
||||
}
|
||||
|
||||
let m = self.tail | u8to64_le!(msg, 0, needed) << 8*self.ntail;
|
||||
@ -228,60 +192,7 @@ impl Writer for SipState {
|
||||
|
||||
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 {
|
@ -14,43 +14,66 @@
|
||||
|
||||
#![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)
|
||||
}
|
||||
|
22
src/libcollections/macros.rs
Normal file
22
src/libcollections/macros.rs
Normal file
@ -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),+))
|
||||
)
|
@ -12,10 +12,12 @@
|
||||
|
||||
#![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)]
|
||||
|
@ -13,12 +13,14 @@
|
||||
//! 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 @@ impl<A> Extendable<A> for RingBuf<A> {
|
||||
}
|
||||
}
|
||||
|
||||
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, "["));
|
||||
|
||||
|
@ -99,20 +99,16 @@ There are a number of free functions that create or take vectors, for example:
|
||||
|
||||
#![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 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};
|
||||
@ -295,13 +291,13 @@ impl<'a, T: Clone> CloneableVector<T> for &'a [T] {
|
||||
#[inline]
|
||||
fn to_owned(&self) -> ~[T] {
|
||||
use RawVec = core::raw::Vec;
|
||||
use num::{CheckedAdd, CheckedMul};
|
||||
use core::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 data_size = ::expect(data_size, "overflow in to_owned()");
|
||||
let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
|
||||
let size = size.expect("overflow in to_owned()");
|
||||
let size = ::expect(size, "overflow in to_owned()");
|
||||
|
||||
unsafe {
|
||||
// this should pass the real required alignment
|
@ -15,9 +15,13 @@
|
||||
|
||||
#![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 @@ impl<V> 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.
|
||||
|
@ -67,21 +67,17 @@ 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 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;
|
||||
|
||||
@ -201,9 +197,6 @@ 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;
|
||||
@ -638,13 +631,10 @@ impl<'a> Default for MaybeOwned<'a> {
|
||||
fn default() -> MaybeOwned<'a> { Slice("") }
|
||||
}
|
||||
|
||||
impl<'a, H: Writer> ::hash::Hash<H> for MaybeOwned<'a> {
|
||||
impl<'a, H: hash::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),
|
||||
}
|
||||
self.as_slice().hash(hasher)
|
||||
}
|
||||
}
|
||||
|
||||
@ -660,10 +650,10 @@ impl<'a> fmt::Show for MaybeOwned<'a> {
|
||||
|
||||
/// Unsafe operations
|
||||
pub mod raw {
|
||||
use c_str::CString;
|
||||
use libc;
|
||||
use mem;
|
||||
use raw::Slice;
|
||||
use core::prelude::*;
|
||||
use core::mem;
|
||||
use core::raw::Slice;
|
||||
|
||||
use string::String;
|
||||
use vec::Vec;
|
||||
|
||||
@ -681,9 +671,16 @@ pub mod raw {
|
||||
}
|
||||
|
||||
/// Create a Rust string from a null-terminated C string
|
||||
pub unsafe fn from_c_str(c_string: *libc::c_char) -> String {
|
||||
pub unsafe fn from_c_str(c_string: *i8) -> String {
|
||||
let mut buf = String::new();
|
||||
buf.push_bytes(CString::new(c_string, false).as_bytes_no_nul());
|
||||
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
|
||||
}
|
||||
|
||||
@ -800,10 +797,8 @@ pub trait StrAllocating: Str {
|
||||
#[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()))
|
||||
mem::transmute(Vec::from_slice(self.as_slice().as_bytes()))
|
||||
}
|
||||
}
|
||||
|
||||
@ -852,9 +847,9 @@ pub trait StrAllocating: Str {
|
||||
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;
|
||||
*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;
|
@ -10,23 +10,17 @@
|
||||
|
||||
//! 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 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.
|
||||
@ -168,14 +162,17 @@ impl 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);
|
||||
// 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 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());
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -340,7 +337,7 @@ impl fmt::Show for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl<H:Writer> ::hash::Hash<H> for String {
|
||||
impl<H: hash::Writer> hash::Hash<H> for String {
|
||||
#[inline]
|
||||
fn hash(&self, hasher: &mut H) {
|
||||
self.as_slice().hash(hasher)
|
||||
@ -354,13 +351,6 @@ impl<'a, S: Str> Equiv<S> for String {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for String {
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Option<String> {
|
||||
Some(s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
extern crate test;
|
@ -12,13 +12,17 @@
|
||||
//! 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
|
||||
|
@ -10,11 +10,15 @@
|
||||
|
||||
//! 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"),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,11 +13,9 @@
|
||||
#![allow(missing_doc, non_uppercase_statics)]
|
||||
|
||||
pub mod normalization {
|
||||
use option::{Some, None};
|
||||
use slice::ImmutableVector;
|
||||
use core::prelude::*;
|
||||
|
||||
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 }
|
@ -10,25 +10,22 @@
|
||||
|
||||
//! 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};
|
||||
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.
|
||||
///
|
||||
@ -90,12 +87,12 @@ impl<T> Vec<T> {
|
||||
/// ```
|
||||
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 }
|
||||
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 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 }
|
||||
}
|
||||
@ -503,8 +500,8 @@ impl<T> Vec<T> {
|
||||
if mem::size_of::<T>() == 0 { return }
|
||||
|
||||
if capacity > self.cap {
|
||||
let size = capacity.checked_mul(&mem::size_of::<T>())
|
||||
.expect("capacity overflow");
|
||||
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>());
|
||||
@ -583,7 +580,7 @@ impl<T> Vec<T> {
|
||||
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");
|
||||
self.len = ::expect(self.len.checked_add(&1), "length overflow");
|
||||
unsafe { mem::forget(value); }
|
||||
return
|
||||
}
|
||||
@ -1530,9 +1527,9 @@ 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 data_size = ::expect(data_size, "overflow in from_vec()");
|
||||
let size = mem::size_of::<RawVec<()>>().checked_add(&data_size);
|
||||
let size = size.expect("overflow in from_vec()");
|
||||
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
|
||||
@ -1563,7 +1560,7 @@ impl<T> FromVec<T> for ~[T] {
|
||||
/// Unsafe operations
|
||||
pub mod raw {
|
||||
use super::Vec;
|
||||
use ptr;
|
||||
use core::ptr;
|
||||
|
||||
/// Constructs a vector from an unsafe pointer to a buffer.
|
||||
///
|
@ -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 {
|
||||
|
@ -31,12 +31,6 @@ pub use self::num::radix;
|
||||
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;
|
||||
|
@ -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)*)
|
||||
})
|
||||
)
|
||||
|
@ -10,40 +10,39 @@
|
||||
|
||||
//! 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;
|
||||
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 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};
|
||||
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;
|
||||
|
||||
@ -217,12 +216,12 @@ mod table {
|
||||
/// 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");
|
||||
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,
|
||||
@ -339,8 +338,8 @@ mod table {
|
||||
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);
|
||||
overwrite(&mut *self.keys.offset(idx), k);
|
||||
overwrite(&mut *self.vals.offset(idx), v);
|
||||
}
|
||||
|
||||
self.size += 1;
|
||||
@ -519,8 +518,8 @@ mod table {
|
||||
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());
|
||||
overwrite(&mut *new_ht.keys.offset(i as int), (*k).clone());
|
||||
overwrite(&mut *new_ht.vals.offset(i as int), (*v).clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1037,6 +1036,7 @@ impl<K: Hash + Eq, V> 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();
|
||||
@ -1047,6 +1047,9 @@ impl<K: Hash + Eq, V> HashMap<K, V, sip::SipHasher> {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
@ -1326,7 +1329,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
||||
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)
|
||||
None => fail!("no entry found for key")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1334,7 +1337,7 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
|
||||
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)
|
||||
None => fail!("no entry found for key")
|
||||
}
|
||||
}
|
||||
|
||||
@ -1533,6 +1536,10 @@ impl<T: Hash + Eq> HashSet<T, sip::SipHasher> {
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
@ -1632,8 +1639,10 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S> + Default> Extendable<T> for HashSet<T, H>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq + Hash> Default for HashSet<T, sip::SipHasher> {
|
||||
fn default() -> HashSet<T> { HashSet::new() }
|
||||
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
|
@ -37,13 +37,18 @@
|
||||
//! 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;
|
||||
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 }
|
||||
|
25
src/libstd/collections/mod.rs
Normal file
25
src/libstd/collections/mod.rs
Normal file
@ -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;
|
@ -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 @@ impl FromStr for bool {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for String {
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Option<String> {
|
||||
Some(s.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use prelude::*;
|
||||
|
@ -124,6 +124,7 @@ extern crate alloc;
|
||||
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";
|
||||
@ -160,6 +161,12 @@ pub use core::option;
|
||||
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 @@ pub mod prelude;
|
||||
#[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 @@ pub mod gc;
|
||||
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 @@ pub mod cleanup;
|
||||
#[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]
|
||||
|
@ -10,16 +10,17 @@
|
||||
|
||||
//! 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 @@ impl<'a> ToCStr for &'a Path {
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -16,6 +16,7 @@ use clone::Clone;
|
||||
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 @@ impl<'a> ToCStr for &'a Path {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user