From: Brian Anderson Date: Fri, 11 Jul 2014 17:12:38 +0000 (-0700) Subject: collections: Move push/pop to MutableSeq X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=d36a8f3f9c70c63ed9042d83cdc47392d12b3886;p=rust.git collections: Move push/pop to MutableSeq Implement for Vec, DList, RingBuf. Add MutableSeq to the prelude. Since the collections traits are in the prelude most consumers of these methods will continue to work without change. [breaking-change] --- 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 @@ fn drop(&mut self) { #[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::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 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::mem; use core::ptr; -use {Collection, Mutable, Deque}; +use {Collection, Mutable, Deque, MutableSeq}; /// A doubly-linked list. pub struct DList { @@ -265,6 +265,11 @@ fn pop_back(&mut self) -> Option { } } +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::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::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 @@ fn push_back(&mut self, t: T) { } } +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::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 @@ fn main() { 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::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::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::ptr; use core::uint; -use {Collection, Mutable}; +use {Collection, Mutable, MutableSeq}; use slice::{MutableOrdVector, MutableVectorAllocating, CloneableVector}; use slice::{Items, MutItems}; @@ -666,67 +666,6 @@ pub fn shrink_to_fit(&mut self) { } } - /// 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 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { } } +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 @@ 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 @@ #![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 @@ 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 @@ */ 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 @@ #![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 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 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::kinds::marker; use core::mem; use core::ty::Unsafe; -use collections::Vec; +use collections::{Vec, MutableSeq}; use mutex; use comm::{Receiver, Sender, channel};