diff --git a/mk/crates.mk b/mk/crates.mk index 9b252267aba..cea9133e835 100644 --- a/mk/crates.mk +++ b/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 diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index c91a5289faa..6cd3616fc71 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -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 { diff --git a/src/libcollections/btree.rs b/src/libcollections/btree.rs index cebf21ee7e7..d589aa73a52 100644 --- a/src/libcollections/btree.rs +++ b/src/libcollections/btree.rs @@ -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> { diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs index fa2cb233873..b4930173bb6 100644 --- a/src/libcollections/deque.rs +++ b/src/libcollections/deque.rs @@ -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 { diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 014d4e680ee..062e94d21c0 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -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; diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs index 78485321aa5..856aff64b6a 100644 --- a/src/libcollections/enum_set.rs +++ b/src/libcollections/enum_set.rs @@ -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/libstd/hash/mod.rs b/src/libcollections/hash/mod.rs similarity index 93% rename from src/libstd/hash/mod.rs rename to src/libcollections/hash/mod.rs index 8e95263d48e..067f266f63f 100644 --- a/src/libstd/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -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) } } diff --git a/src/libstd/hash/sip.rs b/src/libcollections/hash/sip.rs similarity index 88% rename from src/libstd/hash/sip.rs rename to src/libcollections/hash/sip.rs index 90767908612..039aee7347b 100644 --- a/src/libstd/hash/sip.rs +++ b/src/libcollections/hash/sip.rs @@ -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 { diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index d1c75b89579..0ac26e686cd 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -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) +} diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs new file mode 100644 index 00000000000..db062a70bbb --- /dev/null +++ b/src/libcollections/macros.rs @@ -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),+)) +) diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index d73c07ee17d..d40051faf13 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -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)] diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs index 7b8d416c4fe..713888cf473 100644 --- a/src/libcollections/ringbuf.rs +++ b/src/libcollections/ringbuf.rs @@ -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, "[")); diff --git a/src/libstd/slice.rs b/src/libcollections/slice.rs similarity index 99% rename from src/libstd/slice.rs rename to src/libcollections/slice.rs index d6f63da09f2..a724307a70e 100644 --- a/src/libstd/slice.rs +++ b/src/libcollections/slice.rs @@ -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 diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs index 932011baa56..c284a73d8bc 100644 --- a/src/libcollections/smallintmap.rs +++ b/src/libcollections/smallintmap.rs @@ -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. diff --git a/src/libstd/str.rs b/src/libcollections/str.rs similarity index 98% rename from src/libstd/str.rs rename to src/libcollections/str.rs index 3af3821486f..144f14acdcd 100644 --- a/src/libstd/str.rs +++ b/src/libcollections/str.rs @@ -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; diff --git a/src/libstd/string.rs b/src/libcollections/string.rs similarity index 94% rename from src/libstd/string.rs rename to src/libcollections/string.rs index 80973bb5328..764811e92c7 100644 --- a/src/libstd/string.rs +++ b/src/libcollections/string.rs @@ -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; diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 1184c9b7b52..1fd9fce2089 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -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 diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs index e6df4fd87e1..a70b466623f 100644 --- a/src/libcollections/trie.rs +++ b/src/libcollections/trie.rs @@ -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"), } } diff --git a/src/libstd/unicode.rs b/src/libcollections/unicode.rs similarity index 98% rename from src/libstd/unicode.rs rename to src/libcollections/unicode.rs index 03c960e96ff..440290164c3 100644 --- a/src/libstd/unicode.rs +++ b/src/libcollections/unicode.rs @@ -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 } diff --git a/src/libstd/vec.rs b/src/libcollections/vec.rs similarity index 97% rename from src/libstd/vec.rs rename to src/libcollections/vec.rs index cdcee9464de..faa9db7c919 100644 --- a/src/libstd/vec.rs +++ b/src/libcollections/vec.rs @@ -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. /// diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index f6c438698b4..eef133181e1 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -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 { diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index f41efdbc1db..2cce68d5f60 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -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; diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 6474c5e37a4..94901aff001 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -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/libcollections/hashmap.rs b/src/libstd/collections/hashmap.rs similarity index 97% rename from src/libcollections/hashmap.rs rename to src/libstd/collections/hashmap.rs index dfcb85a3e39..bcf6d139c35 100644 --- a/src/libcollections/hashmap.rs +++ b/src/libstd/collections/hashmap.rs @@ -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 diff --git a/src/libcollections/lru_cache.rs b/src/libstd/collections/lru_cache.rs similarity index 97% rename from src/libcollections/lru_cache.rs rename to src/libstd/collections/lru_cache.rs index ea25eee06d0..09511316a67 100644 --- a/src/libcollections/lru_cache.rs +++ b/src/libstd/collections/lru_cache.rs @@ -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 } diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs new file mode 100644 index 00000000000..16a6a35d9d5 --- /dev/null +++ b/src/libstd/collections/mod.rs @@ -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; diff --git a/src/libstd/from_str.rs b/src/libstd/from_str.rs index 62bb8e4d969..4394fb9d355 100644 --- a/src/libstd/from_str.rs +++ b/src/libstd/from_str.rs @@ -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::*; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index db84a724adb..90d6677d612 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -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] diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index a6bbf22b401..8dfb64194e7 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -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) diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 865e53cbe38..e53842ecd8f 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -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) {