diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 9b4f879e61e..27174de8e74 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -268,6 +268,7 @@ impl Drop for Weak { #[allow(experimental)] mod tests { use std::clone::Clone; + use std::collections::MutableSeq; use std::comm::channel; use std::mem::drop; use std::ops::Drop; diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs index f1e9eabe8d1..e7190a810e4 100644 --- a/src/libcollections/bitv.rs +++ b/src/libcollections/bitv.rs @@ -72,7 +72,7 @@ use core::slice; use core::uint; use std::hash; -use {Collection, Mutable, Set, MutableSet}; +use {Collection, Mutable, Set, MutableSet, MutableSeq}; use vec::Vec; diff --git a/src/libcollections/btree.rs b/src/libcollections/btree.rs index e4605527ce5..096b0c7f517 100644 --- a/src/libcollections/btree.rs +++ b/src/libcollections/btree.rs @@ -24,7 +24,7 @@ use alloc::boxed::Box; use core::fmt; use core::fmt::Show; -use Collection; +use {Collection, MutableSeq}; use vec::Vec; #[allow(missing_doc)] diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 48ea1bd1c01..24df95e77c4 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -30,7 +30,7 @@ use core::iter; use core::mem; use core::ptr; -use {Collection, Mutable, Deque}; +use {Collection, Mutable, Deque, MutableSeq}; /// A doubly-linked list. pub struct DList { @@ -265,6 +265,11 @@ impl Deque for DList { } } +impl MutableSeq for DList { + fn push(&mut self, elt: T) { self.push_back(elt) } + fn pop(&mut self) -> Option { self.pop_back() } +} + impl Default for DList { #[inline] fn default() -> DList { DList::new() } @@ -719,7 +724,7 @@ mod tests { use test::Bencher; use test; - use Deque; + use {Deque, MutableSeq}; use super::{DList, Node, ListInsertion}; use vec::Vec; diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs index 7168af89b59..485dc8c5959 100644 --- a/src/libcollections/hash/sip.rs +++ b/src/libcollections/hash/sip.rs @@ -281,6 +281,8 @@ mod tests { use super::super::{Hash, Writer}; use super::{SipState, hash, hash_with_keys}; + use MutableSeq; + // Hash just the bytes of the slice, without length prefix struct Bytes<'a>(&'a [u8]); diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index fba89df1bbc..2b1d8b140ae 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -325,6 +325,11 @@ pub trait MutableSet: Set + Mutable { fn remove(&mut self, value: &T) -> bool; } +pub trait MutableSeq: Mutable { + fn push(&mut self, t: T); + fn pop(&mut self) -> Option; +} + /// A double-ended sequence that allows querying, insertion and deletion at both /// ends. /// @@ -384,7 +389,7 @@ pub trait MutableSet: Set + Mutable { /// println!("{}", (f, b)); /// } /// ``` -pub trait Deque : Mutable { +pub trait Deque : MutableSeq { /// Provide a reference to the front element, or `None` if the sequence is /// empty. /// @@ -535,4 +540,8 @@ mod std { pub use core::clone; // deriving(Clone) pub use core::cmp; // deriving(Eq, Ord, etc.) pub use hash; // deriving(Hash) + + pub mod collections { + pub use MutableSeq; + } } diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs index db062a70bbb..0e4b46cfc56 100644 --- a/src/libcollections/macros.rs +++ b/src/libcollections/macros.rs @@ -11,8 +11,26 @@ #![macro_escape] /// Create a `std::vec::Vec` containing the arguments. +#[cfg(not(test))] macro_rules! vec( ($($e:expr),*) => ({ + #[allow(unused_imports)] + use std::collections::MutableSeq; + + // leading _ to allow empty construction without a warning. + let mut _temp = ::vec::Vec::new(); + $(_temp.push($e);)* + _temp + }); + ($($e:expr),+,) => (vec!($($e),+)) +) + +#[cfg(test)] +macro_rules! vec( + ($($e:expr),*) => ({ + #[allow(unused_imports)] + use MutableSeq; + // leading _ to allow empty construction without a warning. let mut _temp = ::vec::Vec::new(); $(_temp.push($e);)* diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs index 9451f2521c8..6e1a3ec1cb6 100644 --- a/src/libcollections/priority_queue.rs +++ b/src/libcollections/priority_queue.rs @@ -154,7 +154,7 @@ use core::default::Default; use core::mem::{zeroed, replace, swap}; use core::ptr; -use {Collection, Mutable}; +use {Collection, Mutable, MutableSeq}; use slice; use vec::Vec; @@ -388,6 +388,7 @@ mod tests { use priority_queue::PriorityQueue; use vec::Vec; + use MutableSeq; #[test] fn test_iterator() { diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs index 5e19accdd67..05dda930398 100644 --- a/src/libcollections/ringbuf.rs +++ b/src/libcollections/ringbuf.rs @@ -20,7 +20,7 @@ use core::default::Default; use core::fmt; use core::iter::RandomAccessIterator; -use {Deque, Collection, Mutable}; +use {Deque, Collection, Mutable, MutableSeq}; use vec::Vec; static INITIAL_CAPACITY: uint = 8u; // 2^3 @@ -114,6 +114,11 @@ impl Deque for RingBuf { } } +impl MutableSeq for RingBuf { + fn push(&mut self, t: T) { self.push_back(t) } + fn pop(&mut self) -> Option { self.pop_back() } +} + impl Default for RingBuf { #[inline] fn default() -> RingBuf { RingBuf::new() } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 6c3c8437e25..64062dc0ccb 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -107,7 +107,7 @@ use core::mem; use core::ptr; use core::iter::{range_step, MultiplicativeIterator}; -use Collection; +use {Collection, MutableSeq}; use vec::Vec; pub use core::slice::{ref_slice, mut_ref_slice, Splits, Windows}; @@ -731,7 +731,7 @@ mod tests { use std::rt; use slice::*; - use Mutable; + use {Mutable, MutableSeq}; use vec::Vec; fn square(n: uint) -> uint { n * n } @@ -2133,6 +2133,7 @@ mod bench { use test::Bencher; use vec::Vec; + use MutableSeq; #[bench] fn iterator(b: &mut Bencher) { diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 48bc492e25c..653f6bae26c 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -77,7 +77,7 @@ use core::cmp; use core::iter::AdditiveIterator; use core::mem; -use Collection; +use {Collection, MutableSeq}; use hash; use string::String; use unicode; diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index b19bef68590..10cc446abcd 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -20,7 +20,7 @@ use core::mem; use core::ptr; use core::raw::Slice; -use {Collection, Mutable}; +use {Collection, Mutable, MutableSeq}; use hash; use str; use str::{CharRange, StrAllocating, MaybeOwned, Owned, Slice}; diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs index 8c24326c840..124209ba52e 100644 --- a/src/libcollections/treemap.rs +++ b/src/libcollections/treemap.rs @@ -40,7 +40,7 @@ use core::mem::{replace, swap}; use core::ptr; use std::hash::{Writer, Hash}; -use {Collection, Mutable, Set, MutableSet, MutableMap, Map}; +use {Collection, Mutable, Set, MutableSet, MutableMap, Map, MutableSeq}; use vec::Vec; // This is implemented as an AA tree, which is a simplified variation of @@ -1127,7 +1127,7 @@ mod test_treemap { use std::rand::Rng; use std::rand; - use {Map, MutableMap, Mutable}; + use {Map, MutableMap, Mutable, MutableSeq}; use super::{TreeMap, TreeNode}; #[test] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 0002867495c..2338b5ff7e9 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -23,7 +23,7 @@ use core::num; use core::ptr; use core::uint; -use {Collection, Mutable}; +use {Collection, Mutable, MutableSeq}; use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector}; use slice::{Items, MutItems}; @@ -666,67 +666,6 @@ impl Vec { } } - /// Remove the last element from a vector and return it, or `None` if it is - /// empty. - /// - /// # Example - /// - /// ``` - /// let mut vec = vec![1i, 2, 3]; - /// assert_eq!(vec.pop(), Some(3)); - /// assert_eq!(vec, vec![1, 2]); - /// ``` - #[inline] - pub fn pop(&mut self) -> Option { - 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 - /// - /// ``` - /// let mut vec = vec![1i, 2]; - /// vec.push(3); - /// assert_eq!(vec, vec![1, 2, 3]); - /// ``` - #[inline] - pub fn push(&mut self, value: T) { - if mem::size_of::() == 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::(); - let size = max(old_size, 2 * mem::size_of::()) * 2; - if old_size > size { fail!("capacity overflow") } - unsafe { - self.ptr = alloc_or_realloc(self.ptr, size, - self.cap * mem::size_of::()); - } - self.cap = max(self.cap, 2) * 2; - } - - unsafe { - let end = (self.ptr as *const T).offset(self.len as int) as *mut T; - ptr::write(&mut *end, value); - self.len += 1; - } - } - /// Appends one element to the vector provided. The vector itself is then /// returned for use again. /// @@ -1615,6 +1554,70 @@ impl fmt::Show for Vec { } } +impl MutableSeq for Vec { + /// 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!(1i, 2); + /// vec.push(3); + /// assert_eq!(vec, vec!(1, 2, 3)); + /// ``` + #[inline] + fn push(&mut self, value: T) { + if mem::size_of::() == 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::(); + let size = max(old_size, 2 * mem::size_of::()) * 2; + if old_size > size { fail!("capacity overflow") } + unsafe { + self.ptr = alloc_or_realloc(self.ptr, size, + self.cap * mem::size_of::()); + } + self.cap = max(self.cap, 2) * 2; + } + + unsafe { + let end = (self.ptr as *const T).offset(self.len as int) as *mut T; + ptr::write(&mut *end, value); + self.len += 1; + } + } + + /// Remove the last element from a vector and return it, or `None` if it is + /// empty. + /// + /// # Example + /// + /// ```rust + /// let mut vec = vec!(1i, 2, 3); + /// assert_eq!(vec.pop(), Some(3)); + /// assert_eq!(vec, vec!(1, 2)); + /// ``` + #[inline] + fn pop(&mut self) -> Option { + if self.len == 0 { + None + } else { + unsafe { + self.len -= 1; + Some(ptr::read(self.as_slice().unsafe_ref(self.len()))) + } + } + } + +} + /// An iterator that moves out of a vector. pub struct MoveItems { allocation: *mut T, // the block of memory allocated for the vector @@ -1704,6 +1707,8 @@ mod tests { use test::Bencher; use super::{unzip, raw, Vec}; + use MutableSeq; + #[test] fn test_small_vec_struct() { assert!(size_of::>() == size_of::() * 3); diff --git a/src/librustrt/at_exit_imp.rs b/src/librustrt/at_exit_imp.rs index 1faf492e498..c9188e81975 100644 --- a/src/librustrt/at_exit_imp.rs +++ b/src/librustrt/at_exit_imp.rs @@ -15,6 +15,7 @@ use core::prelude::*; use alloc::boxed::Box; +use collections::MutableSeq; use collections::vec::Vec; use core::atomics; use core::mem; diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs index 7434951d3ee..b7366f440d0 100644 --- a/src/librustrt/local_data.rs +++ b/src/librustrt/local_data.rs @@ -41,6 +41,7 @@ assert_eq!(*key_vector.get().unwrap(), vec![4]); use core::prelude::*; use alloc::boxed::Box; +use collections::MutableSeq; use collections::vec::Vec; use core::kinds::marker; use core::mem; diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs index ccef1c0fd2a..d98d490a84b 100644 --- a/src/libstd/collections/mod.rs +++ b/src/libstd/collections/mod.rs @@ -15,7 +15,7 @@ #![experimental] pub use core_collections::{Collection, Mutable, Map, MutableMap}; -pub use core_collections::{Set, MutableSet, Deque}; +pub use core_collections::{Set, MutableSet, Deque, MutableSeq}; pub use core_collections::{Bitv, BitvSet, BTree, DList, EnumSet}; pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap}; pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet}; diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs index 86283f03381..5980245fa79 100644 --- a/src/libstd/dynamic_lib.rs +++ b/src/libstd/dynamic_lib.rs @@ -20,6 +20,7 @@ A simple wrapper over the platform's dynamic library facilities #![allow(missing_doc)] use clone::Clone; +use collections::MutableSeq; use c_str::ToCStr; use iter::Iterator; use mem; diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs index ca3eee01575..5215aec5dfb 100644 --- a/src/libstd/io/extensions.rs +++ b/src/libstd/io/extensions.rs @@ -15,7 +15,7 @@ // FIXME: Not sure how this should be structured // FIXME: Iteration should probably be considered separately -use collections::Collection; +use collections::{Collection, MutableSeq}; use iter::Iterator; use option::{Option, Some, None}; use result::{Ok, Err}; diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs index afd88ee0ed9..c7dec49a76d 100644 --- a/src/libstd/io/fs.rs +++ b/src/libstd/io/fs.rs @@ -53,7 +53,7 @@ fs::unlink(&path); use c_str::ToCStr; use clone::Clone; -use collections::Collection; +use collections::{Collection, MutableSeq}; use io::standard_error; use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode}; use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader}; diff --git a/src/libstd/io/signal.rs b/src/libstd/io/signal.rs index d46f437cddd..c126866e715 100644 --- a/src/libstd/io/signal.rs +++ b/src/libstd/io/signal.rs @@ -20,6 +20,7 @@ definitions for a number of signals. */ use clone::Clone; +use collections::MutableSeq; use comm::{Sender, Receiver, channel}; use io; use iter::Iterator; diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e14092bc8dc..125c3fdf5d9 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -288,4 +288,6 @@ mod std { #[cfg(test)] pub use os = realstd::os; // The test runner requires std::slice::Vector, so re-export std::slice just for it. #[cfg(test)] pub use slice; + + pub use collections; // vec!() uses MutableSeq } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 3c6c860f516..6de6b9d680f 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -315,6 +315,9 @@ macro_rules! try( #[macro_export] macro_rules! vec( ($($e:expr),*) => ({ + #[allow(unused_imports)] + use std::collections::MutableSeq; + // leading _ to allow empty construction without a warning. let mut _temp = ::std::vec::Vec::new(); $(_temp.push($e);)* diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs index cc30acf064b..c8528e752e8 100644 --- a/src/libstd/num/strconv.rs +++ b/src/libstd/num/strconv.rs @@ -14,7 +14,7 @@ use char; use clone::Clone; -use collections::Collection; +use collections::{Collection, MutableSeq}; use num::{NumCast, Zero, One, cast, Int}; use num::{Float, FPNaN, FPInfinite, ToPrimitive}; use num; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 96d3b3e3e6a..f71f1d22d00 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -32,7 +32,7 @@ #![allow(non_snake_case_functions)] use clone::Clone; -use collections::Collection; +use collections::{Collection, MutableSeq}; use fmt; use io::{IoResult, IoError}; use iter::Iterator; diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index ececfab5f74..0c93f8e6de9 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -65,7 +65,7 @@ println!("path exists: {}", path.exists()); #![experimental] -use collections::Collection; +use collections::{Collection, MutableSeq}; use c_str::CString; use clone::Clone; use fmt; diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 007686aa05c..877ca2c7e01 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -13,7 +13,7 @@ use c_str::{CString, ToCStr}; use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; -use collections::Collection; +use collections::{Collection, MutableSeq}; use from_str::FromStr; use hash; use io::Writer; diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 4a6ed561233..d9b802b38fd 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -16,7 +16,7 @@ use ascii::AsciiCast; use c_str::{CString, ToCStr}; use clone::Clone; use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering}; -use collections::Collection; +use collections::{Collection, MutableSeq}; use from_str::FromStr; use hash; use io::Writer; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 0fa223305a6..0ce7497cf30 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -63,7 +63,7 @@ #[doc(no_inline)] pub use clone::Clone; #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord}; #[doc(no_inline)] pub use cmp::{Ordering, Less, Equal, Greater, Equiv}; -#[doc(no_inline)] pub use collections::{Collection, Mutable, Map, MutableMap}; +#[doc(no_inline)] pub use collections::{Collection, Mutable, Map, MutableMap, MutableSeq}; #[doc(no_inline)] pub use collections::{Set, MutableSet}; #[doc(no_inline)] pub use iter::{FromIterator, Extendable, ExactSize}; #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator}; diff --git a/src/libsync/deque.rs b/src/libsync/deque.rs index 913a58010d4..c541cc02774 100644 --- a/src/libsync/deque.rs +++ b/src/libsync/deque.rs @@ -55,7 +55,7 @@ use core::prelude::*; use alloc::arc::Arc; use alloc::heap::{allocate, deallocate}; use alloc::boxed::Box; -use collections::Vec; +use collections::{Vec, MutableSeq}; use core::kinds::marker; use core::mem::{forget, min_align_of, size_of, transmute}; use core::ptr; diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs index d056566bb9a..1bdf24ea7dd 100644 --- a/src/libsync/raw.rs +++ b/src/libsync/raw.rs @@ -22,7 +22,7 @@ use core::finally::Finally; use core::kinds::marker; use core::mem; use core::ty::Unsafe; -use collections::Vec; +use collections::{Vec, MutableSeq}; use mutex; use comm::{Receiver, Sender, channel};