diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 6bc34f1eb2c..c513aec0b84 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -32,6 +32,7 @@ use std::io::process; use std::io::timer; use std::io; use std::os; +use std::iter::repeat; use std::str; use std::string::String; use std::thread::Thread; @@ -947,8 +948,7 @@ fn check_expected_errors(expected_errors: Vec , proc_res: &ProcRes) { // true if we found the error in question - let mut found_flags = Vec::from_elem( - expected_errors.len(), false); + let mut found_flags: Vec<_> = repeat(false).take(expected_errors.len()).collect(); if proc_res.status.success() { fatal("process did not return an error status"); @@ -1308,7 +1308,7 @@ fn make_run_args(config: &Config, props: &TestProps, testfile: &Path) -> // Add the arguments in the run_flags directive args.extend(split_maybe_args(&props.run_flags).into_iter()); - let prog = args.remove(0).unwrap(); + let prog = args.remove(0); return ProcArgs { prog: prog, args: args, diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 04128f837ec..03634657a71 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -96,7 +96,7 @@ use heap::deallocate; /// use std::thread::Thread; /// /// fn main() { -/// let numbers = Vec::from_fn(100, |i| i as f32); +/// let numbers: Vec<_> = range(0, 100u32).map(|i| i as f32).collect(); /// let shared_numbers = Arc::new(numbers); /// /// for _ in range(0u, 10) { diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs index b2dba59c977..2427422f743 100644 --- a/src/libcollections/binary_heap.rs +++ b/src/libcollections/binary_heap.rs @@ -66,7 +66,7 @@ //! // for a simpler implementation. //! fn shortest_path(adj_list: &Vec>, start: uint, goal: uint) -> uint { //! // dist[node] = current shortest distance from `start` to `node` -//! let mut dist = Vec::from_elem(adj_list.len(), uint::MAX); +//! let mut dist: Vec<_> = range(0, adj_list.len()).map(|_| uint::MAX).collect(); //! //! let mut heap = BinaryHeap::new(); //! diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs index 74ff6d90da7..e29f19bbed3 100644 --- a/src/libcollections/bit.rs +++ b/src/libcollections/bit.rs @@ -85,7 +85,7 @@ use core::prelude::*; use core::cmp; use core::default::Default; use core::fmt; -use core::iter::{Cloned, Chain, Enumerate, Repeat, Skip, Take}; +use core::iter::{Cloned, Chain, Enumerate, Repeat, Skip, Take, repeat}; use core::iter; use core::num::Int; use core::slice::{Iter, IterMut}; @@ -267,7 +267,7 @@ impl Bitv { pub fn from_elem(nbits: uint, bit: bool) -> Bitv { let nblocks = blocks_for_bits(nbits); let mut bitv = Bitv { - storage: Vec::from_elem(nblocks, if bit { !0u32 } else { 0u32 }), + storage: repeat(if bit { !0u32 } else { 0u32 }).take(nblocks).collect(), nbits: nbits }; bitv.fix_last_block(); @@ -651,7 +651,7 @@ impl Bitv { let len = self.nbits/8 + if self.nbits % 8 == 0 { 0 } else { 1 }; - Vec::from_fn(len, |i| + range(0, len).map(|i| bit(self, i, 0) | bit(self, i, 1) | bit(self, i, 2) | @@ -660,7 +660,7 @@ impl Bitv { bit(self, i, 5) | bit(self, i, 6) | bit(self, i, 7) - ) + ).collect() } /// Deprecated: Use `iter().collect()`. @@ -834,7 +834,7 @@ impl Bitv { // Allocate new words, if needed if new_nblocks > self.storage.len() { let to_add = new_nblocks - self.storage.len(); - self.storage.grow(to_add, full_value); + self.storage.extend(repeat(full_value).take(to_add)); } // Adjust internal bit count diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 1e4d3237501..8f51b551700 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -555,10 +555,10 @@ impl Node { let node = mem::replace(left_and_out, unsafe { Node::new_internal(capacity_from_b(b)) }); left_and_out._len = 1; unsafe { - ptr::write(left_and_out.keys_mut().unsafe_mut(0), key); - ptr::write(left_and_out.vals_mut().unsafe_mut(0), value); - ptr::write(left_and_out.edges_mut().unsafe_mut(0), node); - ptr::write(left_and_out.edges_mut().unsafe_mut(1), right); + ptr::write(left_and_out.keys_mut().get_unchecked_mut(0), key); + ptr::write(left_and_out.vals_mut().get_unchecked_mut(0), value); + ptr::write(left_and_out.edges_mut().get_unchecked_mut(0), node); + ptr::write(left_and_out.edges_mut().get_unchecked_mut(1), right); } } @@ -637,7 +637,7 @@ impl<'a, K: 'a, V: 'a> Handle<&'a Node, handle::Edge, handle::Internal> { /// making it more suitable for moving down a chain of nodes. pub fn into_edge(self) -> &'a Node { unsafe { - self.node.edges().unsafe_get(self.index) + self.node.edges().get_unchecked(self.index) } } } @@ -648,7 +648,7 @@ impl<'a, K: 'a, V: 'a> Handle<&'a mut Node, handle::Edge, handle::Internal /// `edge_mut`, making it more suitable for moving down a chain of nodes. pub fn into_edge_mut(self) -> &'a mut Node { unsafe { - self.node.edges_mut().unsafe_mut(self.index) + self.node.edges_mut().get_unchecked_mut(self.index) } } } @@ -722,7 +722,7 @@ impl>> Handle &mut Node { unsafe { - self.node.edges_mut().unsafe_mut(self.index) + self.node.edges_mut().get_unchecked_mut(self.index) } } @@ -830,8 +830,8 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a Node, handle::KV, NodeType> { let (keys, vals) = self.node.as_slices(); unsafe { ( - keys.unsafe_get(self.index), - vals.unsafe_get(self.index) + keys.get_unchecked(self.index), + vals.get_unchecked(self.index) ) } } @@ -845,8 +845,8 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle<&'a mut Node, handle::KV, NodeType let (keys, vals) = self.node.as_slices_mut(); unsafe { ( - keys.unsafe_mut(self.index), - vals.unsafe_mut(self.index) + keys.get_unchecked_mut(self.index), + vals.get_unchecked_mut(self.index) ) } } @@ -870,14 +870,14 @@ impl<'a, K: 'a, V: 'a, NodeRef: Deref> + 'a, NodeType> Handle &'a K { - // unsafe { self.node.keys().unsafe_get(self.index) } + // unsafe { self.node.keys().get_unchecked(self.index) } // } // // /// Returns a reference to the value pointed-to by this handle. This doesn't return a // /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the // /// handle. // pub fn val(&'a self) -> &'a V { - // unsafe { self.node.vals().unsafe_get(self.index) } + // unsafe { self.node.vals().get_unchecked(self.index) } // } } @@ -887,14 +887,14 @@ impl<'a, K: 'a, V: 'a, NodeRef: DerefMut> + 'a, NodeType> Handle &'a mut K { - unsafe { self.node.keys_mut().unsafe_mut(self.index) } + unsafe { self.node.keys_mut().get_unchecked_mut(self.index) } } /// Returns a mutable reference to the value pointed-to by this handle. This doesn't return a /// reference with a lifetime as large as `into_kv_mut`, but it also does not consume the /// handle. pub fn val_mut(&'a mut self) -> &'a mut V { - unsafe { self.node.vals_mut().unsafe_mut(self.index) } + unsafe { self.node.vals_mut().get_unchecked_mut(self.index) } } } @@ -1078,7 +1078,7 @@ impl Node { debug_assert!(!self.is_leaf()); unsafe { - let ret = ptr::read(self.edges().unsafe_get(0)); + let ret = ptr::read(self.edges().get_unchecked(0)); self.destroy(); ptr::write(self, ret); } @@ -1092,8 +1092,8 @@ impl Node { unsafe fn push_kv(&mut self, key: K, val: V) { let len = self.len(); - ptr::write(self.keys_mut().unsafe_mut(len), key); - ptr::write(self.vals_mut().unsafe_mut(len), val); + ptr::write(self.keys_mut().get_unchecked_mut(len), key); + ptr::write(self.vals_mut().get_unchecked_mut(len), val); self._len += 1; } @@ -1103,7 +1103,7 @@ impl Node { unsafe fn push_edge(&mut self, edge: Node) { let len = self.len(); - ptr::write(self.edges_mut().unsafe_mut(len), edge); + ptr::write(self.edges_mut().get_unchecked_mut(len), edge); } // This must be followed by insert_edge on an internal node. @@ -1120,12 +1120,12 @@ impl Node { self.len() - index ); - ptr::write(self.keys_mut().unsafe_mut(index), key); - ptr::write(self.vals_mut().unsafe_mut(index), val); + ptr::write(self.keys_mut().get_unchecked_mut(index), key); + ptr::write(self.vals_mut().get_unchecked_mut(index), val); self._len += 1; - self.vals_mut().unsafe_mut(index) + self.vals_mut().get_unchecked_mut(index) } // This can only be called immediately after a call to insert_kv. @@ -1136,14 +1136,14 @@ impl Node { self.edges().as_ptr().offset(index as int), self.len() - index ); - ptr::write(self.edges_mut().unsafe_mut(index), edge); + ptr::write(self.edges_mut().get_unchecked_mut(index), edge); } // This must be followed by pop_edge on an internal node. #[inline] unsafe fn pop_kv(&mut self) -> (K, V) { - let key = ptr::read(self.keys().unsafe_get(self.len() - 1)); - let val = ptr::read(self.vals().unsafe_get(self.len() - 1)); + let key = ptr::read(self.keys().get_unchecked(self.len() - 1)); + let val = ptr::read(self.vals().get_unchecked(self.len() - 1)); self._len -= 1; @@ -1153,7 +1153,7 @@ impl Node { // This can only be called immediately after a call to pop_kv. #[inline] unsafe fn pop_edge(&mut self) -> Node { - let edge = ptr::read(self.edges().unsafe_get(self.len() + 1)); + let edge = ptr::read(self.edges().get_unchecked(self.len() + 1)); edge } @@ -1161,8 +1161,8 @@ impl Node { // This must be followed by remove_edge on an internal node. #[inline] unsafe fn remove_kv(&mut self, index: uint) -> (K, V) { - let key = ptr::read(self.keys().unsafe_get(index)); - let val = ptr::read(self.vals().unsafe_get(index)); + let key = ptr::read(self.keys().get_unchecked(index)); + let val = ptr::read(self.vals().get_unchecked(index)); ptr::copy_memory( self.keys_mut().as_mut_ptr().offset(index as int), @@ -1183,7 +1183,7 @@ impl Node { // This can only be called immediately after a call to remove_kv. #[inline] unsafe fn remove_edge(&mut self, index: uint) -> Node { - let edge = ptr::read(self.edges().unsafe_get(index)); + let edge = ptr::read(self.edges().get_unchecked(index)); ptr::copy_memory( self.edges_mut().as_mut_ptr().offset(index as int), @@ -1230,8 +1230,8 @@ impl Node { ); } - let key = ptr::read(self.keys().unsafe_get(right_offset - 1)); - let val = ptr::read(self.vals().unsafe_get(right_offset - 1)); + let key = ptr::read(self.keys().get_unchecked(right_offset - 1)); + let val = ptr::read(self.vals().get_unchecked(right_offset - 1)); self._len = right_offset - 1; @@ -1250,8 +1250,8 @@ impl Node { let old_len = self.len(); self._len += right.len() + 1; - ptr::write(self.keys_mut().unsafe_mut(old_len), key); - ptr::write(self.vals_mut().unsafe_mut(old_len), val); + ptr::write(self.keys_mut().get_unchecked_mut(old_len), key); + ptr::write(self.vals_mut().get_unchecked_mut(old_len), val); ptr::copy_nonoverlapping_memory( self.keys_mut().as_mut_ptr().offset(old_len as int + 1), diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs index 9f2dcda92c0..82dabedd871 100644 --- a/src/libcollections/dlist.rs +++ b/src/libcollections/dlist.rs @@ -1294,8 +1294,10 @@ mod tests { v.pop(); } 1 => { - m.pop_front(); - v.remove(0); + if !v.is_empty() { + m.pop_front(); + v.remove(0); + } } 2 | 4 => { m.push_front(-i); diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs index fe9d8de440a..688214140c1 100644 --- a/src/libcollections/lib.rs +++ b/src/libcollections/lib.rs @@ -128,8 +128,8 @@ mod prelude { pub use unicode::char::UnicodeChar; // from collections. - pub use slice::{CloneSliceExt, VectorVector}; - pub use str::{IntoMaybeOwned, StrVector}; + pub use slice::{CloneSliceExt, SliceConcatExt}; + pub use str::IntoMaybeOwned; pub use string::{String, ToString}; pub use vec::Vec; } diff --git a/src/libcollections/ring_buf.rs b/src/libcollections/ring_buf.rs index 7f43f8f2e0d..aeda7309064 100644 --- a/src/libcollections/ring_buf.rs +++ b/src/libcollections/ring_buf.rs @@ -1154,7 +1154,7 @@ impl<'a, T> Iterator<&'a T> for Iter<'a, T> { } let tail = self.tail; self.tail = wrap_index(self.tail + 1, self.ring.len()); - unsafe { Some(self.ring.unsafe_get(tail)) } + unsafe { Some(self.ring.get_unchecked(tail)) } } #[inline] @@ -1171,7 +1171,7 @@ impl<'a, T> DoubleEndedIterator<&'a T> for Iter<'a, T> { return None; } self.head = wrap_index(self.head - 1, self.ring.len()); - unsafe { Some(self.ring.unsafe_get(self.head)) } + unsafe { Some(self.ring.get_unchecked(self.head)) } } } @@ -1190,7 +1190,7 @@ impl<'a, T> RandomAccessIterator<&'a T> for Iter<'a, T> { None } else { let idx = wrap_index(self.tail + j, self.ring.len()); - unsafe { Some(self.ring.unsafe_get(idx)) } + unsafe { Some(self.ring.get_unchecked(idx)) } } } } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 0c894d3cc46..bbe6ecc8ea6 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -96,35 +96,934 @@ use core::mem::size_of; use core::mem; use core::ops::{FnMut,SliceMut}; use core::prelude::{Clone, Greater, Iterator, IteratorExt, Less, None, Option}; -use core::prelude::{Ord, Ordering, PtrExt, Some, range}; +use core::prelude::{Ord, Ordering, PtrExt, Some, range, IteratorCloneExt, Result}; use core::ptr; use core::slice as core_slice; use self::Direction::*; use vec::Vec; -pub use core::slice::{Chunks, AsSlice, SplitsN, Windows}; +pub use core::slice::{Chunks, AsSlice, Windows}; pub use core::slice::{Iter, IterMut, PartialEqSliceExt}; -pub use core::slice::{ImmutableIntSlice, MutableIntSlice}; -pub use core::slice::{MutSplits, MutChunks, Splits}; +pub use core::slice::{IntSliceExt, SplitMut, ChunksMut, Split}; +pub use core::slice::{SplitN, RSplitN, SplitNMut, RSplitNMut}; pub use core::slice::{bytes, mut_ref_slice, ref_slice}; -pub use core::slice::{from_raw_buf, from_raw_mut_buf, BinarySearchResult}; +pub use core::slice::{from_raw_buf, from_raw_mut_buf}; -// Functional utilities +#[deprecated = "use Iter instead"] +pub type Items<'a, T:'a> = Iter<'a, T>; -#[allow(missing_docs)] -pub trait VectorVector for Sized? { - // FIXME #5898: calling these .concat and .connect conflicts with - // StrVector::con{cat,nect}, since they have generic contents. - /// Flattens a vector of vectors of `T` into a single `Vec`. - fn concat_vec(&self) -> Vec; +#[deprecated = "use IterMut instead"] +pub type MutItems<'a, T:'a> = IterMut<'a, T>; - /// Concatenate a vector of vectors, placing a given separator between each. - fn connect_vec(&self, sep: &T) -> Vec; +//////////////////////////////////////////////////////////////////////////////// +// Basic slice extension methods +//////////////////////////////////////////////////////////////////////////////// + +/// Allocating extension methods for slices. +#[unstable = "needs associated types, may merge with other traits"] +pub trait SliceExt for Sized? { + /// Sorts the slice, in place, using `compare` to compare + /// elements. + /// + /// This sort is `O(n log n)` worst-case and stable, but allocates + /// approximately `2 * n`, where `n` is the length of `self`. + /// + /// # Examples + /// + /// ```rust + /// let mut v = [5i, 4, 1, 3, 2]; + /// v.sort_by(|a, b| a.cmp(b)); + /// assert!(v == [1, 2, 3, 4, 5]); + /// + /// // reverse sorting + /// v.sort_by(|a, b| b.cmp(a)); + /// assert!(v == [5, 4, 3, 2, 1]); + /// ``` + #[stable] + fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; + + /// Consumes `src` and moves as many elements as it can into `self` + /// from the range [start,end). + /// + /// Returns the number of elements copied (the shorter of `self.len()` + /// and `end - start`). + /// + /// # Arguments + /// + /// * src - A mutable vector of `T` + /// * start - The index into `src` to start copying from + /// * end - The index into `src` to stop copying from + /// + /// # Examples + /// + /// ```rust + /// let mut a = [1i, 2, 3, 4, 5]; + /// let b = vec![6i, 7, 8]; + /// let num_moved = a.move_from(b, 0, 3); + /// assert_eq!(num_moved, 3); + /// assert!(a == [6i, 7, 8, 4, 5]); + /// ``` + #[experimental = "uncertain about this API approach"] + fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; + + /// Returns a subslice spanning the interval [`start`, `end`). + /// + /// Panics when the end of the new slice lies beyond the end of the + /// original slice (i.e. when `end > self.len()`) or when `start > end`. + /// + /// Slicing with `start` equal to `end` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice(&self, start: uint, end: uint) -> &[T]; + + /// Returns a subslice from `start` to the end of the slice. + /// + /// Panics when `start` is strictly greater than the length of the original slice. + /// + /// Slicing from `self.len()` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_from(&self, start: uint) -> &[T]; + + /// Returns a subslice from the start of the slice to `end`. + /// + /// Panics when `end` is strictly greater than the length of the original slice. + /// + /// Slicing to `0` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_to(&self, end: uint) -> &[T]; + + /// Divides one slice into two at an index. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// Panics if `mid > len`. + #[stable] + fn split_at(&self, mid: uint) -> (&[T], &[T]); + + /// Returns an iterator over the slice + #[stable] + fn iter(&self) -> Iter; + + /// Returns an iterator over subslices separated by elements that match + /// `pred`. The matched element is not contained in the subslices. + #[stable] + fn split(&self, pred: F) -> Split + where F: FnMut(&T) -> bool; + + /// Returns an iterator over subslices separated by elements that match + /// `pred`, limited to splitting at most `n` times. The matched element is + /// not contained in the subslices. + #[stable] + fn splitn(&self, n: uint, pred: F) -> SplitN + where F: FnMut(&T) -> bool; + + /// Returns an iterator over subslices separated by elements that match + /// `pred` limited to splitting at most `n` times. This starts at the end of + /// the slice and works backwards. The matched element is not contained in + /// the subslices. + #[stable] + fn rsplitn(&self, n: uint, pred: F) -> RSplitN + where F: FnMut(&T) -> bool; + + /// Returns an iterator over all contiguous windows of length + /// `size`. The windows overlap. If the slice is shorter than + /// `size`, the iterator returns no values. + /// + /// # Panics + /// + /// Panics if `size` is 0. + /// + /// # Example + /// + /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`, + /// `[3,4]`): + /// + /// ```rust + /// let v = &[1i, 2, 3, 4]; + /// for win in v.windows(2) { + /// println!("{}", win); + /// } + /// ``` + #[stable] + fn windows(&self, size: uint) -> Windows; + + /// Returns an iterator over `size` elements of the slice at a + /// time. The chunks do not overlap. If `size` does not divide the + /// length of the slice, then the last chunk will not have length + /// `size`. + /// + /// # Panics + /// + /// Panics if `size` is 0. + /// + /// # Example + /// + /// Print the slice two elements at a time (i.e. `[1,2]`, + /// `[3,4]`, `[5]`): + /// + /// ```rust + /// let v = &[1i, 2, 3, 4, 5]; + /// for win in v.chunks(2) { + /// println!("{}", win); + /// } + /// ``` + #[stable] + fn chunks(&self, size: uint) -> Chunks; + + /// Returns the element of a slice at the given index, or `None` if the + /// index is out of bounds. + #[stable] + fn get(&self, index: uint) -> Option<&T>; + + /// Returns the first element of a slice, or `None` if it is empty. + #[stable] + fn first(&self) -> Option<&T>; + + /// Deprecated: renamed to `first`. + #[deprecated = "renamed to `first`"] + fn head(&self) -> Option<&T> { self.first() } + + /// Returns all but the first element of a slice. + #[experimental = "likely to be renamed"] + fn tail(&self) -> &[T]; + + /// Returns all but the last element of a slice. + #[experimental = "likely to be renamed"] + fn init(&self) -> &[T]; + + /// Returns the last element of a slice, or `None` if it is empty. + #[stable] + fn last(&self) -> Option<&T>; + + /// Returns a pointer to the element at the given index, without doing + /// bounds checking. + #[stable] + unsafe fn get_unchecked(&self, index: uint) -> &T; + + /// Deprecated: renamed to `get_unchecked`. + #[deprecated = "renamed to get_unchecked"] + unsafe fn unsafe_get(&self, index: uint) -> &T { + self.get_unchecked(index) + } + + /// Returns an unsafe pointer to the slice's buffer + /// + /// The caller must ensure that the slice outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// + /// Modifying the slice may cause its buffer to be reallocated, which + /// would also make any pointers to it invalid. + #[stable] + fn as_ptr(&self) -> *const T; + + /// Binary search a sorted slice with a comparator function. + /// + /// The comparator function should implement an order consistent + /// with the sort order of the underlying slice, returning an + /// order code that indicates whether its argument is `Less`, + /// `Equal` or `Greater` the desired target. + /// + /// If a matching value is found then returns `Ok`, containing + /// the index for the matched element; if no match is found then + /// `Err` is returned, containing the index where a matching + /// element could be inserted while maintaining sorted order. + /// + /// # Example + /// + /// Looks up a series of four elements. The first is found, with a + /// uniquely determined position; the second and third are not + /// found; the fourth could match any position in `[1,4]`. + /// + /// ```rust + /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// let s = s.as_slice(); + /// + /// let seek = 13; + /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9)); + /// let seek = 4; + /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7)); + /// let seek = 100; + /// assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13)); + /// let seek = 1; + /// let r = s.binary_search_by(|probe| probe.cmp(&seek)); + /// assert!(match r { Ok(1...4) => true, _ => false, }); + /// ``` + #[stable] + fn binary_search_by(&self, f: F) -> Result where + F: FnMut(&T) -> Ordering; + + /// Return the number of elements in the slice + /// + /// # Example + /// + /// ``` + /// let a = [1i, 2, 3]; + /// assert_eq!(a.len(), 3); + /// ``` + #[stable] + fn len(&self) -> uint; + + /// Returns true if the slice has a length of 0 + /// + /// # Example + /// + /// ``` + /// let a = [1i, 2, 3]; + /// assert!(!a.is_empty()); + /// ``` + #[inline] + #[stable] + fn is_empty(&self) -> bool { self.len() == 0 } + /// Returns a mutable reference to the element at the given index, + /// or `None` if the index is out of bounds + #[stable] + fn get_mut(&mut self, index: uint) -> Option<&mut T>; + + /// Work with `self` as a mut slice. + /// Primarily intended for getting a &mut [T] from a [T, ..N]. + #[stable] + fn as_mut_slice(&mut self) -> &mut [T]; + + /// Returns a mutable subslice spanning the interval [`start`, `end`). + /// + /// Panics when the end of the new slice lies beyond the end of the + /// original slice (i.e. when `end > self.len()`) or when `start > end`. + /// + /// Slicing with `start` equal to `end` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T]; + + /// Returns a mutable subslice from `start` to the end of the slice. + /// + /// Panics when `start` is strictly greater than the length of the original slice. + /// + /// Slicing from `self.len()` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_from_mut(&mut self, start: uint) -> &mut [T]; + + /// Returns a mutable subslice from the start of the slice to `end`. + /// + /// Panics when `end` is strictly greater than the length of the original slice. + /// + /// Slicing to `0` yields an empty slice. + #[experimental = "will be replaced by slice syntax"] + fn slice_to_mut(&mut self, end: uint) -> &mut [T]; + + /// Returns an iterator that allows modifying each value + #[stable] + fn iter_mut(&mut self) -> IterMut; + + /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty + #[stable] + fn first_mut(&mut self) -> Option<&mut T>; + + /// Depreated: renamed to `first_mut`. + #[deprecated = "renamed to first_mut"] + fn head_mut(&mut self) -> Option<&mut T> { + self.first_mut() + } + + /// Returns all but the first element of a mutable slice + #[experimental = "likely to be renamed or removed"] + fn tail_mut(&mut self) -> &mut [T]; + + /// Returns all but the last element of a mutable slice + #[experimental = "likely to be renamed or removed"] + fn init_mut(&mut self) -> &mut [T]; + + /// Returns a mutable pointer to the last item in the slice. + #[stable] + fn last_mut(&mut self) -> Option<&mut T>; + + /// Returns an iterator over mutable subslices separated by elements that + /// match `pred`. The matched element is not contained in the subslices. + #[stable] + fn split_mut(&mut self, pred: F) -> SplitMut + where F: FnMut(&T) -> bool; + + /// Returns an iterator over subslices separated by elements that match + /// `pred`, limited to splitting at most `n` times. The matched element is + /// not contained in the subslices. + #[stable] + fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut + where F: FnMut(&T) -> bool; + + /// Returns an iterator over subslices separated by elements that match + /// `pred` limited to splitting at most `n` times. This starts at the end of + /// the slice and works backwards. The matched element is not contained in + /// the subslices. + #[stable] + fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut + where F: FnMut(&T) -> bool; + + /// Returns an iterator over `chunk_size` elements of the slice at a time. + /// The chunks are mutable and do not overlap. If `chunk_size` does + /// not divide the length of the slice, then the last chunk will not + /// have length `chunk_size`. + /// + /// # Panics + /// + /// Panics if `chunk_size` is 0. + #[stable] + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut; + + /// Swaps two elements in a slice. + /// + /// # Arguments + /// + /// * a - The index of the first element + /// * b - The index of the second element + /// + /// # Panics + /// + /// Panics if `a` or `b` are out of bounds. + /// + /// # Example + /// + /// ```rust + /// let mut v = ["a", "b", "c", "d"]; + /// v.swap(1, 3); + /// assert!(v == ["a", "d", "c", "b"]); + /// ``` + #[stable] + fn swap(&mut self, a: uint, b: uint); + + /// Divides one `&mut` into two at an index. + /// + /// The first will contain all indices from `[0, mid)` (excluding + /// the index `mid` itself) and the second will contain all + /// indices from `[mid, len)` (excluding the index `len` itself). + /// + /// # Panics + /// + /// Panics if `mid > len`. + /// + /// # Example + /// + /// ```rust + /// let mut v = [1i, 2, 3, 4, 5, 6]; + /// + /// // scoped to restrict the lifetime of the borrows + /// { + /// let (left, right) = v.split_at_mut(0); + /// assert!(left == []); + /// assert!(right == [1i, 2, 3, 4, 5, 6]); + /// } + /// + /// { + /// let (left, right) = v.split_at_mut(2); + /// assert!(left == [1i, 2]); + /// assert!(right == [3i, 4, 5, 6]); + /// } + /// + /// { + /// let (left, right) = v.split_at_mut(6); + /// assert!(left == [1i, 2, 3, 4, 5, 6]); + /// assert!(right == []); + /// } + /// ``` + #[stable] + fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]); + + /// Reverse the order of elements in a slice, in place. + /// + /// # Example + /// + /// ```rust + /// let mut v = [1i, 2, 3]; + /// v.reverse(); + /// assert!(v == [3i, 2, 1]); + /// ``` + #[stable] + fn reverse(&mut self); + + /// Returns an unsafe mutable pointer to the element in index + #[stable] + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T; + + /// Deprecated: renamed to `get_unchecked_mut`. + #[deprecated = "renamed to get_unchecked_mut"] + unsafe fn unchecked_mut(&mut self, index: uint) -> &mut T { + self.get_unchecked_mut(index) + } + + /// Return an unsafe mutable pointer to the slice's buffer. + /// + /// The caller must ensure that the slice outlives the pointer this + /// function returns, or else it will end up pointing to garbage. + /// + /// Modifying the slice may cause its buffer to be reallocated, which + /// would also make any pointers to it invalid. + #[inline] + #[stable] + fn as_mut_ptr(&mut self) -> *mut T; } -impl<'a, T: Clone, V: AsSlice> VectorVector for [V] { - fn concat_vec(&self) -> Vec { +#[unstable = "trait is unstable"] +impl SliceExt for [T] { + #[inline] + fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { + merge_sort(self, compare) + } + + #[inline] + fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { + for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) { + mem::swap(a, b); + } + cmp::min(self.len(), end-start) + } + + #[inline] + fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { + core_slice::SliceExt::slice(self, start, end) + } + + #[inline] + fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { + core_slice::SliceExt::slice_from(self, start) + } + + #[inline] + fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { + core_slice::SliceExt::slice_to(self, end) + } + + #[inline] + fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]) { + core_slice::SliceExt::split_at(self, mid) + } + + #[inline] + fn iter<'a>(&'a self) -> Iter<'a, T> { + core_slice::SliceExt::iter(self) + } + + #[inline] + fn split(&self, pred: F) -> Split + where F: FnMut(&T) -> bool { + core_slice::SliceExt::split(self, pred) + } + + #[inline] + fn splitn(&self, n: uint, pred: F) -> SplitN + where F: FnMut(&T) -> bool { + core_slice::SliceExt::splitn(self, n, pred) + } + + #[inline] + fn rsplitn(&self, n: uint, pred: F) -> RSplitN + where F: FnMut(&T) -> bool { + core_slice::SliceExt::rsplitn(self, n, pred) + } + + #[inline] + fn windows<'a>(&'a self, size: uint) -> Windows<'a, T> { + core_slice::SliceExt::windows(self, size) + } + + #[inline] + fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T> { + core_slice::SliceExt::chunks(self, size) + } + + #[inline] + fn get<'a>(&'a self, index: uint) -> Option<&'a T> { + core_slice::SliceExt::get(self, index) + } + + #[inline] + fn first<'a>(&'a self) -> Option<&'a T> { + core_slice::SliceExt::first(self) + } + + #[inline] + fn tail<'a>(&'a self) -> &'a [T] { + core_slice::SliceExt::tail(self) + } + + #[inline] + fn init<'a>(&'a self) -> &'a [T] { + core_slice::SliceExt::init(self) + } + + #[inline] + fn last<'a>(&'a self) -> Option<&'a T> { + core_slice::SliceExt::last(self) + } + + #[inline] + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T { + core_slice::SliceExt::get_unchecked(self, index) + } + + #[inline] + fn as_ptr(&self) -> *const T { + core_slice::SliceExt::as_ptr(self) + } + + #[inline] + fn binary_search_by(&self, f: F) -> Result + where F: FnMut(&T) -> Ordering { + core_slice::SliceExt::binary_search_by(self, f) + } + + #[inline] + fn len(&self) -> uint { + core_slice::SliceExt::len(self) + } + + #[inline] + fn is_empty(&self) -> bool { + core_slice::SliceExt::is_empty(self) + } + + #[inline] + fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T> { + core_slice::SliceExt::get_mut(self, index) + } + + #[inline] + fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { + core_slice::SliceExt::as_mut_slice(self) + } + + #[inline] + fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T] { + core_slice::SliceExt::slice_mut(self, start, end) + } + + #[inline] + fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { + core_slice::SliceExt::slice_from_mut(self, start) + } + + #[inline] + fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { + core_slice::SliceExt::slice_to_mut(self, end) + } + + #[inline] + fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { + core_slice::SliceExt::iter_mut(self) + } + + #[inline] + fn first_mut<'a>(&'a mut self) -> Option<&'a mut T> { + core_slice::SliceExt::first_mut(self) + } + + #[inline] + fn tail_mut<'a>(&'a mut self) -> &'a mut [T] { + core_slice::SliceExt::tail_mut(self) + } + + #[inline] + fn init_mut<'a>(&'a mut self) -> &'a mut [T] { + core_slice::SliceExt::init_mut(self) + } + + #[inline] + fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> { + core_slice::SliceExt::last_mut(self) + } + + #[inline] + fn split_mut(&mut self, pred: F) -> SplitMut + where F: FnMut(&T) -> bool { + core_slice::SliceExt::split_mut(self, pred) + } + + #[inline] + fn splitn_mut(&mut self, n: uint, pred: F) -> SplitNMut + where F: FnMut(&T) -> bool { + core_slice::SliceExt::splitn_mut(self, n, pred) + } + + #[inline] + fn rsplitn_mut(&mut self, n: uint, pred: F) -> RSplitNMut + where F: FnMut(&T) -> bool { + core_slice::SliceExt::rsplitn_mut(self, n, pred) + } + + #[inline] + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T> { + core_slice::SliceExt::chunks_mut(self, chunk_size) + } + + #[inline] + fn swap(&mut self, a: uint, b: uint) { + core_slice::SliceExt::swap(self, a, b) + } + + #[inline] + fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) { + core_slice::SliceExt::split_at_mut(self, mid) + } + + #[inline] + fn reverse(&mut self) { + core_slice::SliceExt::reverse(self) + } + + #[inline] + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T { + core_slice::SliceExt::get_unchecked_mut(self, index) + } + + #[inline] + fn as_mut_ptr(&mut self) -> *mut T { + core_slice::SliceExt::as_mut_ptr(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Extension traits for slices over specifc kinds of data +//////////////////////////////////////////////////////////////////////////////// + +/// Extension methods for boxed slices. +#[experimental = "likely to merge into SliceExt if it survives"] +pub trait BoxedSliceExt { + /// Convert `self` into a vector without clones or allocation. + #[experimental] + fn into_vec(self) -> Vec; +} + +#[experimental = "trait is experimental"] +impl BoxedSliceExt for Box<[T]> { + fn into_vec(mut self) -> Vec { + unsafe { + let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); + mem::forget(self); + xs + } + } +} + +/// Allocating extension methods for slices containing `Clone` elements. +#[unstable = "likely to be merged into SliceExt"] +pub trait CloneSliceExt for Sized? { + /// Copies `self` into a new `Vec`. + #[stable] + fn to_vec(&self) -> Vec; + + /// Deprecated: use `iter().cloned().partition(f)` instead. + #[deprecated = "use iter().cloned().partition(f) instead"] + fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool; + + /// Creates an iterator that yields every possible permutation of the + /// vector in succession. + /// + /// # Examples + /// + /// ```rust + /// let v = [1i, 2, 3]; + /// let mut perms = v.permutations(); + /// + /// for p in perms { + /// println!("{}", p); + /// } + /// ``` + /// + /// Iterating through permutations one by one. + /// + /// ```rust + /// let v = [1i, 2, 3]; + /// let mut perms = v.permutations(); + /// + /// assert_eq!(Some(vec![1i, 2, 3]), perms.next()); + /// assert_eq!(Some(vec![1i, 3, 2]), perms.next()); + /// assert_eq!(Some(vec![3i, 1, 2]), perms.next()); + /// ``` + #[unstable] + fn permutations(&self) -> Permutations; + + /// Copies as many elements from `src` as it can into `self` (the + /// shorter of `self.len()` and `src.len()`). Returns the number + /// of elements copied. + /// + /// # Example + /// + /// ```rust + /// let mut dst = [0i, 0, 0]; + /// let src = [1i, 2]; + /// + /// assert!(dst.clone_from_slice(&src) == 2); + /// assert!(dst == [1, 2, 0]); + /// + /// let src2 = [3i, 4, 5, 6]; + /// assert!(dst.clone_from_slice(&src2) == 3); + /// assert!(dst == [3i, 4, 5]); + /// ``` + #[experimental] + fn clone_from_slice(&mut self, &[T]) -> uint; +} + +#[unstable = "trait is unstable"] +impl CloneSliceExt for [T] { + /// Returns a copy of `v`. + #[inline] + fn to_vec(&self) -> Vec { + let mut vector = Vec::with_capacity(self.len()); + vector.push_all(self); + vector + } + + + #[inline] + fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { + self.iter().cloned().partition(f) + } + + /// Returns an iterator over all permutations of a vector. + fn permutations(&self) -> Permutations { + Permutations{ + swaps: ElementSwaps::new(self.len()), + v: self.to_vec(), + } + } + + fn clone_from_slice(&mut self, src: &[T]) -> uint { + core_slice::CloneSliceExt::clone_from_slice(self, src) + } +} + +/// Allocating extension methods for slices on Ord values. +#[unstable = "likely to merge with SliceExt"] +pub trait OrdSliceExt for Sized? { + /// Sorts the slice, in place. + /// + /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. + /// + /// # Examples + /// + /// ```rust + /// let mut v = [-5i, 4, 1, -3, 2]; + /// + /// v.sort(); + /// assert!(v == [-5i, -3, 1, 2, 4]); + /// ``` + #[stable] + fn sort(&mut self); + + /// Binary search a sorted slice for a given element. + /// + /// If the value is found then `Ok` is returned, containing the + /// index of the matching element; if the value is not found then + /// `Err` is returned, containing the index where a matching + /// element could be inserted while maintaining sorted order. + /// + /// # Example + /// + /// Looks up a series of four elements. The first is found, with a + /// uniquely determined position; the second and third are not + /// found; the fourth could match any position in `[1,4]`. + /// + /// ```rust + /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; + /// let s = s.as_slice(); + /// + /// assert_eq!(s.binary_search(&13), Ok(9)); + /// assert_eq!(s.binary_search(&4), Err(7)); + /// assert_eq!(s.binary_search(&100), Err(13)); + /// let r = s.binary_search(&1); + /// assert!(match r { Ok(1...4) => true, _ => false, }); + /// ``` + #[stable] + fn binary_search(&self, x: &T) -> Result; + + /// Deprecated: use `binary_search` instead. + #[deprecated = "use binary_search instead"] + fn binary_search_elem(&self, x: &T) -> Result { + self.binary_search(x) + } + + /// Mutates the slice to the next lexicographic permutation. + /// + /// Returns `true` if successful and `false` if the slice is at the + /// last-ordered permutation. + /// + /// # Example + /// + /// ```rust + /// let v: &mut [_] = &mut [0i, 1, 2]; + /// v.next_permutation(); + /// let b: &mut [_] = &mut [0i, 2, 1]; + /// assert!(v == b); + /// v.next_permutation(); + /// let b: &mut [_] = &mut [1i, 0, 2]; + /// assert!(v == b); + /// ``` + #[unstable = "uncertain if this merits inclusion in std"] + fn next_permutation(&mut self) -> bool; + + /// Mutates the slice to the previous lexicographic permutation. + /// + /// Returns `true` if successful and `false` if the slice is at the + /// first-ordered permutation. + /// + /// # Example + /// + /// ```rust + /// let v: &mut [_] = &mut [1i, 0, 2]; + /// v.prev_permutation(); + /// let b: &mut [_] = &mut [0i, 2, 1]; + /// assert!(v == b); + /// v.prev_permutation(); + /// let b: &mut [_] = &mut [0i, 1, 2]; + /// assert!(v == b); + /// ``` + #[unstable = "uncertain if this merits inclusion in std"] + fn prev_permutation(&mut self) -> bool; +} + +#[unstable = "trait is unstable"] +impl OrdSliceExt for [T] { + #[inline] + fn sort(&mut self) { + self.sort_by(|a, b| a.cmp(b)) + } + + fn binary_search(&self, x: &T) -> Result { + core_slice::OrdSliceExt::binary_search(self, x) + } + + fn next_permutation(&mut self) -> bool { + core_slice::OrdSliceExt::next_permutation(self) + } + + fn prev_permutation(&mut self) -> bool { + core_slice::OrdSliceExt::prev_permutation(self) + } +} + +#[unstable = "U should be an associated type"] +/// An extension trait for concatenating slices +pub trait SliceConcatExt for Sized? { + /// Flattens a slice of `T` into a single value `U`. + #[stable] + fn concat(&self) -> U; + + #[deprecated = "renamed to concat"] + fn concat_vec(&self) -> U { + self.concat() + } + + /// Flattens a slice of `T` into a single value `U`, placing a + /// given seperator between each. + #[stable] + fn connect(&self, sep: &T) -> U; + + #[deprecated = "renamed to connect"] + fn connect_vec(&self, sep: &T) -> U { + self.connect(sep) + } +} + +impl> SliceConcatExt> for [V] { + fn concat(&self) -> Vec { let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len()); let mut result = Vec::with_capacity(size); for v in self.iter() { @@ -133,7 +1032,7 @@ impl<'a, T: Clone, V: AsSlice> VectorVector for [V] { result } - fn connect_vec(&self, sep: &T) -> Vec { + fn connect(&self, sep: &T) -> Vec { let size = self.iter().fold(0u, |acc, v| acc + v.as_slice().len()); let mut result = Vec::with_capacity(size + self.len()); let mut first = true; @@ -155,6 +1054,7 @@ impl<'a, T: Clone, V: AsSlice> VectorVector for [V] { /// /// The last generated swap is always (0, 1), and it returns the /// sequence to its initial order. +#[experimental] #[deriving(Clone)] pub struct ElementSwaps { sdir: Vec, @@ -166,6 +1066,7 @@ pub struct ElementSwaps { impl ElementSwaps { /// Creates an `ElementSwaps` iterator for a sequence of `length` elements. + #[experimental] pub fn new(length: uint) -> ElementSwaps { // Initialize `sdir` with a direction that position should move in // (all negative at the beginning) and the `size` of the @@ -178,11 +1079,34 @@ impl ElementSwaps { } } -#[deriving(Copy, Clone)] +//////////////////////////////////////////////////////////////////////////////// +// Standard trait implementations for slices +//////////////////////////////////////////////////////////////////////////////// + +#[unstable = "trait is unstable"] +impl BorrowFrom> for [T] { + fn borrow_from(owned: &Vec) -> &[T] { owned[] } +} + +#[unstable = "trait is unstable"] +impl BorrowFromMut> for [T] { + fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned.as_mut_slice_() } +} + +#[unstable = "trait is unstable"] +impl ToOwned> for [T] { + fn to_owned(&self) -> Vec { self.to_vec() } +} + +//////////////////////////////////////////////////////////////////////////////// +// Iterators +//////////////////////////////////////////////////////////////////////////////// + +#[deriving(Copy)] enum Direction { Pos, Neg } /// An `Index` and `Direction` together. -#[deriving(Copy, Clone)] +#[deriving(Copy)] struct SizeDirection { size: uint, dir: Direction, @@ -248,12 +1172,13 @@ impl Iterator<(uint, uint)> for ElementSwaps { /// swap applied. /// /// Generates even and odd permutations alternately. -#[deriving(Clone)] +#[unstable] pub struct Permutations { swaps: ElementSwaps, v: Vec, } +#[unstable = "trait is unstable"] impl Iterator> for Permutations { #[inline] fn next(&mut self) -> Option> { @@ -274,116 +1199,9 @@ impl Iterator> for Permutations { } } -/// Extension methods for boxed slices. -pub trait BoxedSliceExt { - /// Convert `self` into a vector without clones or allocation. - fn into_vec(self) -> Vec; -} - -impl BoxedSliceExt for Box<[T]> { - #[experimental] - fn into_vec(mut self) -> Vec { - unsafe { - let xs = Vec::from_raw_parts(self.as_mut_ptr(), self.len(), self.len()); - mem::forget(self); - xs - } - } -} - -/// Allocating extension methods for slices containing `Clone` elements. -pub trait CloneSliceExt for Sized? { - /// Copies `self` into a new `Vec`. - fn to_vec(&self) -> Vec; - - /// Partitions the vector into two vectors `(a, b)`, where all - /// elements of `a` satisfy `f` and all elements of `b` do not. - fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool; - - /// Creates an iterator that yields every possible permutation of the - /// vector in succession. - /// - /// # Examples - /// - /// ```rust - /// let v = [1i, 2, 3]; - /// let mut perms = v.permutations(); - /// - /// for p in perms { - /// println!("{}", p); - /// } - /// ``` - /// - /// Iterating through permutations one by one. - /// - /// ```rust - /// let v = [1i, 2, 3]; - /// let mut perms = v.permutations(); - /// - /// assert_eq!(Some(vec![1i, 2, 3]), perms.next()); - /// assert_eq!(Some(vec![1i, 3, 2]), perms.next()); - /// assert_eq!(Some(vec![3i, 1, 2]), perms.next()); - /// ``` - fn permutations(&self) -> Permutations; - - /// Copies as many elements from `src` as it can into `self` (the - /// shorter of `self.len()` and `src.len()`). Returns the number - /// of elements copied. - /// - /// # Example - /// - /// ```rust - /// let mut dst = [0i, 0, 0]; - /// let src = [1i, 2]; - /// - /// assert!(dst.clone_from_slice(&src) == 2); - /// assert!(dst == [1, 2, 0]); - /// - /// let src2 = [3i, 4, 5, 6]; - /// assert!(dst.clone_from_slice(&src2) == 3); - /// assert!(dst == [3i, 4, 5]); - /// ``` - fn clone_from_slice(&mut self, &[T]) -> uint; -} - -impl CloneSliceExt for [T] { - /// Returns a copy of `v`. - #[inline] - fn to_vec(&self) -> Vec { - let mut vector = Vec::with_capacity(self.len()); - vector.push_all(self); - vector - } - - - #[inline] - fn partitioned(&self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { - let mut lefts = Vec::new(); - let mut rights = Vec::new(); - - for elt in self.iter() { - if f(elt) { - lefts.push((*elt).clone()); - } else { - rights.push((*elt).clone()); - } - } - - (lefts, rights) - } - - /// Returns an iterator over all permutations of a vector. - fn permutations(&self) -> Permutations { - Permutations{ - swaps: ElementSwaps::new(self.len()), - v: self.to_vec(), - } - } - - fn clone_from_slice(&mut self, src: &[T]) -> uint { - core_slice::CloneSliceExt::clone_from_slice(self, src) - } -} +//////////////////////////////////////////////////////////////////////////////// +// Sorting +//////////////////////////////////////////////////////////////////////////////// fn insertion_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Ordering { let len = v.len() as int; @@ -588,755 +1406,8 @@ fn merge_sort(v: &mut [T], mut compare: F) where F: FnMut(&T, &T) -> Order } } -/// Allocating extension methods for slices on Ord values. -#[experimental = "likely to merge with other traits"] -pub trait OrdSliceExt for Sized? { - /// Sorts the slice, in place. - /// - /// This is equivalent to `self.sort_by(|a, b| a.cmp(b))`. - /// - /// # Examples - /// - /// ```rust - /// let mut v = [-5i, 4, 1, -3, 2]; - /// - /// v.sort(); - /// assert!(v == [-5i, -3, 1, 2, 4]); - /// ``` - #[experimental] - fn sort(&mut self); - - /// Binary search a sorted slice for a given element. - /// - /// If the value is found then `Found` is returned, containing the - /// index of the matching element; if the value is not found then - /// `NotFound` is returned, containing the index where a matching - /// element could be inserted while maintaining sorted order. - /// - /// # Example - /// - /// Looks up a series of four elements. The first is found, with a - /// uniquely determined position; the second and third are not - /// found; the fourth could match any position in `[1,4]`. - /// - /// ```rust - /// use std::slice::BinarySearchResult::{Found, NotFound}; - /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; - /// let s = s.as_slice(); - /// - /// assert_eq!(s.binary_search_elem(&13), Found(9)); - /// assert_eq!(s.binary_search_elem(&4), NotFound(7)); - /// assert_eq!(s.binary_search_elem(&100), NotFound(13)); - /// let r = s.binary_search_elem(&1); - /// assert!(match r { Found(1...4) => true, _ => false, }); - /// ``` - #[unstable = "name likely to change"] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult; - - /// Mutates the slice to the next lexicographic permutation. - /// - /// Returns `true` if successful and `false` if the slice is at the - /// last-ordered permutation. - /// - /// # Example - /// - /// ```rust - /// let v: &mut [_] = &mut [0i, 1, 2]; - /// v.next_permutation(); - /// let b: &mut [_] = &mut [0i, 2, 1]; - /// assert!(v == b); - /// v.next_permutation(); - /// let b: &mut [_] = &mut [1i, 0, 2]; - /// assert!(v == b); - /// ``` - #[experimental] - fn next_permutation(&mut self) -> bool; - - /// Mutates the slice to the previous lexicographic permutation. - /// - /// Returns `true` if successful and `false` if the slice is at the - /// first-ordered permutation. - /// - /// # Example - /// - /// ```rust - /// let v: &mut [_] = &mut [1i, 0, 2]; - /// v.prev_permutation(); - /// let b: &mut [_] = &mut [0i, 2, 1]; - /// assert!(v == b); - /// v.prev_permutation(); - /// let b: &mut [_] = &mut [0i, 1, 2]; - /// assert!(v == b); - /// ``` - #[experimental] - fn prev_permutation(&mut self) -> bool; -} - -impl OrdSliceExt for [T] { - #[inline] - fn sort(&mut self) { - self.sort_by(|a, b| a.cmp(b)) - } - - fn binary_search_elem(&self, x: &T) -> BinarySearchResult { - core_slice::OrdSliceExt::binary_search_elem(self, x) - } - - fn next_permutation(&mut self) -> bool { - core_slice::OrdSliceExt::next_permutation(self) - } - - fn prev_permutation(&mut self) -> bool { - core_slice::OrdSliceExt::prev_permutation(self) - } -} - -/// Allocating extension methods for slices. -#[experimental = "likely to merge with other traits"] -pub trait SliceExt for Sized? { - /// Sorts the slice, in place, using `compare` to compare - /// elements. - /// - /// This sort is `O(n log n)` worst-case and stable, but allocates - /// approximately `2 * n`, where `n` is the length of `self`. - /// - /// # Examples - /// - /// ```rust - /// let mut v = [5i, 4, 1, 3, 2]; - /// v.sort_by(|a, b| a.cmp(b)); - /// assert!(v == [1, 2, 3, 4, 5]); - /// - /// // reverse sorting - /// v.sort_by(|a, b| b.cmp(a)); - /// assert!(v == [5, 4, 3, 2, 1]); - /// ``` - fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering; - - /// Consumes `src` and moves as many elements as it can into `self` - /// from the range [start,end). - /// - /// Returns the number of elements copied (the shorter of `self.len()` - /// and `end - start`). - /// - /// # Arguments - /// - /// * src - A mutable vector of `T` - /// * start - The index into `src` to start copying from - /// * end - The index into `src` to stop copying from - /// - /// # Examples - /// - /// ```rust - /// let mut a = [1i, 2, 3, 4, 5]; - /// let b = vec![6i, 7, 8]; - /// let num_moved = a.move_from(b, 0, 3); - /// assert_eq!(num_moved, 3); - /// assert!(a == [6i, 7, 8, 4, 5]); - /// ``` - fn move_from(&mut self, src: Vec, start: uint, end: uint) -> uint; - - /// Returns a subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "waiting on final error conventions/slicing syntax"] - fn slice(&self, start: uint, end: uint) -> &[T]; - - /// Returns a subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "waiting on final error conventions/slicing syntax"] - fn slice_from(&self, start: uint) -> &[T]; - - /// Returns a subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "waiting on final error conventions/slicing syntax"] - fn slice_to(&self, end: uint) -> &[T]; - - /// Divides one slice into two at an index. - /// - /// The first will contain all indices from `[0, mid)` (excluding - /// the index `mid` itself) and the second will contain all - /// indices from `[mid, len)` (excluding the index `len` itself). - /// - /// Panics if `mid > len`. - #[unstable = "waiting on final error conventions"] - fn split_at(&self, mid: uint) -> (&[T], &[T]); - - /// Returns an iterator over the slice - #[unstable = "iterator type may change"] - fn iter(&self) -> Iter; - - /// Returns an iterator over subslices separated by elements that match - /// `pred`. The matched element is not contained in the subslices. - #[unstable = "iterator type may change, waiting on unboxed closures"] - fn split(&self, pred: F) -> Splits - where F: FnMut(&T) -> bool; - - /// Returns an iterator over subslices separated by elements that match - /// `pred`, limited to splitting at most `n` times. The matched element is - /// not contained in the subslices. - #[unstable = "iterator type may change"] - fn splitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool; - - /// Returns an iterator over subslices separated by elements that match - /// `pred` limited to splitting at most `n` times. This starts at the end of - /// the slice and works backwards. The matched element is not contained in - /// the subslices. - #[unstable = "iterator type may change"] - fn rsplitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool; - - /// Returns an iterator over all contiguous windows of length - /// `size`. The windows overlap. If the slice is shorter than - /// `size`, the iterator returns no values. - /// - /// # Panics - /// - /// Panics if `size` is 0. - /// - /// # Example - /// - /// Print the adjacent pairs of a slice (i.e. `[1,2]`, `[2,3]`, - /// `[3,4]`): - /// - /// ```rust - /// let v = &[1i, 2, 3, 4]; - /// for win in v.windows(2) { - /// println!("{}", win); - /// } - /// ``` - #[unstable = "iterator type may change"] - fn windows(&self, size: uint) -> Windows; - - /// Returns an iterator over `size` elements of the slice at a - /// time. The chunks do not overlap. If `size` does not divide the - /// length of the slice, then the last chunk will not have length - /// `size`. - /// - /// # Panics - /// - /// Panics if `size` is 0. - /// - /// # Example - /// - /// Print the slice two elements at a time (i.e. `[1,2]`, - /// `[3,4]`, `[5]`): - /// - /// ```rust - /// let v = &[1i, 2, 3, 4, 5]; - /// for win in v.chunks(2) { - /// println!("{}", win); - /// } - /// ``` - #[unstable = "iterator type may change"] - fn chunks(&self, size: uint) -> Chunks; - - /// Returns the element of a slice at the given index, or `None` if the - /// index is out of bounds. - #[unstable = "waiting on final collection conventions"] - fn get(&self, index: uint) -> Option<&T>; - - /// Returns the first element of a slice, or `None` if it is empty. - #[unstable = "name may change"] - fn head(&self) -> Option<&T>; - - /// Returns all but the first element of a slice. - #[unstable = "name may change"] - fn tail(&self) -> &[T]; - - /// Returns all but the last element of a slice. - #[unstable = "name may change"] - fn init(&self) -> &[T]; - - /// Returns the last element of a slice, or `None` if it is empty. - #[unstable = "name may change"] - fn last(&self) -> Option<&T>; - - /// Returns a pointer to the element at the given index, without doing - /// bounds checking. - #[unstable] - unsafe fn unsafe_get(&self, index: uint) -> &T; - - /// Returns an unsafe pointer to the slice's buffer - /// - /// The caller must ensure that the slice outlives the pointer this - /// function returns, or else it will end up pointing to garbage. - /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - #[unstable] - fn as_ptr(&self) -> *const T; - - /// Binary search a sorted slice with a comparator function. - /// - /// The comparator function should implement an order consistent - /// with the sort order of the underlying slice, returning an - /// order code that indicates whether its argument is `Less`, - /// `Equal` or `Greater` the desired target. - /// - /// If a matching value is found then returns `Found`, containing - /// the index for the matched element; if no match is found then - /// `NotFound` is returned, containing the index where a matching - /// element could be inserted while maintaining sorted order. - /// - /// # Example - /// - /// Looks up a series of four elements. The first is found, with a - /// uniquely determined position; the second and third are not - /// found; the fourth could match any position in `[1,4]`. - /// - /// ```rust - /// use std::slice::BinarySearchResult::{Found, NotFound}; - /// let s = [0i, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55]; - /// let s = s.as_slice(); - /// - /// let seek = 13; - /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), Found(9)); - /// let seek = 4; - /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(7)); - /// let seek = 100; - /// assert_eq!(s.binary_search(|probe| probe.cmp(&seek)), NotFound(13)); - /// let seek = 1; - /// let r = s.binary_search(|probe| probe.cmp(&seek)); - /// assert!(match r { Found(1...4) => true, _ => false, }); - /// ``` - #[unstable = "waiting on unboxed closures"] - fn binary_search(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering; - - /// Return the number of elements in the slice - /// - /// # Example - /// - /// ``` - /// let a = [1i, 2, 3]; - /// assert_eq!(a.len(), 3); - /// ``` - #[experimental = "not triaged yet"] - fn len(&self) -> uint; - - /// Returns true if the slice has a length of 0 - /// - /// # Example - /// - /// ``` - /// let a = [1i, 2, 3]; - /// assert!(!a.is_empty()); - /// ``` - #[inline] - #[experimental = "not triaged yet"] - fn is_empty(&self) -> bool { self.len() == 0 } - /// Returns a mutable reference to the element at the given index, - /// or `None` if the index is out of bounds - #[unstable = "waiting on final error conventions"] - fn get_mut(&mut self, index: uint) -> Option<&mut T>; - - /// Work with `self` as a mut slice. - /// Primarily intended for getting a &mut [T] from a [T, ..N]. - fn as_mut_slice(&mut self) -> &mut [T]; - - /// Returns a mutable subslice spanning the interval [`start`, `end`). - /// - /// Panics when the end of the new slice lies beyond the end of the - /// original slice (i.e. when `end > self.len()`) or when `start > end`. - /// - /// Slicing with `start` equal to `end` yields an empty slice. - #[unstable = "waiting on final error conventions"] - fn slice_mut(&mut self, start: uint, end: uint) -> &mut [T]; - - /// Returns a mutable subslice from `start` to the end of the slice. - /// - /// Panics when `start` is strictly greater than the length of the original slice. - /// - /// Slicing from `self.len()` yields an empty slice. - #[unstable = "waiting on final error conventions"] - fn slice_from_mut(&mut self, start: uint) -> &mut [T]; - - /// Returns a mutable subslice from the start of the slice to `end`. - /// - /// Panics when `end` is strictly greater than the length of the original slice. - /// - /// Slicing to `0` yields an empty slice. - #[unstable = "waiting on final error conventions"] - fn slice_to_mut(&mut self, end: uint) -> &mut [T]; - - /// Returns an iterator that allows modifying each value - #[unstable = "waiting on iterator type name conventions"] - fn iter_mut(&mut self) -> IterMut; - - /// Returns a mutable pointer to the first element of a slice, or `None` if it is empty - #[unstable = "name may change"] - fn head_mut(&mut self) -> Option<&mut T>; - - /// Returns all but the first element of a mutable slice - #[unstable = "name may change"] - fn tail_mut(&mut self) -> &mut [T]; - - /// Returns all but the last element of a mutable slice - #[unstable = "name may change"] - fn init_mut(&mut self) -> &mut [T]; - - /// Returns a mutable pointer to the last item in the slice. - #[unstable = "name may change"] - fn last_mut(&mut self) -> Option<&mut T>; - - /// Returns an iterator over mutable subslices separated by elements that - /// match `pred`. The matched element is not contained in the subslices. - #[unstable = "waiting on unboxed closures, iterator type name conventions"] - fn split_mut(&mut self, pred: F) -> MutSplits - where F: FnMut(&T) -> bool; - - /// Returns an iterator over subslices separated by elements that match - /// `pred`, limited to splitting at most `n` times. The matched element is - /// not contained in the subslices. - #[unstable = "waiting on unboxed closures, iterator type name conventions"] - fn splitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool; - - /// Returns an iterator over subslices separated by elements that match - /// `pred` limited to splitting at most `n` times. This starts at the end of - /// the slice and works backwards. The matched element is not contained in - /// the subslices. - #[unstable = "waiting on unboxed closures, iterator type name conventions"] - fn rsplitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool; - - /// Returns an iterator over `chunk_size` elements of the slice at a time. - /// The chunks are mutable and do not overlap. If `chunk_size` does - /// not divide the length of the slice, then the last chunk will not - /// have length `chunk_size`. - /// - /// # Panics - /// - /// Panics if `chunk_size` is 0. - #[unstable = "waiting on iterator type name conventions"] - fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks; - - /// Swaps two elements in a slice. - /// - /// Panics if `a` or `b` are out of bounds. - /// - /// # Arguments - /// - /// * a - The index of the first element - /// * b - The index of the second element - /// - /// # Example - /// - /// ```rust - /// let mut v = ["a", "b", "c", "d"]; - /// v.swap(1, 3); - /// assert!(v == ["a", "d", "c", "b"]); - /// ``` - #[unstable = "waiting on final error conventions"] - fn swap(&mut self, a: uint, b: uint); - - /// Divides one `&mut` into two at an index. - /// - /// The first will contain all indices from `[0, mid)` (excluding - /// the index `mid` itself) and the second will contain all - /// indices from `[mid, len)` (excluding the index `len` itself). - /// - /// Panics if `mid > len`. - /// - /// # Example - /// - /// ```rust - /// let mut v = [1i, 2, 3, 4, 5, 6]; - /// - /// // scoped to restrict the lifetime of the borrows - /// { - /// let (left, right) = v.split_at_mut(0); - /// assert!(left == []); - /// assert!(right == [1i, 2, 3, 4, 5, 6]); - /// } - /// - /// { - /// let (left, right) = v.split_at_mut(2); - /// assert!(left == [1i, 2]); - /// assert!(right == [3i, 4, 5, 6]); - /// } - /// - /// { - /// let (left, right) = v.split_at_mut(6); - /// assert!(left == [1i, 2, 3, 4, 5, 6]); - /// assert!(right == []); - /// } - /// ``` - #[unstable = "waiting on final error conventions"] - fn split_at_mut(&mut self, mid: uint) -> (&mut [T], &mut [T]); - - /// Reverse the order of elements in a slice, in place. - /// - /// # Example - /// - /// ```rust - /// let mut v = [1i, 2, 3]; - /// v.reverse(); - /// assert!(v == [3i, 2, 1]); - /// ``` - #[experimental = "may be moved to iterators instead"] - fn reverse(&mut self); - - /// Returns an unsafe mutable pointer to the element in index - #[experimental = "waiting on unsafe conventions"] - unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T; - - /// Return an unsafe mutable pointer to the slice's buffer. - /// - /// The caller must ensure that the slice outlives the pointer this - /// function returns, or else it will end up pointing to garbage. - /// - /// Modifying the slice may cause its buffer to be reallocated, which - /// would also make any pointers to it invalid. - #[inline] - #[unstable] - fn as_mut_ptr(&mut self) -> *mut T; -} - -impl SliceExt for [T] { - #[inline] - fn sort_by(&mut self, compare: F) where F: FnMut(&T, &T) -> Ordering { - merge_sort(self, compare) - } - - #[inline] - fn move_from(&mut self, mut src: Vec, start: uint, end: uint) -> uint { - for (a, b) in self.iter_mut().zip(src.slice_mut(start, end).iter_mut()) { - mem::swap(a, b); - } - cmp::min(self.len(), end-start) - } - - #[inline] - fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { - core_slice::SliceExt::slice(self, start, end) - } - - #[inline] - fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { - core_slice::SliceExt::slice_from(self, start) - } - - #[inline] - fn slice_to<'a>(&'a self, end: uint) -> &'a [T] { - core_slice::SliceExt::slice_to(self, end) - } - - #[inline] - fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]) { - core_slice::SliceExt::split_at(self, mid) - } - - #[inline] - fn iter<'a>(&'a self) -> Iter<'a, T> { - core_slice::SliceExt::iter(self) - } - - #[inline] - fn split(&self, pred: F) -> Splits - where F: FnMut(&T) -> bool { - core_slice::SliceExt::split(self, pred) - } - - #[inline] - fn splitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::splitn(self, n, pred) - } - - #[inline] - fn rsplitn(&self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::rsplitn(self, n, pred) - } - - #[inline] - fn windows<'a>(&'a self, size: uint) -> Windows<'a, T> { - core_slice::SliceExt::windows(self, size) - } - - #[inline] - fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T> { - core_slice::SliceExt::chunks(self, size) - } - - #[inline] - fn get<'a>(&'a self, index: uint) -> Option<&'a T> { - core_slice::SliceExt::get(self, index) - } - - #[inline] - fn head<'a>(&'a self) -> Option<&'a T> { - core_slice::SliceExt::head(self) - } - - #[inline] - fn tail<'a>(&'a self) -> &'a [T] { - core_slice::SliceExt::tail(self) - } - - #[inline] - fn init<'a>(&'a self) -> &'a [T] { - core_slice::SliceExt::init(self) - } - - #[inline] - fn last<'a>(&'a self) -> Option<&'a T> { - core_slice::SliceExt::last(self) - } - - #[inline] - unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T { - core_slice::SliceExt::unsafe_get(self, index) - } - - #[inline] - fn as_ptr(&self) -> *const T { - core_slice::SliceExt::as_ptr(self) - } - - #[inline] - fn binary_search(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering { - core_slice::SliceExt::binary_search(self, f) - } - - #[inline] - fn len(&self) -> uint { - core_slice::SliceExt::len(self) - } - - #[inline] - fn is_empty(&self) -> bool { - core_slice::SliceExt::is_empty(self) - } - - #[inline] - fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T> { - core_slice::SliceExt::get_mut(self, index) - } - - #[inline] - fn as_mut_slice<'a>(&'a mut self) -> &'a mut [T] { - core_slice::SliceExt::as_mut_slice(self) - } - - #[inline] - fn slice_mut<'a>(&'a mut self, start: uint, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_mut(self, start, end) - } - - #[inline] - fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_from_mut(self, start) - } - - #[inline] - fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T] { - core_slice::SliceExt::slice_to_mut(self, end) - } - - #[inline] - fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> { - core_slice::SliceExt::iter_mut(self) - } - - #[inline] - fn head_mut<'a>(&'a mut self) -> Option<&'a mut T> { - core_slice::SliceExt::head_mut(self) - } - - #[inline] - fn tail_mut<'a>(&'a mut self) -> &'a mut [T] { - core_slice::SliceExt::tail_mut(self) - } - - #[inline] - fn init_mut<'a>(&'a mut self) -> &'a mut [T] { - core_slice::SliceExt::init_mut(self) - } - - #[inline] - fn last_mut<'a>(&'a mut self) -> Option<&'a mut T> { - core_slice::SliceExt::last_mut(self) - } - - #[inline] - fn split_mut(&mut self, pred: F) -> MutSplits - where F: FnMut(&T) -> bool { - core_slice::SliceExt::split_mut(self, pred) - } - - #[inline] - fn splitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::splitn_mut(self, n, pred) - } - - #[inline] - fn rsplitn_mut(&mut self, n: uint, pred: F) -> SplitsN> - where F: FnMut(&T) -> bool { - core_slice::SliceExt::rsplitn_mut(self, n, pred) - } - - #[inline] - fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T> { - core_slice::SliceExt::chunks_mut(self, chunk_size) - } - - #[inline] - fn swap(&mut self, a: uint, b: uint) { - core_slice::SliceExt::swap(self, a, b) - } - - #[inline] - fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]) { - core_slice::SliceExt::split_at_mut(self, mid) - } - - #[inline] - fn reverse(&mut self) { - core_slice::SliceExt::reverse(self) - } - - #[inline] - unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T { - core_slice::SliceExt::unsafe_mut(self, index) - } - - #[inline] - fn as_mut_ptr(&mut self) -> *mut T { - core_slice::SliceExt::as_mut_ptr(self) - } -} - -#[unstable = "trait is unstable"] -impl BorrowFrom> for [T] { - fn borrow_from(owned: &Vec) -> &[T] { owned[] } -} - -#[unstable = "trait is unstable"] -impl BorrowFromMut> for [T] { - fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned.as_mut_slice_() } -} - -#[unstable = "trait is unstable"] -impl ToOwned> for [T] { - fn to_owned(&self) -> Vec { self.to_vec() } -} - -/// Unsafe operations +/// Deprecated, unsafe operations +#[deprecated] pub mod raw { pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice}; pub use core::slice::raw::{shift_ptr, pop_ptr}; @@ -1348,7 +1419,7 @@ mod tests { use prelude::{Some, None, range, Vec, ToString, Clone, Greater, Less, Equal}; use prelude::{SliceExt, Iterator, IteratorExt, DoubleEndedIteratorExt}; use prelude::{OrdSliceExt, CloneSliceExt, PartialEqSliceExt, AsSlice}; - use prelude::{RandomAccessIterator, Ord, VectorVector}; + use prelude::{RandomAccessIterator, Ord, SliceConcatExt}; use core::cell::Cell; use core::default::Default; use core::mem; @@ -1614,15 +1685,19 @@ mod tests { fn test_swap_remove() { let mut v = vec![1i, 2, 3, 4, 5]; let mut e = v.swap_remove(0); - assert_eq!(e, Some(1)); + assert_eq!(e, 1); assert_eq!(v, vec![5i, 2, 3, 4]); e = v.swap_remove(3); - assert_eq!(e, Some(4)); + assert_eq!(e, 4); assert_eq!(v, vec![5i, 2, 3]); + } - e = v.swap_remove(3); - assert_eq!(e, None); - assert_eq!(v, vec![5i, 2, 3]); + #[test] + #[should_fail] + fn test_swap_remove_fail() { + let mut v = vec![1i]; + let _ = v.swap_remove(0); + let _ = v.swap_remove(0); } #[test] @@ -1906,48 +1981,48 @@ mod tests { } #[test] - fn test_binary_search_elem() { - assert_eq!([1i,2,3,4,5].binary_search_elem(&5).found(), Some(4)); - assert_eq!([1i,2,3,4,5].binary_search_elem(&4).found(), Some(3)); - assert_eq!([1i,2,3,4,5].binary_search_elem(&3).found(), Some(2)); - assert_eq!([1i,2,3,4,5].binary_search_elem(&2).found(), Some(1)); - assert_eq!([1i,2,3,4,5].binary_search_elem(&1).found(), Some(0)); + fn test_binary_search() { + assert_eq!([1i,2,3,4,5].binary_search(&5).ok(), Some(4)); + assert_eq!([1i,2,3,4,5].binary_search(&4).ok(), Some(3)); + assert_eq!([1i,2,3,4,5].binary_search(&3).ok(), Some(2)); + assert_eq!([1i,2,3,4,5].binary_search(&2).ok(), Some(1)); + assert_eq!([1i,2,3,4,5].binary_search(&1).ok(), Some(0)); - assert_eq!([2i,4,6,8,10].binary_search_elem(&1).found(), None); - assert_eq!([2i,4,6,8,10].binary_search_elem(&5).found(), None); - assert_eq!([2i,4,6,8,10].binary_search_elem(&4).found(), Some(1)); - assert_eq!([2i,4,6,8,10].binary_search_elem(&10).found(), Some(4)); + assert_eq!([2i,4,6,8,10].binary_search(&1).ok(), None); + assert_eq!([2i,4,6,8,10].binary_search(&5).ok(), None); + assert_eq!([2i,4,6,8,10].binary_search(&4).ok(), Some(1)); + assert_eq!([2i,4,6,8,10].binary_search(&10).ok(), Some(4)); - assert_eq!([2i,4,6,8].binary_search_elem(&1).found(), None); - assert_eq!([2i,4,6,8].binary_search_elem(&5).found(), None); - assert_eq!([2i,4,6,8].binary_search_elem(&4).found(), Some(1)); - assert_eq!([2i,4,6,8].binary_search_elem(&8).found(), Some(3)); + assert_eq!([2i,4,6,8].binary_search(&1).ok(), None); + assert_eq!([2i,4,6,8].binary_search(&5).ok(), None); + assert_eq!([2i,4,6,8].binary_search(&4).ok(), Some(1)); + assert_eq!([2i,4,6,8].binary_search(&8).ok(), Some(3)); - assert_eq!([2i,4,6].binary_search_elem(&1).found(), None); - assert_eq!([2i,4,6].binary_search_elem(&5).found(), None); - assert_eq!([2i,4,6].binary_search_elem(&4).found(), Some(1)); - assert_eq!([2i,4,6].binary_search_elem(&6).found(), Some(2)); + assert_eq!([2i,4,6].binary_search(&1).ok(), None); + assert_eq!([2i,4,6].binary_search(&5).ok(), None); + assert_eq!([2i,4,6].binary_search(&4).ok(), Some(1)); + assert_eq!([2i,4,6].binary_search(&6).ok(), Some(2)); - assert_eq!([2i,4].binary_search_elem(&1).found(), None); - assert_eq!([2i,4].binary_search_elem(&5).found(), None); - assert_eq!([2i,4].binary_search_elem(&2).found(), Some(0)); - assert_eq!([2i,4].binary_search_elem(&4).found(), Some(1)); + assert_eq!([2i,4].binary_search(&1).ok(), None); + assert_eq!([2i,4].binary_search(&5).ok(), None); + assert_eq!([2i,4].binary_search(&2).ok(), Some(0)); + assert_eq!([2i,4].binary_search(&4).ok(), Some(1)); - assert_eq!([2i].binary_search_elem(&1).found(), None); - assert_eq!([2i].binary_search_elem(&5).found(), None); - assert_eq!([2i].binary_search_elem(&2).found(), Some(0)); + assert_eq!([2i].binary_search(&1).ok(), None); + assert_eq!([2i].binary_search(&5).ok(), None); + assert_eq!([2i].binary_search(&2).ok(), Some(0)); - assert_eq!([].binary_search_elem(&1i).found(), None); - assert_eq!([].binary_search_elem(&5i).found(), None); + assert_eq!([].binary_search(&1i).ok(), None); + assert_eq!([].binary_search(&5i).ok(), None); - assert!([1i,1,1,1,1].binary_search_elem(&1).found() != None); - assert!([1i,1,1,1,2].binary_search_elem(&1).found() != None); - assert!([1i,1,1,2,2].binary_search_elem(&1).found() != None); - assert!([1i,1,2,2,2].binary_search_elem(&1).found() != None); - assert_eq!([1i,2,2,2,2].binary_search_elem(&1).found(), Some(0)); + assert!([1i,1,1,1,1].binary_search(&1).ok() != None); + assert!([1i,1,1,1,2].binary_search(&1).ok() != None); + assert!([1i,1,1,2,2].binary_search(&1).ok() != None); + assert!([1i,1,2,2,2].binary_search(&1).ok() != None); + assert_eq!([1i,2,2,2,2].binary_search(&1).ok(), Some(0)); - assert_eq!([1i,2,3,4,5].binary_search_elem(&6).found(), None); - assert_eq!([1i,2,3,4,5].binary_search_elem(&0).found(), None); + assert_eq!([1i,2,3,4,5].binary_search(&6).ok(), None); + assert_eq!([1i,2,3,4,5].binary_search(&0).ok(), None); } #[test] @@ -2042,13 +2117,15 @@ mod tests { #[test] fn test_concat() { let v: [Vec, ..0] = []; - assert_eq!(v.concat_vec(), vec![]); - assert_eq!([vec![1i], vec![2i,3i]].concat_vec(), vec![1, 2, 3]); + let c: Vec = v.concat(); + assert_eq!(c, []); + let d: Vec = [vec![1i], vec![2i,3i]].concat(); + assert_eq!(d, vec![1i, 2, 3]); let v: [&[int], ..2] = [&[1], &[2, 3]]; - assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 3]); - let v: [&[int], ..3] = [&[1], &[2], &[3]]; - assert_eq!(v.connect_vec(&0), vec![1, 0, 2, 0, 3]); + assert_eq!(v.connect(&0), vec![1i, 0, 2, 3]); + let v: [&[int], ..3] = [&[1i], &[2], &[3]]; + assert_eq!(v.connect(&0), vec![1i, 0, 2, 0, 3]); } #[test] @@ -2094,23 +2171,25 @@ mod tests { fn test_remove() { let mut a = vec![1i,2,3,4]; - assert_eq!(a.remove(2), Some(3)); + assert_eq!(a.remove(2), 3); assert_eq!(a, vec![1i,2,4]); - assert_eq!(a.remove(2), Some(4)); + assert_eq!(a.remove(2), 4); assert_eq!(a, vec![1i,2]); - assert_eq!(a.remove(2), None); - assert_eq!(a, vec![1i,2]); - - assert_eq!(a.remove(0), Some(1)); + assert_eq!(a.remove(0), 1); assert_eq!(a, vec![2i]); - assert_eq!(a.remove(0), Some(2)); + assert_eq!(a.remove(0), 2); assert_eq!(a, vec![]); + } - assert_eq!(a.remove(0), None); - assert_eq!(a.remove(10), None); + #[test] + #[should_fail] + fn test_remove_fail() { + let mut a = vec![1i]; + let _ = a.remove(0); + let _ = a.remove(0); } #[test] @@ -2806,7 +2885,7 @@ mod bench { let xss: Vec> = Vec::from_fn(100, |i| range(0u, i).collect()); b.iter(|| { - xss.as_slice().concat_vec() + xss.as_slice().concat(); }); } diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 7c7a7e19a2f..8d5d76f9598 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -77,6 +77,7 @@ use slice::SliceExt; use string::String; use unicode; use vec::Vec; +use slice::SliceConcatExt; pub use core::str::{from_utf8, CharEq, Chars, CharIndices}; pub use core::str::{Bytes, CharSplits, is_utf8}; @@ -93,71 +94,45 @@ pub use core::str::{SplitN, RSplitN}; Section: Creating a string */ -/// Methods for vectors of strings. -#[unstable = "functionality may be replaced with iterators"] -pub trait StrVector for Sized? { - /// Concatenates a vector of strings. - /// - /// # Examples - /// - /// ```rust - /// let first = "Restaurant at the End of the".to_string(); - /// let second = " Universe".to_string(); - /// let string_vec = vec![first, second]; - /// assert_eq!(string_vec.concat(), "Restaurant at the End of the Universe".to_string()); - /// ``` - fn concat(&self) -> String; - - /// Concatenates a vector of strings, placing a given separator between each. - /// - /// # Examples - /// - /// ```rust - /// let first = "Roast".to_string(); - /// let second = "Sirloin Steak".to_string(); - /// let string_vec = vec![first, second]; - /// assert_eq!(string_vec.connect(", "), "Roast, Sirloin Steak".to_string()); - /// ``` - fn connect(&self, sep: &str) -> String; -} - -#[allow(deprecated)] -impl StrVector for [S] { +impl SliceConcatExt for [S] { fn concat(&self) -> String { - if self.is_empty() { + let s = self.as_slice(); + + if s.is_empty() { return String::new(); } // `len` calculation may overflow but push_str will check boundaries - let len = self.iter().map(|s| s.as_slice().len()).sum(); - + let len = s.iter().map(|s| s.as_slice().len()).sum(); let mut result = String::with_capacity(len); - for s in self.iter() { - result.push_str(s.as_slice()); + for s in s.iter() { + result.push_str(s.as_slice()) } result } fn connect(&self, sep: &str) -> String { - if self.is_empty() { + let s = self.as_slice(); + + if s.is_empty() { return String::new(); } // concat is faster if sep.is_empty() { - return self.concat(); + return s.concat(); } // this is wrong without the guarantee that `self` is non-empty // `len` calculation may overflow but push_str but will check boundaries - let len = sep.len() * (self.len() - 1) - + self.iter().map(|s| s.as_slice().len()).sum(); + let len = sep.len() * (s.len() - 1) + + s.iter().map(|s| s.as_slice().len()).sum(); let mut result = String::with_capacity(len); let mut first = true; - for s in self.iter() { + for s in s.iter() { if first { first = false; } else { @@ -169,18 +144,6 @@ impl StrVector for [S] { } } -impl> StrVector for T { - #[inline] - fn concat(&self) -> String { - self.as_slice().concat() - } - - #[inline] - fn connect(&self, sep: &str) -> String { - self.as_slice().connect(sep) - } -} - /* Section: Iterators */ @@ -221,7 +184,7 @@ pub struct Decompositions<'a> { impl<'a> Iterator for Decompositions<'a> { #[inline] fn next(&mut self) -> Option { - match self.buffer.head() { + match self.buffer.first() { Some(&(c, 0)) => { self.sorted = false; self.buffer.remove(0); @@ -268,13 +231,16 @@ impl<'a> Iterator for Decompositions<'a> { self.sorted = true; } - match self.buffer.remove(0) { - Some((c, 0)) => { - self.sorted = false; - Some(c) + if self.buffer.is_empty() { + None + } else { + match self.buffer.remove(0) { + (c, 0) => { + self.sorted = false; + Some(c) + } + (c, _) => Some(c), } - Some((c, _)) => Some(c), - None => None } } @@ -747,7 +713,7 @@ pub trait StrExt for Sized?: ops::Slice { if me.is_empty() { return t.chars().count(); } if t.is_empty() { return me.chars().count(); } - let mut dcol = Vec::from_fn(t.len() + 1, |x| x); + let mut dcol: Vec<_> = range(0, t.len() + 1).collect(); let mut t_last = 0; for (i, sc) in me.chars().enumerate() { @@ -1892,22 +1858,12 @@ mod tests { assert_eq!("ะเทศไท", "ประเทศไทย中华Việt Nam".slice_chars(2, 8)); } - struct S { - x: [String, .. 2] - } - - impl AsSlice for S { - fn as_slice<'a> (&'a self) -> &'a [String] { - &self.x - } - } - fn s(x: &str) -> String { x.into_string() } macro_rules! test_concat { ($expected: expr, $string: expr) => { { - let s = $string.concat(); + let s: String = $string.concat(); assert_eq!($expected, s); } } @@ -1915,22 +1871,10 @@ mod tests { #[test] fn test_concat_for_different_types() { - test_concat!("ab", ["a", "b"]); - test_concat!("ab", [s("a"), s("b")]); + test_concat!("ab", vec![s("a"), s("b")]); test_concat!("ab", vec!["a", "b"]); test_concat!("ab", vec!["a", "b"].as_slice()); test_concat!("ab", vec![s("a"), s("b")]); - - let mut v0 = ["a", "b"]; - let mut v1 = [s("a"), s("b")]; - unsafe { - use std::c_vec::CVec; - - test_concat!("ab", CVec::new(v0.as_mut_ptr(), v0.len())); - test_concat!("ab", CVec::new(v1.as_mut_ptr(), v1.len())); - } - - test_concat!("ab", S { x: [s("a"), s("b")] }); } #[test] @@ -1959,17 +1903,6 @@ mod tests { test_connect!("a-b", vec!["a", "b"], hyphen.as_slice()); test_connect!("a-b", vec!["a", "b"].as_slice(), "-"); test_connect!("a-b", vec![s("a"), s("b")], "-"); - - let mut v0 = ["a", "b"]; - let mut v1 = [s("a"), s("b")]; - unsafe { - use std::c_vec::CVec; - - test_connect!("a-b", CVec::new(v0.as_mut_ptr(), v0.len()), "-"); - test_connect!("a-b", CVec::new(v1.as_mut_ptr(), v1.len()), hyphen.as_slice()); - } - - test_connect!("a-b", S { x: [s("a"), s("b")] }, "-"); } #[test] @@ -3339,7 +3272,7 @@ mod tests { #[cfg(test)] mod bench { use super::*; - use prelude::{SliceExt, IteratorExt, DoubleEndedIteratorExt}; + use prelude::{SliceExt, IteratorExt, DoubleEndedIteratorExt, SliceConcatExt}; use test::Bencher; use test::black_box; @@ -3502,7 +3435,7 @@ mod bench { fn bench_connect(b: &mut Bencher) { let s = "ศไทย中华Việt Nam; Mary had a little lamb, Little lamb"; let sep = "→"; - let v = [s, s, s, s, s, s, s, s, s, s]; + let v = vec![s, s, s, s, s, s, s, s, s, s]; b.iter(|| { assert_eq!(v.connect(sep).len(), s.len() * 10 + sep.len() * 9); }) diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index 9c54fbdd6a7..f703ff99660 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -151,7 +151,7 @@ impl String { let mut i = 0; let total = v.len(); fn unsafe_get(xs: &[u8], i: uint) -> u8 { - unsafe { *xs.unsafe_get(i) } + unsafe { *xs.get_unchecked(i) } } fn safe_get(xs: &[u8], i: uint, total: uint) -> u8 { if i >= total { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e2a9d2f8f63..a1952352bad 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -142,26 +142,9 @@ pub struct Vec { unsafe impl Send for Vec { } unsafe impl Sync for Vec { } -/// A clone-on-write vector -pub type CowVec<'a, T> = Cow<'a, Vec, [T]>; - -impl<'a, T> FromIterator for CowVec<'a, T> where T: Clone { - fn from_iter>(it: I) -> CowVec<'a, T> { - Cow::Owned(FromIterator::from_iter(it)) - } -} - -impl<'a, T: 'a> IntoCow<'a, Vec, [T]> for Vec where T: Clone { - fn into_cow(self) -> CowVec<'a, T> { - Cow::Owned(self) - } -} - -impl<'a, T> IntoCow<'a, Vec, [T]> for &'a [T] where T: Clone { - fn into_cow(self) -> CowVec<'a, T> { - Cow::Borrowed(self) - } -} +//////////////////////////////////////////////////////////////////////////////// +// Inherent methods +//////////////////////////////////////////////////////////////////////////////// impl Vec { /// Constructs a new, empty `Vec`. @@ -190,8 +173,7 @@ impl Vec { /// /// It is important to note that this function does not specify the *length* of the returned /// vector, but only the *capacity*. (For an explanation of the difference between length and - /// capacity, see the main `Vec` docs above, 'Capacity and reallocation'.) To create a - /// vector of a given length, use `Vec::from_elem` or `Vec::from_fn`. + /// capacity, see the main `Vec` docs above, 'Capacity and reallocation'.) /// /// # Examples /// @@ -225,30 +207,11 @@ impl Vec { } } - /// Creates and initializes a `Vec`. - /// - /// Creates a `Vec` of size `length` and initializes the elements to the value returned by - /// the closure `op`. - /// - /// # Examples - /// - /// ``` - /// let vec = Vec::from_fn(3, |idx| idx * 2); - /// assert_eq!(vec, vec![0, 2, 4]); - /// ``` + /// Deprecated: use `iter::range(0, length).map(op).collect()` instead #[inline] - #[unstable = "the naming is uncertain as well as this migrating to unboxed \ - closures in the future"] - pub fn from_fn(length: uint, mut op: F) -> Vec where F: FnMut(uint) -> T { - unsafe { - let mut xs = Vec::with_capacity(length); - while xs.len < length { - let len = xs.len; - ptr::write(xs.unsafe_mut(len), op(len)); - xs.len += 1; - } - xs - } + #[deprecated = "use iter::range(0, length).map(op).collect() instead"] + pub fn from_fn(length: uint, op: F) -> Vec where F: FnMut(uint) -> T { + range(0, length).map(op).collect() } /// Creates a `Vec` directly from the raw components of another vector. @@ -285,7 +248,7 @@ impl Vec { /// } /// } /// ``` - #[unstable = "needs finalization"] + #[stable] pub unsafe fn from_raw_parts(ptr: *mut T, length: uint, capacity: uint) -> Vec { Vec { ptr: NonZero::new(ptr), len: length, cap: capacity } @@ -297,7 +260,7 @@ impl Vec { /// owned by the returned `Vec`. The elements of the buffer are copied into the vector /// without cloning, as if `ptr::read()` were called on them. #[inline] - #[unstable = "just renamed from raw::from_buf"] + #[unstable = "may be better expressed via composition"] pub unsafe fn from_raw_buf(ptr: *const T, elts: uint) -> Vec { let mut dst = Vec::with_capacity(elts); dst.set_len(elts); @@ -305,413 +268,15 @@ impl Vec { dst } - /// Consumes the `Vec`, partitioning it based on a predicate. - /// - /// Partitions the `Vec` into two `Vec`s `(A,B)`, where all elements of `A` satisfy `f` - /// and all elements of `B` do not. The order of elements is preserved. - /// - /// # Examples - /// - /// ``` - /// let vec = vec![1i, 2i, 3i, 4i]; - /// let (even, odd) = vec.partition(|&n| n % 2 == 0); - /// assert_eq!(even, vec![2, 4]); - /// assert_eq!(odd, vec![1, 3]); - /// ``` + /// Deprecated: use `into_iter().partition(f)` instead. #[inline] - #[experimental] - pub fn partition(self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { - let mut lefts = Vec::new(); - let mut rights = Vec::new(); - - for elt in self.into_iter() { - if f(&elt) { - lefts.push(elt); - } else { - rights.push(elt); - } - } - - (lefts, rights) - } -} - -impl Vec { - /// Constructs a `Vec` with copies of a value. - /// - /// Creates a `Vec` with `length` copies of `value`. - /// - /// # Examples - /// - /// ``` - /// let vec = Vec::from_elem(3, "hi"); - /// println!("{}", vec); // prints [hi, hi, hi] - /// ``` - #[inline] - #[unstable = "this functionality may become more generic over all collections"] - pub fn from_elem(length: uint, value: T) -> Vec { - unsafe { - let mut xs = Vec::with_capacity(length); - while xs.len < length { - let len = xs.len; - ptr::write(xs.unsafe_mut(len), - value.clone()); - xs.len += 1; - } - xs - } + #[deprecated = "use into_iter().partition(f) instead"] + pub fn partition(self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { + self.into_iter().partition(f) } - /// Appends all elements in a slice to the `Vec`. - /// - /// Iterates over the slice `other`, clones each element, and then appends - /// it to this `Vec`. The `other` vector is traversed in-order. - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec![1i]; - /// vec.push_all(&[2i, 3, 4]); - /// assert_eq!(vec, vec![1, 2, 3, 4]); - /// ``` - #[inline] - #[experimental] - pub fn push_all(&mut self, other: &[T]) { - self.reserve(other.len()); - - for i in range(0, other.len()) { - let len = self.len(); - - // Unsafe code so this can be optimised to a memcpy (or something similarly - // fast) when T is Copy. LLVM is easily confused, so any extra operations - // during the loop can prevent this optimisation. - unsafe { - ptr::write( - self.unsafe_mut(len), - other.unsafe_get(i).clone()); - self.set_len(len + 1); - } - } - } - - /// Grows the `Vec` in-place. - /// - /// Adds `n` copies of `value` to the `Vec`. - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec!["hello"]; - /// vec.grow(2, "world"); - /// assert_eq!(vec, vec!["hello", "world", "world"]); - /// ``` - #[stable] - pub fn grow(&mut self, n: uint, value: T) { - self.reserve(n); - let mut i: uint = 0u; - - while i < n { - self.push(value.clone()); - i += 1u; - } - } - - /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`. - /// - /// Calls either `extend()` or `truncate()` depending on whether `new_len` - /// is larger than the current value of `len()` or not. - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec!["hello"]; - /// vec.resize(3, "world"); - /// assert_eq!(vec, vec!["hello", "world", "world"]); - /// - /// let mut vec = vec![1i, 2, 3, 4]; - /// vec.resize(2, 0); - /// assert_eq!(vec, vec![1, 2]); - /// ``` - #[unstable = "matches collection reform specification; waiting for dust to settle"] - pub fn resize(&mut self, new_len: uint, value: T) { - let len = self.len(); - - if new_len > len { - self.extend(repeat(value).take(new_len - len)); - } else { - self.truncate(new_len); - } - } - - /// Partitions a vector based on a predicate. - /// - /// Clones the elements of the vector, partitioning them into two `Vec`s - /// `(a, b)`, where all elements of `a` satisfy `f` and all elements of `b` - /// do not. The order of elements is preserved. - /// - /// # Examples - /// - /// ``` - /// let vec = vec![1i, 2, 3, 4]; - /// let (even, odd) = vec.partitioned(|&n| n % 2 == 0); - /// assert_eq!(even, vec![2i, 4]); - /// assert_eq!(odd, vec![1i, 3]); - /// ``` - #[experimental] - pub fn partitioned(&self, mut f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { - let mut lefts = Vec::new(); - let mut rights = Vec::new(); - - for elt in self.iter() { - if f(elt) { - lefts.push(elt.clone()); - } else { - rights.push(elt.clone()); - } - } - - (lefts, rights) - } -} - -#[stable] -impl Clone for Vec { - fn clone(&self) -> Vec { self.as_slice().to_vec() } - - fn clone_from(&mut self, other: &Vec) { - // drop anything in self that will not be overwritten - if self.len() > other.len() { - self.truncate(other.len()) - } - - // reuse the contained values' allocations/resources. - for (place, thing) in self.iter_mut().zip(other.iter()) { - place.clone_from(thing) - } - - // self.len <= other.len due to the truncate above, so the - // slice here is always in-bounds. - let slice = other[self.len()..]; - self.push_all(slice); - } -} - -#[experimental = "waiting on Index stability"] -impl Index for Vec { - #[inline] - fn index<'a>(&'a self, index: &uint) -> &'a T { - &self.as_slice()[*index] - } -} - -impl IndexMut for Vec { - #[inline] - fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T { - &mut self.as_mut_slice()[*index] - } -} - -impl ops::Slice for Vec { - #[inline] - fn as_slice_<'a>(&'a self) -> &'a [T] { - self.as_slice() - } - - #[inline] - fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { - self.as_slice().slice_from_or_fail(start) - } - - #[inline] - fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { - self.as_slice().slice_to_or_fail(end) - } - #[inline] - fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { - self.as_slice().slice_or_fail(start, end) - } -} - -impl ops::SliceMut for Vec { - #[inline] - fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { - self.as_mut_slice() - } - - #[inline] - fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { - self.as_mut_slice().slice_from_or_fail_mut(start) - } - - #[inline] - fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { - self.as_mut_slice().slice_to_or_fail_mut(end) - } - #[inline] - fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { - self.as_mut_slice().slice_or_fail_mut(start, end) - } -} - -#[experimental = "waiting on Deref stability"] -impl ops::Deref<[T]> for Vec { - fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() } -} - -#[experimental = "waiting on DerefMut stability"] -impl ops::DerefMut<[T]> for Vec { - fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() } -} - -#[experimental = "waiting on FromIterator stability"] -impl FromIterator for Vec { - #[inline] - fn from_iter>(mut iterator: I) -> Vec { - let (lower, _) = iterator.size_hint(); - let mut vector = Vec::with_capacity(lower); - for element in iterator { - vector.push(element) - } - vector - } -} - -#[experimental = "waiting on Extend stability"] -impl Extend for Vec { - #[inline] - fn extend>(&mut self, mut iterator: I) { - let (lower, _) = iterator.size_hint(); - self.reserve(lower); - for element in iterator { - self.push(element) - } - } -} - -#[stable] -impl PartialEq> for Vec where A: PartialEq { - #[inline] - fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } -} - -macro_rules! impl_eq { - ($lhs:ty, $rhs:ty) => { - #[stable] - impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq { - #[inline] - fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } - } - - #[stable] - impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq { - #[inline] - fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) } - } - } -} - -impl_eq! { Vec, &'b [B] } -impl_eq! { Vec, &'b mut [B] } - -#[stable] -impl<'a, A, B> PartialEq> for CowVec<'a, A> where A: PartialEq + Clone { - #[inline] - fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } -} - -#[stable] -impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { - #[inline] - fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } -} - -macro_rules! impl_eq_for_cowvec { - ($rhs:ty) => { - #[stable] - impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq + Clone { - #[inline] - fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } - } - - #[stable] - impl<'a, 'b, A, B> PartialEq> for $rhs where A: Clone, B: PartialEq { - #[inline] - fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } - #[inline] - fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } - } - } -} - -impl_eq_for_cowvec! { &'b [B] } -impl_eq_for_cowvec! { &'b mut [B] } - -#[stable] -impl PartialOrd for Vec { - #[inline] - fn partial_cmp(&self, other: &Vec) -> Option { - self.as_slice().partial_cmp(other.as_slice()) - } -} - -#[stable] -impl Eq for Vec {} - -#[allow(deprecated)] -#[deprecated = "Use overloaded `core::cmp::PartialEq`"] -impl> Equiv for Vec { - #[inline] - fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } -} - -#[stable] -impl Ord for Vec { - #[inline] - fn cmp(&self, other: &Vec) -> Ordering { - self.as_slice().cmp(other.as_slice()) - } -} - -impl> Hash for Vec { - #[inline] - fn hash(&self, state: &mut S) { - self.as_slice().hash(state); - } -} - -// FIXME: #13996: need a way to mark the return value as `noalias` -#[inline(never)] -unsafe fn alloc_or_realloc(ptr: *mut T, old_size: uint, size: uint) -> *mut T { - if old_size == 0 { - allocate(size, mem::min_align_of::()) as *mut T - } else { - reallocate(ptr as *mut u8, old_size, size, mem::min_align_of::()) as *mut T - } -} - -#[inline] -unsafe fn dealloc(ptr: *mut T, len: uint) { - if mem::size_of::() != 0 { - deallocate(ptr as *mut u8, - len * mem::size_of::(), - mem::min_align_of::()) - } -} - -impl Vec { - /// Returns the number of elements the vector can hold without reallocating. + /// Returns the number of elements the vector can hold without + /// reallocating. /// /// # Examples /// @@ -745,22 +310,23 @@ impl Vec { /// vec.reserve(10); /// assert!(vec.capacity() >= 11); /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] + #[stable] pub fn reserve(&mut self, additional: uint) { if self.cap - self.len < additional { let err_msg = "Vec::reserve: `uint` overflow"; let new_cap = self.len.checked_add(additional).expect(err_msg) - .checked_next_power_of_two().expect(err_msg); + .checked_next_power_of_two().expect(err_msg); self.grow_capacity(new_cap); } } - /// Reserves the minimum capacity for exactly `additional` more elements to be inserted in the - /// given `Vec`. Does nothing if the capacity is already sufficient. + /// Reserves the minimum capacity for exactly `additional` more elements to + /// be inserted in the given `Vec`. Does nothing if the capacity is already + /// sufficient. /// - /// Note that the allocator may give the collection more space than it requests. Therefore - /// capacity can not be relied upon to be precisely minimal. Prefer `reserve` if future - /// insertions are expected. + /// Note that the allocator may give the collection more space than it + /// requests. Therefore capacity can not be relied upon to be precisely + /// minimal. Prefer `reserve` if future insertions are expected. /// /// # Panics /// @@ -773,7 +339,7 @@ impl Vec { /// vec.reserve_exact(10); /// assert!(vec.capacity() >= 11); /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] + #[stable] pub fn reserve_exact(&mut self, additional: uint) { if self.cap - self.len < additional { match self.len.checked_add(additional) { @@ -785,17 +351,15 @@ impl Vec { /// Shrinks the capacity of the vector as much as possible. /// - /// It will drop down as close as possible to the length but the allocator may still inform the - /// vector that there is space for a few more elements. + /// It will drop down as close as possible to the length but the allocator + /// may still inform the vector that there is space for a few more elements. /// /// # Examples /// /// ``` /// let mut vec: Vec = Vec::with_capacity(10); - /// /// vec.push_all(&[1, 2, 3]); /// assert_eq!(vec.capacity(), 10); - /// /// vec.shrink_to_fit(); /// assert!(vec.capacity() >= 3); /// ``` @@ -827,8 +391,9 @@ impl Vec { /// Convert the vector into Box<[T]>. /// - /// Note that this will drop any excess capacity. Calling this and converting back to a vector - /// with `into_vec()` is equivalent to calling `shrink_to_fit()`. + /// Note that this will drop any excess capacity. Calling this and + /// converting back to a vector with `into_vec()` is equivalent to calling + /// `shrink_to_fit()`. #[experimental] pub fn into_boxed_slice(mut self) -> Box<[T]> { self.shrink_to_fit(); @@ -851,7 +416,7 @@ impl Vec { /// vec.truncate(2); /// assert_eq!(vec, vec![1, 2]); /// ``` - #[unstable = "matches collection reform specification; waiting on panic semantics"] + #[stable] pub fn truncate(&mut self, len: uint) { unsafe { // drop any extra elements @@ -859,7 +424,7 @@ impl Vec { // decrement len before the read(), so a panic on Drop doesn't // re-drop the just-failed value. self.len -= 1; - ptr::read(self.unsafe_get(self.len)); + ptr::read(self.get_unchecked(self.len)); } } } @@ -885,21 +450,21 @@ impl Vec { } } - /// Creates a consuming iterator, that is, one that moves each value out of the vector (from - /// start to end). The vector cannot be used after calling this. + /// Creates a consuming iterator, that is, one that moves each value out of + /// the vector (from start to end). The vector cannot be used after calling + /// this. /// /// # Examples /// /// ``` /// let v = vec!["a".to_string(), "b".to_string()]; - /// /// for s in v.into_iter() { /// // s has type String, not &String /// println!("{}", s); /// } /// ``` #[inline] - #[unstable = "matches collection reform specification, waiting for dust to settle"] + #[stable] pub fn into_iter(self) -> IntoIter { unsafe { let ptr = *self.ptr; @@ -917,8 +482,9 @@ impl Vec { /// Sets the length of a vector. /// - /// This will explicitly set the size of the vector, without actually modifying its buffers, so - /// it is up to the caller to ensure that the vector is actually the specified size. + /// This will explicitly set the size of the vector, without actually + /// modifying its buffers, so it is up to the caller to ensure that the + /// vector is actually the specified size. /// /// # Examples /// @@ -934,44 +500,41 @@ impl Vec { self.len = len; } - /// Removes an element from anywhere in the vector and return it, replacing it with the last - /// element. + /// Removes an element from anywhere in the vector and return it, replacing + /// it with the last element. /// /// This does not preserve ordering, but is O(1). /// - /// Returns `None` if `index` is out of bounds. + /// # Panics + /// + /// Panics if `index` is out of bounds. /// /// # Examples /// /// ``` /// let mut v = vec!["foo", "bar", "baz", "qux"]; /// - /// assert_eq!(v.swap_remove(1), Some("bar")); + /// assert_eq!(v.swap_remove(1), "bar"); /// assert_eq!(v, vec!["foo", "qux", "baz"]); /// - /// assert_eq!(v.swap_remove(0), Some("foo")); + /// assert_eq!(v.swap_remove(0), "foo"); /// assert_eq!(v, vec!["baz", "qux"]); - /// - /// assert_eq!(v.swap_remove(2), None); /// ``` #[inline] - #[unstable = "the naming of this function may be altered"] - pub fn swap_remove(&mut self, index: uint) -> Option { + #[stable] + pub fn swap_remove(&mut self, index: uint) -> T { let length = self.len(); - if length > 0 && index < length - 1 { - self.swap(index, length - 1); - } else if index >= length { - return None - } - self.pop() + self.swap(index, length - 1); + self.pop().unwrap() } - /// Inserts an element at position `index` within the vector, shifting all elements after - /// position `i` one position to the right. + /// Inserts an element at position `index` within the vector, shifting all + /// elements after position `i` one position to the right. /// /// # Panics /// - /// Panics if `index` is not between `0` and the vector's length (both bounds inclusive). + /// Panics if `index` is not between `0` and the vector's length (both + /// bounds inclusive). /// /// # Examples /// @@ -982,7 +545,7 @@ impl Vec { /// vec.insert(4, 5); /// assert_eq!(vec, vec![1, 4, 2, 3, 5]); /// ``` - #[unstable = "panic semantics need settling"] + #[stable] pub fn insert(&mut self, index: uint, element: T) { let len = self.len(); assert!(index <= len); @@ -1004,49 +567,46 @@ impl Vec { } } - /// Removes and returns the element at position `index` within the vector, shifting all - /// elements after position `index` one position to the left. Returns `None` if `i` is out of - /// bounds. + /// Removes and returns the element at position `index` within the vector, + /// shifting all elements after position `index` one position to the left. + /// + /// # Panics + /// + /// Panics if `i` is out of bounds. /// /// # Examples /// /// ``` /// let mut v = vec![1i, 2, 3]; - /// assert_eq!(v.remove(1), Some(2)); - /// assert_eq!(v, vec![1, 3]); - /// - /// assert_eq!(v.remove(4), None); - /// // v is unchanged: + /// assert_eq!(v.remove(1), 2); /// assert_eq!(v, vec![1, 3]); /// ``` - #[unstable = "panic semantics need settling"] - pub fn remove(&mut self, index: uint) -> Option { + #[stable] + pub fn remove(&mut self, index: uint) -> T { let len = self.len(); - if index < len { - unsafe { // infallible - let ret; - { - // the place we are taking from. - let ptr = self.as_mut_ptr().offset(index as int); - // copy it out, unsafely having a copy of the value on - // the stack and in the vector at the same time. - ret = Some(ptr::read(ptr as *const T)); + assert!(index < len); + unsafe { // infallible + let ret; + { + // the place we are taking from. + let ptr = self.as_mut_ptr().offset(index as int); + // copy it out, unsafely having a copy of the value on + // the stack and in the vector at the same time. + ret = ptr::read(ptr as *const T); - // Shift everything down to fill in that spot. - ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1); - } - self.set_len(len - 1); - ret + // Shift everything down to fill in that spot. + ptr::copy_memory(ptr, &*ptr.offset(1), len - index - 1); } - } else { - None + self.set_len(len - 1); + ret } } /// Retains only the elements specified by the predicate. /// - /// In other words, remove all elements `e` such that `f(&e)` returns false. This method - /// operates in place and preserves the order of the retained elements. + /// In other words, remove all elements `e` such that `f(&e)` returns false. + /// This method operates in place and preserves the order of the retained + /// elements. /// /// # Examples /// @@ -1055,7 +615,7 @@ impl Vec { /// vec.retain(|&x| x%2 == 0); /// assert_eq!(vec, vec![2, 4]); /// ``` - #[unstable = "the closure argument may become an unboxed closure"] + #[stable] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool { let len = self.len(); let mut del = 0u; @@ -1075,24 +635,10 @@ impl Vec { } } - /// Expands a vector in place, initializing the new elements to the result of a function. - /// - /// The vector is grown by `n` elements. The i-th new element are initialized to the value - /// returned by `f(i)` where `i` is in the range [0, n). - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec![0u, 1]; - /// vec.grow_fn(3, |i| i); - /// assert_eq!(vec, vec![0, 1, 0, 1, 2]); - /// ``` - #[unstable = "this function may be renamed or change to unboxed closures"] - pub fn grow_fn(&mut self, n: uint, mut f: F) where F: FnMut(uint) -> T { - self.reserve(n); - for i in range(0u, n) { - self.push(f(i)); - } + /// Deprecated: use `extend(range(0, n).map(f))` instead. + #[deprecated = "use extend(range(0, n).map(f)) instead"] + pub fn grow_fn(&mut self, n: uint, f: F) where F: FnMut(uint) -> T { + self.extend(range(0, n).map(f)); } /// Appends an element to the back of a collection. @@ -1112,7 +658,8 @@ impl Vec { #[stable] 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 + // 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 @@ -1153,7 +700,7 @@ impl Vec { } else { unsafe { self.len -= 1; - Some(ptr::read(self.unsafe_get(self.len()))) + Some(ptr::read(self.get_unchecked(self.len()))) } } } @@ -1230,505 +777,9 @@ impl Vec { /// v.push(1i); /// assert!(!v.is_empty()); /// ``` - #[unstable = "matches collection reform specification, waiting for dust to settle"] + #[stable] pub fn is_empty(&self) -> bool { self.len() == 0 } - /// Reserves capacity for exactly `capacity` elements in the given vector. - /// - /// If the capacity for `self` is already equal to or greater than the - /// requested capacity, then no action is taken. - fn grow_capacity(&mut self, capacity: uint) { - if mem::size_of::() == 0 { return } - - if capacity > self.cap { - let size = capacity.checked_mul(mem::size_of::()) - .expect("capacity overflow"); - unsafe { - let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::(), size); - if ptr.is_null() { ::alloc::oom() } - self.ptr = NonZero::new(ptr); - } - self.cap = capacity; - } - } -} - -impl Vec { - /// Removes consecutive repeated elements in the vector. - /// - /// If the vector is sorted, this removes all duplicates. - /// - /// # Examples - /// - /// ``` - /// let mut vec = vec![1i, 2, 2, 3, 2]; - /// - /// vec.dedup(); - /// - /// assert_eq!(vec, vec![1i, 2, 3, 2]); - /// ``` - #[unstable = "this function may be renamed"] - pub fn dedup(&mut self) { - unsafe { - // Although we have a mutable reference to `self`, we cannot make - // *arbitrary* changes. The `PartialEq` comparisons could panic, so we - // must ensure that the vector is in a valid state at all time. - // - // The way that we handle this is by using swaps; we iterate - // over all the elements, swapping as we go so that at the end - // the elements we wish to keep are in the front, and those we - // wish to reject are at the back. We can then truncate the - // vector. This operation is still O(n). - // - // Example: We start in this state, where `r` represents "next - // read" and `w` represents "next_write`. - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 1 | 2 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Comparing self[r] against self[w-1], this is not a duplicate, so - // we swap self[r] and self[w] (no effect as r==w) and then increment both - // r and w, leaving us with: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 1 | 2 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Comparing self[r] against self[w-1], this value is a duplicate, - // so we increment `r` but leave everything else unchanged: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 1 | 2 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Comparing self[r] against self[w-1], this is not a duplicate, - // so swap self[r] and self[w] and advance r and w: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 2 | 1 | 3 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Not a duplicate, repeat: - // - // r - // +---+---+---+---+---+---+ - // | 0 | 1 | 2 | 3 | 1 | 3 | - // +---+---+---+---+---+---+ - // w - // - // Duplicate, advance r. End of vec. Truncate to w. - - let ln = self.len(); - if ln < 1 { return; } - - // Avoid bounds checks by using unsafe pointers. - let p = self.as_mut_ptr(); - let mut r = 1; - let mut w = 1; - - while r < ln { - let p_r = p.offset(r as int); - let p_wm1 = p.offset((w - 1) as int); - if *p_r != *p_wm1 { - if r != w { - let p_w = p_wm1.offset(1); - mem::swap(&mut *p_r, &mut *p_w); - } - w += 1; - } - r += 1; - } - - self.truncate(w); - } - } -} - -impl AsSlice for Vec { - /// Returns a slice into `self`. - /// - /// # Examples - /// - /// ``` - /// fn foo(slice: &[int]) {} - /// - /// let vec = vec![1i, 2]; - /// foo(vec.as_slice()); - /// ``` - #[inline] - #[stable] - fn as_slice<'a>(&'a self) -> &'a [T] { - unsafe { - mem::transmute(RawSlice { - data: *self.ptr as *const T, - len: self.len - }) - } - } -} - -impl<'a, T: Clone> Add<&'a [T], Vec> for Vec { - #[inline] - fn add(mut self, rhs: &[T]) -> Vec { - self.push_all(rhs); - self - } -} - -#[unsafe_destructor] -impl Drop for Vec { - fn drop(&mut self) { - // This is (and should always remain) a no-op if the fields are - // zeroed (when moving out, because of #[unsafe_no_drop_flag]). - if self.cap != 0 { - unsafe { - for x in self.iter() { - ptr::read(x); - } - dealloc(*self.ptr, self.cap) - } - } - } -} - -#[stable] -impl Default for Vec { - #[stable] - fn default() -> Vec { - Vec::new() - } -} - -#[experimental = "waiting on Show stability"] -impl fmt::Show for Vec { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.as_slice().fmt(f) - } -} - -/// An iterator that moves out of a vector. -pub struct IntoIter { - allocation: *mut T, // the block of memory allocated for the vector - cap: uint, // the capacity of the vector - ptr: *const T, - end: *const T -} - -impl IntoIter { - /// Drops all items that have not yet been moved and returns the empty vector. - #[inline] - #[unstable] - pub fn into_inner(mut self) -> Vec { - unsafe { - for _x in self { } - let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self; - mem::forget(self); - Vec { ptr: NonZero::new(allocation), cap: cap, len: 0 } - } - } - - /// Deprecated, use .into_inner() instead - #[deprecated = "use .into_inner() instead"] - pub fn unwrap(self) -> Vec { self.into_inner() } -} - -impl Iterator for IntoIter { - #[inline] - fn next<'a>(&'a mut self) -> Option { - unsafe { - if self.ptr == self.end { - None - } else { - if mem::size_of::() == 0 { - // purposefully don't use 'ptr.offset' because for - // vectors with 0-size elements this would return the - // same pointer. - self.ptr = mem::transmute(self.ptr as uint + 1); - - // Use a non-null pointer value - Some(ptr::read(mem::transmute(1u))) - } else { - let old = self.ptr; - self.ptr = self.ptr.offset(1); - - Some(ptr::read(old)) - } - } - } - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - let diff = (self.end as uint) - (self.ptr as uint); - let size = mem::size_of::(); - let exact = diff / (if size == 0 {1} else {size}); - (exact, Some(exact)) - } -} - -impl DoubleEndedIterator for IntoIter { - #[inline] - fn next_back<'a>(&'a mut self) -> Option { - unsafe { - if self.end == self.ptr { - None - } else { - if mem::size_of::() == 0 { - // See above for why 'ptr.offset' isn't used - self.end = mem::transmute(self.end as uint - 1); - - // Use a non-null pointer value - Some(ptr::read(mem::transmute(1u))) - } else { - self.end = self.end.offset(-1); - - Some(ptr::read(mem::transmute(self.end))) - } - } - } - } -} - -impl ExactSizeIterator for IntoIter {} - -#[unsafe_destructor] -impl Drop for IntoIter { - fn drop(&mut self) { - // destroy the remaining elements - if self.cap != 0 { - for _x in *self {} - unsafe { - dealloc(self.allocation, self.cap); - } - } - } -} - -/// An iterator that drains a vector. -#[unsafe_no_drop_flag] -pub struct Drain<'a, T> { - ptr: *const T, - end: *const T, - marker: ContravariantLifetime<'a>, -} - -impl<'a, T> Iterator for Drain<'a, T> { - #[inline] - fn next(&mut self) -> Option { - unsafe { - if self.ptr == self.end { - None - } else { - if mem::size_of::() == 0 { - // purposefully don't use 'ptr.offset' because for - // vectors with 0-size elements this would return the - // same pointer. - self.ptr = mem::transmute(self.ptr as uint + 1); - - // Use a non-null pointer value - Some(ptr::read(mem::transmute(1u))) - } else { - let old = self.ptr; - self.ptr = self.ptr.offset(1); - - Some(ptr::read(old)) - } - } - } - } - - #[inline] - fn size_hint(&self) -> (uint, Option) { - let diff = (self.end as uint) - (self.ptr as uint); - let size = mem::size_of::(); - let exact = diff / (if size == 0 {1} else {size}); - (exact, Some(exact)) - } -} - -impl<'a, T> DoubleEndedIterator for Drain<'a, T> { - #[inline] - fn next_back(&mut self) -> Option { - unsafe { - if self.end == self.ptr { - None - } else { - if mem::size_of::() == 0 { - // See above for why 'ptr.offset' isn't used - self.end = mem::transmute(self.end as uint - 1); - - // Use a non-null pointer value - Some(ptr::read(mem::transmute(1u))) - } else { - self.end = self.end.offset(-1); - - Some(ptr::read(self.end)) - } - } - } - } -} - -impl<'a, T> ExactSizeIterator for Drain<'a, T> {} - -#[unsafe_destructor] -impl<'a, T> Drop for Drain<'a, T> { - fn drop(&mut self) { - // self.ptr == self.end == null if drop has already been called, - // so we can use #[unsafe_no_drop_flag]. - - // destroy the remaining elements - for _x in *self {} - } -} - -/// Converts an iterator of pairs into a pair of vectors. -/// -/// Returns a tuple containing two vectors where the i-th element of the first vector contains the -/// first element of the i-th tuple of the input iterator, and the i-th element of the second -/// vector contains the second element of the i-th tuple of the input iterator. -#[unstable = "this functionality may become more generic over time"] -pub fn unzip>(mut iter: V) -> (Vec, Vec) { - let (lo, _) = iter.size_hint(); - let mut ts = Vec::with_capacity(lo); - let mut us = Vec::with_capacity(lo); - for (t, u) in iter { - ts.push(t); - us.push(u); - } - (ts, us) -} - -/// Wrapper type providing a `&Vec` reference via `Deref`. -#[experimental] -pub struct DerefVec<'a, T> { - x: Vec, - l: ContravariantLifetime<'a> -} - -impl<'a, T> Deref> for DerefVec<'a, T> { - fn deref<'b>(&'b self) -> &'b Vec { - &self.x - } -} - -// Prevent the inner `Vec` from attempting to deallocate memory. -#[unsafe_destructor] -impl<'a, T> Drop for DerefVec<'a, T> { - fn drop(&mut self) { - self.x.len = 0; - self.x.cap = 0; - } -} - -/// Convert a slice to a wrapper type providing a `&Vec` reference. -#[experimental] -pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> { - unsafe { - DerefVec { - x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()), - l: ContravariantLifetime::<'a> - } - } -} - -/// Unsafe vector operations. -#[deprecated] -pub mod raw { - use super::Vec; - - /// Constructs a vector from an unsafe pointer to a buffer. - /// - /// The elements of the buffer are copied into the vector without cloning, - /// as if `ptr::read()` were called on them. - #[inline] - #[deprecated = "renamed to Vec::from_raw_buf"] - pub unsafe fn from_buf(ptr: *const T, elts: uint) -> Vec { - Vec::from_raw_buf(ptr, elts) - } -} - -/// An owned, partially type-converted vector of elements with non-zero size. -/// -/// `T` and `U` must have the same, non-zero size. They must also have the same -/// alignment. -/// -/// When the destructor of this struct runs, all `U`s from `start_u` (incl.) to -/// `end_u` (excl.) and all `T`s from `start_t` (incl.) to `end_t` (excl.) are -/// destructed. Additionally the underlying storage of `vec` will be freed. -struct PartialVecNonZeroSized { - vec: Vec, - - start_u: *mut U, - end_u: *mut U, - start_t: *mut T, - end_t: *mut T, -} - -/// An owned, partially type-converted vector of zero-sized elements. -/// -/// When the destructor of this struct runs, all `num_t` `T`s and `num_u` `U`s -/// are destructed. -struct PartialVecZeroSized { - num_t: uint, - num_u: uint, - marker_t: InvariantType, - marker_u: InvariantType, -} - -#[unsafe_destructor] -impl Drop for PartialVecNonZeroSized { - fn drop(&mut self) { - unsafe { - // `vec` hasn't been modified until now. As it has a length - // currently, this would run destructors of `T`s which might not be - // there. So at first, set `vec`s length to `0`. This must be done - // at first to remain memory-safe as the destructors of `U` or `T` - // might cause unwinding where `vec`s destructor would be executed. - self.vec.set_len(0); - - // We have instances of `U`s and `T`s in `vec`. Destruct them. - while self.start_u != self.end_u { - let _ = ptr::read(self.start_u as *const U); // Run a `U` destructor. - self.start_u = self.start_u.offset(1); - } - while self.start_t != self.end_t { - let _ = ptr::read(self.start_t as *const T); // Run a `T` destructor. - self.start_t = self.start_t.offset(1); - } - // After this destructor ran, the destructor of `vec` will run, - // deallocating the underlying memory. - } - } -} - -#[unsafe_destructor] -impl Drop for PartialVecZeroSized { - fn drop(&mut self) { - unsafe { - // Destruct the instances of `T` and `U` this struct owns. - while self.num_t != 0 { - let _: T = mem::uninitialized(); // Run a `T` destructor. - self.num_t -= 1; - } - while self.num_u != 0 { - let _: U = mem::uninitialized(); // Run a `U` destructor. - self.num_u -= 1; - } - } - } -} - -impl Vec { /// Converts a `Vec` to a `Vec` where `T` and `U` have the same /// size and in case they are not zero-sized the same minimal alignment. /// @@ -1750,6 +801,7 @@ impl Vec { /// let newtyped_bytes = bytes.map_in_place(|x| Newtype(x)); /// assert_eq!(newtyped_bytes.as_slice(), [Newtype(0x11), Newtype(0x22)].as_slice()); /// ``` + #[experimental = "API may change to provide stronger guarantees"] pub fn map_in_place(self, mut f: F) -> Vec where F: FnMut(T) -> U { // FIXME: Assert statically that the types `T` and `U` have the same // size. @@ -1926,6 +978,516 @@ impl Vec { } } +impl Vec { + /// Deprecated: use `repeat(value).take(length).collect()` instead. + #[inline] + #[deprecated = "use repeat(value).take(length).collect() instead"] + pub fn from_elem(length: uint, value: T) -> Vec { + repeat(value).take(length).collect() + } + + /// Resizes the `Vec` in-place so that `len()` is equal to `new_len`. + /// + /// Calls either `extend()` or `truncate()` depending on whether `new_len` + /// is larger than the current value of `len()` or not. + /// + /// # Examples + /// + /// ``` + /// let mut vec = vec!["hello"]; + /// vec.resize(3, "world"); + /// assert_eq!(vec, vec!["hello", "world", "world"]); + /// + /// let mut vec = vec![1i, 2, 3, 4]; + /// vec.resize(2, 0); + /// assert_eq!(vec, vec![1, 2]); + /// ``` + #[unstable = "matches collection reform specification; waiting for dust to settle"] + pub fn resize(&mut self, new_len: uint, value: T) { + let len = self.len(); + + if new_len > len { + self.extend(repeat(value).take(new_len - len)); + } else { + self.truncate(new_len); + } + } + + /// Appends all elements in a slice to the `Vec`. + /// + /// Iterates over the slice `other`, clones each element, and then appends + /// it to this `Vec`. The `other` vector is traversed in-order. + /// + /// # Examples + /// + /// ``` + /// let mut vec = vec![1i]; + /// vec.push_all(&[2i, 3, 4]); + /// assert_eq!(vec, vec![1, 2, 3, 4]); + /// ``` + #[inline] + #[experimental = "likely to be replaced by a more optimized extend"] + pub fn push_all(&mut self, other: &[T]) { + self.reserve(other.len()); + + for i in range(0, other.len()) { + let len = self.len(); + + // Unsafe code so this can be optimised to a memcpy (or something similarly + // fast) when T is Copy. LLVM is easily confused, so any extra operations + // during the loop can prevent this optimisation. + unsafe { + ptr::write( + self.get_unchecked_mut(len), + other.get_unchecked(i).clone()); + self.set_len(len + 1); + } + } + } + + /// Deprecated: use `extend(repeat(value).take(n))` instead + #[deprecated = "use extend(repeat(value).take(n)) instead"] + pub fn grow(&mut self, n: uint, value: T) { + self.extend(repeat(value).take(n)) + } + + /// Deprecated: use `iter().cloned().partition(f)` instead. + #[deprecated = "use iter().cloned().partition(f) instead"] + pub fn partitioned(&self, f: F) -> (Vec, Vec) where F: FnMut(&T) -> bool { + self.iter().cloned().partition(f) + } +} + +impl Vec { + /// Removes consecutive repeated elements in the vector. + /// + /// If the vector is sorted, this removes all duplicates. + /// + /// # Examples + /// + /// ``` + /// let mut vec = vec![1i, 2, 2, 3, 2]; + /// + /// vec.dedup(); + /// + /// assert_eq!(vec, vec![1i, 2, 3, 2]); + /// ``` + #[stable] + pub fn dedup(&mut self) { + unsafe { + // Although we have a mutable reference to `self`, we cannot make + // *arbitrary* changes. The `PartialEq` comparisons could panic, so we + // must ensure that the vector is in a valid state at all time. + // + // The way that we handle this is by using swaps; we iterate + // over all the elements, swapping as we go so that at the end + // the elements we wish to keep are in the front, and those we + // wish to reject are at the back. We can then truncate the + // vector. This operation is still O(n). + // + // Example: We start in this state, where `r` represents "next + // read" and `w` represents "next_write`. + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 1 | 2 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Comparing self[r] against self[w-1], this is not a duplicate, so + // we swap self[r] and self[w] (no effect as r==w) and then increment both + // r and w, leaving us with: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 1 | 2 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Comparing self[r] against self[w-1], this value is a duplicate, + // so we increment `r` but leave everything else unchanged: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 1 | 2 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Comparing self[r] against self[w-1], this is not a duplicate, + // so swap self[r] and self[w] and advance r and w: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 2 | 1 | 3 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Not a duplicate, repeat: + // + // r + // +---+---+---+---+---+---+ + // | 0 | 1 | 2 | 3 | 1 | 3 | + // +---+---+---+---+---+---+ + // w + // + // Duplicate, advance r. End of vec. Truncate to w. + + let ln = self.len(); + if ln < 1 { return; } + + // Avoid bounds checks by using unsafe pointers. + let p = self.as_mut_ptr(); + let mut r = 1; + let mut w = 1; + + while r < ln { + let p_r = p.offset(r as int); + let p_wm1 = p.offset((w - 1) as int); + if *p_r != *p_wm1 { + if r != w { + let p_w = p_wm1.offset(1); + mem::swap(&mut *p_r, &mut *p_w); + } + w += 1; + } + r += 1; + } + + self.truncate(w); + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Public free fns +//////////////////////////////////////////////////////////////////////////////// + +/// Deprecated: use `unzip` directly on the iterator instead. +#[deprecated = "use unzip directly on the iterator instead"] +pub fn unzip>(iter: V) -> (Vec, Vec) { + iter.unzip() +} + +//////////////////////////////////////////////////////////////////////////////// +// Internal methods and functions +//////////////////////////////////////////////////////////////////////////////// + +impl Vec { + /// Reserves capacity for exactly `capacity` elements in the given vector. + /// + /// If the capacity for `self` is already equal to or greater than the + /// requested capacity, then no action is taken. + fn grow_capacity(&mut self, capacity: uint) { + if mem::size_of::() == 0 { return } + + if capacity > self.cap { + let size = capacity.checked_mul(mem::size_of::()) + .expect("capacity overflow"); + unsafe { + let ptr = alloc_or_realloc(*self.ptr, self.cap * mem::size_of::(), size); + if ptr.is_null() { ::alloc::oom() } + self.ptr = NonZero::new(ptr); + } + self.cap = capacity; + } + } +} + +// FIXME: #13996: need a way to mark the return value as `noalias` +#[inline(never)] +unsafe fn alloc_or_realloc(ptr: *mut T, old_size: uint, size: uint) -> *mut T { + if old_size == 0 { + allocate(size, mem::min_align_of::()) as *mut T + } else { + reallocate(ptr as *mut u8, old_size, size, mem::min_align_of::()) as *mut T + } +} + +#[inline] +unsafe fn dealloc(ptr: *mut T, len: uint) { + if mem::size_of::() != 0 { + deallocate(ptr as *mut u8, + len * mem::size_of::(), + mem::min_align_of::()) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Common trait implementations for Vec +//////////////////////////////////////////////////////////////////////////////// + +#[unstable] +impl Clone for Vec { + fn clone(&self) -> Vec { self.as_slice().to_vec() } + + fn clone_from(&mut self, other: &Vec) { + // drop anything in self that will not be overwritten + if self.len() > other.len() { + self.truncate(other.len()) + } + + // reuse the contained values' allocations/resources. + for (place, thing) in self.iter_mut().zip(other.iter()) { + place.clone_from(thing) + } + + // self.len <= other.len due to the truncate above, so the + // slice here is always in-bounds. + let slice = other[self.len()..]; + self.push_all(slice); + } +} + +impl> Hash for Vec { + #[inline] + fn hash(&self, state: &mut S) { + self.as_slice().hash(state); + } +} + +#[experimental = "waiting on Index stability"] +impl Index for Vec { + #[inline] + fn index<'a>(&'a self, index: &uint) -> &'a T { + &self.as_slice()[*index] + } +} + +impl IndexMut for Vec { + #[inline] + fn index_mut<'a>(&'a mut self, index: &uint) -> &'a mut T { + &mut self.as_mut_slice()[*index] + } +} + +impl ops::Slice for Vec { + #[inline] + fn as_slice_<'a>(&'a self) -> &'a [T] { + self.as_slice() + } + + #[inline] + fn slice_from_or_fail<'a>(&'a self, start: &uint) -> &'a [T] { + self.as_slice().slice_from_or_fail(start) + } + + #[inline] + fn slice_to_or_fail<'a>(&'a self, end: &uint) -> &'a [T] { + self.as_slice().slice_to_or_fail(end) + } + #[inline] + fn slice_or_fail<'a>(&'a self, start: &uint, end: &uint) -> &'a [T] { + self.as_slice().slice_or_fail(start, end) + } +} + +impl ops::SliceMut for Vec { + #[inline] + fn as_mut_slice_<'a>(&'a mut self) -> &'a mut [T] { + self.as_mut_slice() + } + + #[inline] + fn slice_from_or_fail_mut<'a>(&'a mut self, start: &uint) -> &'a mut [T] { + self.as_mut_slice().slice_from_or_fail_mut(start) + } + + #[inline] + fn slice_to_or_fail_mut<'a>(&'a mut self, end: &uint) -> &'a mut [T] { + self.as_mut_slice().slice_to_or_fail_mut(end) + } + #[inline] + fn slice_or_fail_mut<'a>(&'a mut self, start: &uint, end: &uint) -> &'a mut [T] { + self.as_mut_slice().slice_or_fail_mut(start, end) + } +} + +#[experimental = "waiting on Deref stability"] +impl ops::Deref<[T]> for Vec { + fn deref<'a>(&'a self) -> &'a [T] { self.as_slice() } +} + +#[experimental = "waiting on DerefMut stability"] +impl ops::DerefMut<[T]> for Vec { + fn deref_mut<'a>(&'a mut self) -> &'a mut [T] { self.as_mut_slice() } +} + +#[experimental = "waiting on FromIterator stability"] +impl FromIterator for Vec { + #[inline] + fn from_iter>(mut iterator: I) -> Vec { + let (lower, _) = iterator.size_hint(); + let mut vector = Vec::with_capacity(lower); + for element in iterator { + vector.push(element) + } + vector + } +} + +#[experimental = "waiting on Extend stability"] +impl Extend for Vec { + #[inline] + fn extend>(&mut self, mut iterator: I) { + let (lower, _) = iterator.size_hint(); + self.reserve(lower); + for element in iterator { + self.push(element) + } + } +} + +impl PartialEq> for Vec where A: PartialEq { + #[inline] + fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } +} + +macro_rules! impl_eq { + ($lhs:ty, $rhs:ty) => { + impl<'b, A, B> PartialEq<$rhs> for $lhs where A: PartialEq { + #[inline] + fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } + } + + impl<'b, A, B> PartialEq<$lhs> for $rhs where B: PartialEq { + #[inline] + fn eq(&self, other: &$lhs) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &$lhs) -> bool { PartialEq::ne(&**self, &**other) } + } + } +} + +impl_eq! { Vec, &'b [B] } +impl_eq! { Vec, &'b mut [B] } + +impl<'a, A, B> PartialEq> for CowVec<'a, A> where A: PartialEq + Clone { + #[inline] + fn eq(&self, other: &Vec) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &Vec) -> bool { PartialEq::ne(&**self, &**other) } +} + +impl<'a, A, B> PartialEq> for Vec where A: Clone, B: PartialEq { + #[inline] + fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } +} + +macro_rules! impl_eq_for_cowvec { + ($rhs:ty) => { + impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq + Clone { + #[inline] + fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) } + } + + impl<'a, 'b, A, B> PartialEq> for $rhs where A: Clone, B: PartialEq { + #[inline] + fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) } + #[inline] + fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) } + } + } +} + +impl_eq_for_cowvec! { &'b [B] } +impl_eq_for_cowvec! { &'b mut [B] } + +#[unstable = "waiting on PartialOrd stability"] +impl PartialOrd for Vec { + #[inline] + fn partial_cmp(&self, other: &Vec) -> Option { + self.as_slice().partial_cmp(other.as_slice()) + } +} + +#[unstable = "waiting on Eq stability"] +impl Eq for Vec {} + +#[allow(deprecated)] +#[deprecated = "Use overloaded `core::cmp::PartialEq`"] +impl> Equiv for Vec { + #[inline] + fn equiv(&self, other: &V) -> bool { self.as_slice() == other.as_slice() } +} + +#[unstable = "waiting on Ord stability"] +impl Ord for Vec { + #[inline] + fn cmp(&self, other: &Vec) -> Ordering { + self.as_slice().cmp(other.as_slice()) + } +} + +impl AsSlice for Vec { + /// Returns a slice into `self`. + /// + /// # Examples + /// + /// ``` + /// fn foo(slice: &[int]) {} + /// + /// let vec = vec![1i, 2]; + /// foo(vec.as_slice()); + /// ``` + #[inline] + #[stable] + fn as_slice<'a>(&'a self) -> &'a [T] { + unsafe { + mem::transmute(RawSlice { + data: *self.ptr as *const T, + len: self.len + }) + } + } +} + +impl<'a, T: Clone> Add<&'a [T], Vec> for Vec { + #[inline] + fn add(mut self, rhs: &[T]) -> Vec { + self.push_all(rhs); + self + } +} + +#[unsafe_destructor] +impl Drop for Vec { + fn drop(&mut self) { + // This is (and should always remain) a no-op if the fields are + // zeroed (when moving out, because of #[unsafe_no_drop_flag]). + if self.cap != 0 { + unsafe { + for x in self.iter() { + ptr::read(x); + } + dealloc(*self.ptr, self.cap) + } + } + } +} + +#[stable] +impl Default for Vec { + #[stable] + fn default() -> Vec { + Vec::new() + } +} + +#[experimental = "waiting on Show stability"] +impl fmt::Show for Vec { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.as_slice().fmt(f) + } +} + impl<'a> fmt::FormatWriter for Vec { fn write(&mut self, buf: &[u8]) -> fmt::Result { self.push_all(buf); @@ -1933,6 +1495,351 @@ impl<'a> fmt::FormatWriter for Vec { } } +//////////////////////////////////////////////////////////////////////////////// +// Clone-on-write +//////////////////////////////////////////////////////////////////////////////// + +#[experimental = "unclear how valuable this alias is"] +/// A clone-on-write vector +pub type CowVec<'a, T> = Cow<'a, Vec, [T]>; + +impl<'a, T> FromIterator for CowVec<'a, T> where T: Clone { + fn from_iter>(it: I) -> CowVec<'a, T> { + Cow::Owned(FromIterator::from_iter(it)) + } +} + +impl<'a, T: 'a> IntoCow<'a, Vec, [T]> for Vec where T: Clone { + fn into_cow(self) -> CowVec<'a, T> { + Cow::Owned(self) + } +} + +impl<'a, T> IntoCow<'a, Vec, [T]> for &'a [T] where T: Clone { + fn into_cow(self) -> CowVec<'a, T> { + Cow::Borrowed(self) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Iterators +//////////////////////////////////////////////////////////////////////////////// + +/// An iterator that moves out of a vector. +#[stable] +pub struct IntoIter { + allocation: *mut T, // the block of memory allocated for the vector + cap: uint, // the capacity of the vector + ptr: *const T, + end: *const T +} + +#[deprecated = "use IntoIter instead"] +pub type MoveItems = IntoIter; + +impl IntoIter { + #[inline] + /// Drops all items that have not yet been moved and returns the empty vector. + #[unstable] + pub fn into_inner(mut self) -> Vec { + unsafe { + for _x in self { } + let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self; + mem::forget(self); + Vec { ptr: NonZero::new(allocation), cap: cap, len: 0 } + } + } + + /// Deprecated, use .into_inner() instead + #[deprecated = "use .into_inner() instead"] + pub fn unwrap(self) -> Vec { self.into_inner() } +} + +impl Iterator for IntoIter { + #[inline] + fn next<'a>(&'a mut self) -> Option { + unsafe { + if self.ptr == self.end { + None + } else { + if mem::size_of::() == 0 { + // purposefully don't use 'ptr.offset' because for + // vectors with 0-size elements this would return the + // same pointer. + self.ptr = mem::transmute(self.ptr as uint + 1); + + // Use a non-null pointer value + Some(ptr::read(mem::transmute(1u))) + } else { + let old = self.ptr; + self.ptr = self.ptr.offset(1); + + Some(ptr::read(old)) + } + } + } + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let diff = (self.end as uint) - (self.ptr as uint); + let size = mem::size_of::(); + let exact = diff / (if size == 0 {1} else {size}); + (exact, Some(exact)) + } +} + +impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back<'a>(&'a mut self) -> Option { + unsafe { + if self.end == self.ptr { + None + } else { + if mem::size_of::() == 0 { + // See above for why 'ptr.offset' isn't used + self.end = mem::transmute(self.end as uint - 1); + + // Use a non-null pointer value + Some(ptr::read(mem::transmute(1u))) + } else { + self.end = self.end.offset(-1); + + Some(ptr::read(mem::transmute(self.end))) + } + } + } + } +} + +impl ExactSizeIterator for IntoIter {} + +#[unsafe_destructor] +impl Drop for IntoIter { + fn drop(&mut self) { + // destroy the remaining elements + if self.cap != 0 { + for _x in *self {} + unsafe { + dealloc(self.allocation, self.cap); + } + } + } +} + +/// An iterator that drains a vector. +#[unsafe_no_drop_flag] +#[unstable = "recently added as part of collections reform 2"] +pub struct Drain<'a, T> { + ptr: *const T, + end: *const T, + marker: ContravariantLifetime<'a>, +} + +impl<'a, T> Iterator for Drain<'a, T> { + #[inline] + fn next(&mut self) -> Option { + unsafe { + if self.ptr == self.end { + None + } else { + if mem::size_of::() == 0 { + // purposefully don't use 'ptr.offset' because for + // vectors with 0-size elements this would return the + // same pointer. + self.ptr = mem::transmute(self.ptr as uint + 1); + + // Use a non-null pointer value + Some(ptr::read(mem::transmute(1u))) + } else { + let old = self.ptr; + self.ptr = self.ptr.offset(1); + + Some(ptr::read(old)) + } + } + } + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + let diff = (self.end as uint) - (self.ptr as uint); + let size = mem::size_of::(); + let exact = diff / (if size == 0 {1} else {size}); + (exact, Some(exact)) + } +} + +impl<'a, T> DoubleEndedIterator for Drain<'a, T> { + #[inline] + fn next_back(&mut self) -> Option { + unsafe { + if self.end == self.ptr { + None + } else { + if mem::size_of::() == 0 { + // See above for why 'ptr.offset' isn't used + self.end = mem::transmute(self.end as uint - 1); + + // Use a non-null pointer value + Some(ptr::read(mem::transmute(1u))) + } else { + self.end = self.end.offset(-1); + + Some(ptr::read(self.end)) + } + } + } + } +} + +impl<'a, T> ExactSizeIterator for Drain<'a, T> {} + +#[unsafe_destructor] +impl<'a, T> Drop for Drain<'a, T> { + fn drop(&mut self) { + // self.ptr == self.end == null if drop has already been called, + // so we can use #[unsafe_no_drop_flag]. + + // destroy the remaining elements + for _x in *self {} + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Conversion from &[T] to &Vec +//////////////////////////////////////////////////////////////////////////////// + +/// Wrapper type providing a `&Vec` reference via `Deref`. +#[experimental] +pub struct DerefVec<'a, T> { + x: Vec, + l: ContravariantLifetime<'a> +} + +#[experimental] +impl<'a, T> Deref> for DerefVec<'a, T> { + fn deref<'b>(&'b self) -> &'b Vec { + &self.x + } +} + +// Prevent the inner `Vec` from attempting to deallocate memory. +#[unsafe_destructor] +#[experimental] +impl<'a, T> Drop for DerefVec<'a, T> { + fn drop(&mut self) { + self.x.len = 0; + self.x.cap = 0; + } +} + +/// Convert a slice to a wrapper type providing a `&Vec` reference. +#[experimental] +pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> { + unsafe { + DerefVec { + x: Vec::from_raw_parts(x.as_ptr() as *mut T, x.len(), x.len()), + l: ContravariantLifetime::<'a> + } + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Raw module (deprecated) +//////////////////////////////////////////////////////////////////////////////// + +/// Unsafe vector operations. +#[deprecated] +pub mod raw { + use super::Vec; + + /// Constructs a vector from an unsafe pointer to a buffer. + /// + /// The elements of the buffer are copied into the vector without cloning, + /// as if `ptr::read()` were called on them. + #[inline] + #[deprecated = "renamed to Vec::from_raw_buf"] + pub unsafe fn from_buf(ptr: *const T, elts: uint) -> Vec { + Vec::from_raw_buf(ptr, elts) + } +} + +//////////////////////////////////////////////////////////////////////////////// +// Partial vec, used for map_in_place +//////////////////////////////////////////////////////////////////////////////// + +/// An owned, partially type-converted vector of elements with non-zero size. +/// +/// `T` and `U` must have the same, non-zero size. They must also have the same +/// alignment. +/// +/// When the destructor of this struct runs, all `U`s from `start_u` (incl.) to +/// `end_u` (excl.) and all `T`s from `start_t` (incl.) to `end_t` (excl.) are +/// destructed. Additionally the underlying storage of `vec` will be freed. +struct PartialVecNonZeroSized { + vec: Vec, + + start_u: *mut U, + end_u: *mut U, + start_t: *mut T, + end_t: *mut T, +} + +/// An owned, partially type-converted vector of zero-sized elements. +/// +/// When the destructor of this struct runs, all `num_t` `T`s and `num_u` `U`s +/// are destructed. +struct PartialVecZeroSized { + num_t: uint, + num_u: uint, + marker_t: InvariantType, + marker_u: InvariantType, +} + +#[unsafe_destructor] +impl Drop for PartialVecNonZeroSized { + fn drop(&mut self) { + unsafe { + // `vec` hasn't been modified until now. As it has a length + // currently, this would run destructors of `T`s which might not be + // there. So at first, set `vec`s length to `0`. This must be done + // at first to remain memory-safe as the destructors of `U` or `T` + // might cause unwinding where `vec`s destructor would be executed. + self.vec.set_len(0); + + // We have instances of `U`s and `T`s in `vec`. Destruct them. + while self.start_u != self.end_u { + let _ = ptr::read(self.start_u as *const U); // Run a `U` destructor. + self.start_u = self.start_u.offset(1); + } + while self.start_t != self.end_t { + let _ = ptr::read(self.start_t as *const T); // Run a `T` destructor. + self.start_t = self.start_t.offset(1); + } + // After this destructor ran, the destructor of `vec` will run, + // deallocating the underlying memory. + } + } +} + +#[unsafe_destructor] +impl Drop for PartialVecZeroSized { + fn drop(&mut self) { + unsafe { + // Destruct the instances of `T` and `U` this struct owns. + while self.num_t != 0 { + let _: T = mem::uninitialized(); // Run a `T` destructor. + self.num_t -= 1; + } + while self.num_u != 0 { + let _: U = mem::uninitialized(); // Run a `U` destructor. + self.num_u -= 1; + } + } + } +} + #[cfg(test)] mod tests { use prelude::*; @@ -2300,9 +2207,10 @@ mod tests { } #[test] + #[should_fail] fn test_swap_remove_empty() { let mut vec: Vec = vec!(); - assert_eq!(vec.swap_remove(0), None); + vec.swap_remove(0); } #[test] diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs index 99d4e18fb87..3a7168094ff 100644 --- a/src/libcollections/vec_map.rs +++ b/src/libcollections/vec_map.rs @@ -448,7 +448,7 @@ impl VecMap { pub fn insert(&mut self, key: uint, value: V) -> Option { let len = self.v.len(); if len <= key { - self.v.grow_fn(key - len + 1, |_| None); + self.v.extend(range(0, key - len + 1).map(|_| None)); } replace(&mut self.v[key], Some(value)) } diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs index 9c3e53a1ace..b0fd52896fe 100644 --- a/src/libcore/iter.rs +++ b/src/libcore/iter.rs @@ -59,6 +59,7 @@ pub use self::MinMaxResult::*; use clone::Clone; use cmp; use cmp::Ord; +use default::Default; use mem; use num::{ToPrimitive, Int}; use ops::{Add, Deref, FnMut}; @@ -68,20 +69,6 @@ use uint; #[deprecated = "renamed to Extend"] pub use self::Extend as Extendable; -/// Conversion from an `Iterator` -#[unstable = "may be replaced by a more general conversion trait"] -pub trait FromIterator { - /// Build a container with elements from an external iterator. - fn from_iter>(iterator: T) -> Self; -} - -/// A type growable from an `Iterator` implementation -#[unstable = "just renamed as part of collections reform"] -pub trait Extend { - /// Extend a container with the elements yielded by an arbitrary iterator - fn extend>(&mut self, iterator: T); -} - /// An interface for dealing with "external iterators". These types of iterators /// can be resumed at any time as all state is stored internally as opposed to /// being located on the call stack. @@ -106,6 +93,20 @@ pub trait Iterator { fn size_hint(&self) -> (uint, Option) { (0, None) } } +/// Conversion from an `Iterator` +#[unstable = "may be replaced by a more general conversion trait"] +pub trait FromIterator { + /// Build a container with elements from an external iterator. + fn from_iter>(iterator: T) -> Self; +} + +/// A type growable from an `Iterator` implementation +#[unstable = "just renamed as part of collections reform"] +pub trait Extend { + /// Extend a container with the elements yielded by an arbitrary iterator + fn extend>(&mut self, iterator: T); +} + #[unstable = "new convention for extension traits"] /// An extension trait providing numerous methods applicable to all iterators. pub trait IteratorExt: Iterator { @@ -223,7 +224,6 @@ pub trait IteratorExt: Iterator { Enumerate{iter: self, count: 0} } - /// Creates an iterator that has a `.peek()` method /// that returns an optional reference to the next element. /// @@ -471,6 +471,35 @@ pub trait IteratorExt: Iterator { FromIterator::from_iter(self) } + /// Loops through the entire iterator, collecting all of the elements into + /// one of two containers, depending on a predicate. The elements of the + /// first container satisfy the predicate, while the elements of the second + /// do not. + /// + /// ``` + /// let vec = vec![1i, 2i, 3i, 4i]; + /// let (even, odd): (Vec, Vec) = vec.into_iter().partition(|&n| n % 2 == 0); + /// assert_eq!(even, vec![2, 4]); + /// assert_eq!(odd, vec![1, 3]); + /// ``` + #[unstable = "recently added as part of collections reform"] + fn partition(mut self, mut f: F) -> (B, B) where + B: Default + Extend, F: FnMut(&A) -> bool + { + let mut left: B = Default::default(); + let mut right: B = Default::default(); + + for x in self { + if f(&x) { + left.extend(Some(x).into_iter()) + } else { + right.extend(Some(x).into_iter()) + } + } + + (left, right) + } + /// Loops through `n` iterations, returning the `n`th element of the /// iterator. /// @@ -661,6 +690,42 @@ pub trait IteratorExt: Iterator { #[unstable = "trait is unstable"] impl IteratorExt for I where I: Iterator {} +/// Extention trait for iterators of pairs. +#[unstable = "newly added trait, likely to be merged with IteratorExt"] +pub trait IteratorPairExt: Iterator<(A, B)> { + /// Converts an iterator of pairs into a pair of containers. + /// + /// Loops through the entire iterator, collecting the first component of + /// each item into one new container, and the second component into another. + fn unzip(mut self) -> (FromA, FromB) where + FromA: Default + Extend, FromB: Default + Extend + { + struct SizeHint(uint, Option); + impl Iterator for SizeHint { + fn next(&mut self) -> Option { None } + fn size_hint(&self) -> (uint, Option) { + (self.0, self.1) + } + } + + let (lo, hi) = self.size_hint(); + let mut ts: FromA = Default::default(); + let mut us: FromB = Default::default(); + + ts.extend(SizeHint(lo, hi)); + us.extend(SizeHint(lo, hi)); + + for (t, u) in self { + ts.extend(Some(t).into_iter()); + us.extend(Some(u).into_iter()); + } + + (ts, us) + } +} + +impl IteratorPairExt for I where I: Iterator<(A, B)> {} + /// A range iterator able to yield elements from both ends /// /// A `DoubleEndedIterator` can be thought of as a deque in that `next()` and `next_back()` exhaust diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs index fd1598db8cd..cecb4938153 100644 --- a/src/libcore/prelude.rs +++ b/src/libcore/prelude.rs @@ -52,7 +52,7 @@ pub use cmp::{Ordering, Equiv}; pub use cmp::Ordering::{Less, Equal, Greater}; pub use iter::{FromIterator, Extend, IteratorExt}; pub use iter::{Iterator, DoubleEndedIterator, DoubleEndedIteratorExt, RandomAccessIterator}; -pub use iter::{IteratorCloneExt, CloneIteratorExt}; +pub use iter::{IteratorCloneExt, CloneIteratorExt, IteratorPairExt}; pub use iter::{IteratorOrdExt, MutableDoubleEndedIterator, ExactSizeIterator}; pub use num::{ToPrimitive, FromPrimitive}; pub use option::Option; diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs index 77bb5cc2499..7d894ac697b 100644 --- a/src/libcore/slice.rs +++ b/src/libcore/slice.rs @@ -46,6 +46,8 @@ use num::Int; use ops::{FnMut, mod}; use option::Option; use option::Option::{None, Some}; +use result::Result; +use result::Result::{Ok, Err}; use ptr; use ptr::PtrExt; use mem; @@ -68,23 +70,23 @@ pub trait SliceExt for Sized? { fn slice_to<'a>(&'a self, end: uint) -> &'a [T]; fn split_at<'a>(&'a self, mid: uint) -> (&'a [T], &'a [T]); fn iter<'a>(&'a self) -> Iter<'a, T>; - fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> + fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> where P: FnMut(&T) -> bool; - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> where P: FnMut(&T) -> bool; - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> where P: FnMut(&T) -> bool; fn windows<'a>(&'a self, size: uint) -> Windows<'a, T>; fn chunks<'a>(&'a self, size: uint) -> Chunks<'a, T>; fn get<'a>(&'a self, index: uint) -> Option<&'a T>; - fn head<'a>(&'a self) -> Option<&'a T>; + fn first<'a>(&'a self) -> Option<&'a T>; fn tail<'a>(&'a self) -> &'a [T]; fn init<'a>(&'a self) -> &'a [T]; fn last<'a>(&'a self) -> Option<&'a T>; - unsafe fn unsafe_get<'a>(&'a self, index: uint) -> &'a T; + unsafe fn get_unchecked<'a>(&'a self, index: uint) -> &'a T; fn as_ptr(&self) -> *const T; - fn binary_search(&self, f: F) -> BinarySearchResult - where F: FnMut(&T) -> Ordering; + fn binary_search_by(&self, f: F) -> Result where + F: FnMut(&T) -> Ordering; fn len(&self) -> uint; fn is_empty(&self) -> bool { self.len() == 0 } fn get_mut<'a>(&'a mut self, index: uint) -> Option<&'a mut T>; @@ -93,21 +95,21 @@ pub trait SliceExt for Sized? { fn slice_from_mut<'a>(&'a mut self, start: uint) -> &'a mut [T]; fn slice_to_mut<'a>(&'a mut self, end: uint) -> &'a mut [T]; fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>; - fn head_mut<'a>(&'a mut self) -> Option<&'a mut T>; + fn first_mut<'a>(&'a mut self) -> Option<&'a mut T>; fn tail_mut<'a>(&'a mut self) -> &'a mut [T]; fn init_mut<'a>(&'a mut self) -> &'a mut [T]; fn last_mut<'a>(&'a mut self) -> Option<&'a mut T>; - fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool; - fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitsN> + fn splitn_mut

(&mut self, n: uint, pred: P) -> SplitNMut where P: FnMut(&T) -> bool; - fn rsplitn_mut

(&mut self, n: uint, pred: P) -> SplitsN> + fn rsplitn_mut

(&mut self, n: uint, pred: P) -> RSplitNMut where P: FnMut(&T) -> bool; - fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> MutChunks<'a, T>; + fn chunks_mut<'a>(&'a mut self, chunk_size: uint) -> ChunksMut<'a, T>; fn swap(&mut self, a: uint, b: uint); fn split_at_mut<'a>(&'a mut self, mid: uint) -> (&'a mut [T], &'a mut [T]); fn reverse(&mut self); - unsafe fn unsafe_mut<'a>(&'a mut self, index: uint) -> &'a mut T; + unsafe fn get_unchecked_mut<'a>(&'a mut self, index: uint) -> &'a mut T; fn as_mut_ptr(&mut self) -> *mut T; } @@ -145,11 +147,11 @@ impl SliceExt for [T] { unsafe { let p = self.as_ptr(); if mem::size_of::() == 0 { - Iter{ptr: p, + Iter {ptr: p, end: (p as uint + self.len()) as *const T, marker: marker::ContravariantLifetime::<'a>} } else { - Iter{ptr: p, + Iter {ptr: p, end: p.offset(self.len() as int), marker: marker::ContravariantLifetime::<'a>} } @@ -157,8 +159,8 @@ impl SliceExt for [T] { } #[inline] - fn split<'a, P>(&'a self, pred: P) -> Splits<'a, T, P> where P: FnMut(&T) -> bool { - Splits { + fn split<'a, P>(&'a self, pred: P) -> Split<'a, T, P> where P: FnMut(&T) -> bool { + Split { v: self, pred: pred, finished: false @@ -166,24 +168,28 @@ impl SliceExt for [T] { } #[inline] - fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> where + fn splitn<'a, P>(&'a self, n: uint, pred: P) -> SplitN<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split(pred), - count: n, - invert: false + SplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: false + } } } #[inline] - fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> SplitsN> where + fn rsplitn<'a, P>(&'a self, n: uint, pred: P) -> RSplitN<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split(pred), - count: n, - invert: true + RSplitN { + inner: GenericSplitN { + iter: self.split(pred), + count: n, + invert: true + } } } @@ -205,7 +211,7 @@ impl SliceExt for [T] { } #[inline] - fn head(&self) -> Option<&T> { + fn first(&self) -> Option<&T> { if self.len() == 0 { None } else { Some(&self[0]) } } @@ -223,7 +229,7 @@ impl SliceExt for [T] { } #[inline] - unsafe fn unsafe_get(&self, index: uint) -> &T { + unsafe fn get_unchecked(&self, index: uint) -> &T { transmute(self.repr().data.offset(index as int)) } @@ -233,14 +239,16 @@ impl SliceExt for [T] { } #[unstable] - fn binary_search(&self, mut f: F) -> BinarySearchResult where F: FnMut(&T) -> Ordering { + fn binary_search_by(&self, mut f: F) -> Result where + F: FnMut(&T) -> Ordering + { let mut base : uint = 0; let mut lim : uint = self.len(); while lim != 0 { let ix = base + (lim >> 1); match f(&self[ix]) { - Equal => return BinarySearchResult::Found(ix), + Equal => return Ok(ix), Less => { base = ix + 1; lim -= 1; @@ -249,7 +257,7 @@ impl SliceExt for [T] { } lim >>= 1; } - return BinarySearchResult::NotFound(base); + Err(base) } #[inline] @@ -292,11 +300,11 @@ impl SliceExt for [T] { unsafe { let p = self.as_mut_ptr(); if mem::size_of::() == 0 { - IterMut{ptr: p, + IterMut {ptr: p, end: (p as uint + self.len()) as *mut T, marker: marker::ContravariantLifetime::<'a>} } else { - IterMut{ptr: p, + IterMut {ptr: p, end: p.offset(self.len() as int), marker: marker::ContravariantLifetime::<'a>} } @@ -311,7 +319,7 @@ impl SliceExt for [T] { } #[inline] - fn head_mut(&mut self) -> Option<&mut T> { + fn first_mut(&mut self) -> Option<&mut T> { if self.len() == 0 { None } else { Some(&mut self[0]) } } @@ -327,36 +335,40 @@ impl SliceExt for [T] { } #[inline] - fn split_mut<'a, P>(&'a mut self, pred: P) -> MutSplits<'a, T, P> where P: FnMut(&T) -> bool { - MutSplits { v: self, pred: pred, finished: false } + fn split_mut<'a, P>(&'a mut self, pred: P) -> SplitMut<'a, T, P> where P: FnMut(&T) -> bool { + SplitMut { v: self, pred: pred, finished: false } } #[inline] - fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> where + fn splitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitNMut<'a, T, P> where P: FnMut(&T) -> bool { - SplitsN { - iter: self.split_mut(pred), - count: n, - invert: false + SplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: false + } } } #[inline] - fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> SplitsN> where + fn rsplitn_mut<'a, P>(&'a mut self, n: uint, pred: P) -> RSplitNMut<'a, T, P> where P: FnMut(&T) -> bool, { - SplitsN { - iter: self.split_mut(pred), - count: n, - invert: true + RSplitNMut { + inner: GenericSplitN { + iter: self.split_mut(pred), + count: n, + invert: true + } } } #[inline] - fn chunks_mut(&mut self, chunk_size: uint) -> MutChunks { + fn chunks_mut(&mut self, chunk_size: uint) -> ChunksMut { assert!(chunk_size > 0); - MutChunks { v: self, chunk_size: chunk_size } + ChunksMut { v: self, chunk_size: chunk_size } } fn swap(&mut self, a: uint, b: uint) { @@ -375,8 +387,8 @@ impl SliceExt for [T] { while i < ln / 2 { // Unsafe swap to avoid the bounds check in safe swap. unsafe { - let pa: *mut T = self.unsafe_mut(i); - let pb: *mut T = self.unsafe_mut(ln - i - 1); + let pa: *mut T = self.get_unchecked_mut(i); + let pb: *mut T = self.get_unchecked_mut(ln - i - 1); ptr::swap(pa, pb); } i += 1; @@ -384,7 +396,7 @@ impl SliceExt for [T] { } #[inline] - unsafe fn unsafe_mut(&mut self, index: uint) -> &mut T { + unsafe fn get_unchecked_mut(&mut self, index: uint) -> &mut T { transmute((self.repr().data as *mut T).offset(index as int)) } @@ -468,21 +480,26 @@ impl ops::SliceMut for [T] { } /// Extension methods for slices containing `PartialEq` elements. -#[unstable = "may merge with other traits"] +#[unstable = "may merge with SliceExt"] pub trait PartialEqSliceExt for Sized? { /// Find the first index containing a matching value. + #[experimental] fn position_elem(&self, t: &T) -> Option; /// Find the last index containing a matching value. + #[experimental] fn rposition_elem(&self, t: &T) -> Option; /// Return true if the slice contains an element with the given value. + #[stable] fn contains(&self, x: &T) -> bool; /// Returns true if `needle` is a prefix of the slice. + #[stable] fn starts_with(&self, needle: &[T]) -> bool; /// Returns true if `needle` is a suffix of the slice. + #[stable] fn ends_with(&self, needle: &[T]) -> bool; } @@ -520,19 +537,16 @@ impl PartialEqSliceExt for [T] { #[unstable = "may merge with other traits"] #[allow(missing_docs)] // docs in libcollections pub trait OrdSliceExt for Sized? { - #[unstable = "name likely to change"] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult; - #[experimental] + fn binary_search(&self, x: &T) -> Result; fn next_permutation(&mut self) -> bool; - #[experimental] fn prev_permutation(&mut self) -> bool; } #[unstable = "trait is unstable"] impl OrdSliceExt for [T] { #[unstable] - fn binary_search_elem(&self, x: &T) -> BinarySearchResult { - self.binary_search(|p| p.cmp(x)) + fn binary_search(&self, x: &T) -> Result { + self.binary_search_by(|p| p.cmp(x)) } #[experimental] @@ -619,28 +633,30 @@ impl CloneSliceExt for [T] { } } -// +//////////////////////////////////////////////////////////////////////////////// // Common traits -// +//////////////////////////////////////////////////////////////////////////////// /// Data that is viewable as a slice. -#[unstable = "may merge with other traits"] +#[experimental = "will be replaced by slice syntax"] pub trait AsSlice for Sized? { /// Work with `self` as a slice. fn as_slice<'a>(&'a self) -> &'a [T]; } -#[unstable = "trait is unstable"] +#[experimental = "trait is experimental"] impl AsSlice for [T] { #[inline(always)] fn as_slice<'a>(&'a self) -> &'a [T] { self } } +#[experimental = "trait is experimental"] impl<'a, T, Sized? U: AsSlice> AsSlice for &'a U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } } +#[experimental = "trait is experimental"] impl<'a, T, Sized? U: AsSlice> AsSlice for &'a mut U { #[inline(always)] fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) } @@ -656,7 +672,7 @@ impl<'a, T> Default for &'a [T] { // Iterators // -// The shared definition of the `Item` and `IterMut` iterators +// The shared definition of the `Iter` and `IterMut` iterators macro_rules! iterator { (struct $name:ident -> $ptr:ty, $elem:ty) => { #[experimental = "needs review"] @@ -736,9 +752,8 @@ macro_rules! make_slice { }} } - /// Immutable slice iterator -#[experimental = "needs review"] +#[stable] pub struct Iter<'a, T: 'a> { ptr: *const T, end: *const T, @@ -813,7 +828,7 @@ impl<'a, T> RandomAccessIterator<&'a T> for Iter<'a, T> { } /// Mutable slice iterator. -#[experimental = "needs review"] +#[stable] pub struct IterMut<'a, T: 'a> { ptr: *mut T, end: *mut T, @@ -876,9 +891,9 @@ iterator!{struct IterMut -> *mut T, &'a mut T} #[experimental = "needs review"] impl<'a, T> ExactSizeIterator<&'a mut T> for IterMut<'a, T> {} -/// An abstraction over the splitting iterators, so that splitn, splitn_mut etc -/// can be implemented once. -trait SplitsIter: DoubleEndedIterator { +/// An internal abstraction over the splitting iterators, so that +/// splitn, splitn_mut etc can be implemented once. +trait SplitIter: DoubleEndedIterator { /// Mark the underlying iterator as complete, extracting the remaining /// portion of the slice. fn finish(&mut self) -> Option; @@ -886,8 +901,8 @@ trait SplitsIter: DoubleEndedIterator { /// An iterator over subslices separated by elements that match a predicate /// function. -#[experimental = "needs review"] -pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { +#[stable] +pub struct Split<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a [T], pred: P, finished: bool @@ -895,9 +910,9 @@ pub struct Splits<'a, T:'a, P> where P: FnMut(&T) -> bool { // FIXME(#19839) Remove in favor of `#[deriving(Clone)]` #[stable] -impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { - fn clone(&self) -> Splits<'a, T, P> { - Splits { +impl<'a, T, P> Clone for Split<'a, T, P> where P: Clone + FnMut(&T) -> bool { + fn clone(&self) -> Split<'a, T, P> { + Split { v: self.v, pred: self.pred.clone(), finished: self.finished, @@ -906,7 +921,7 @@ impl<'a, T, P> Clone for Splits<'a, T, P> where P: Clone + FnMut(&T) -> bool { } #[experimental = "needs review"] -impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next(&mut self) -> Option<&'a [T]> { if self.finished { return None; } @@ -932,7 +947,7 @@ impl<'a, T, P> Iterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool } #[experimental = "needs review"] -impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { if self.finished { return None; } @@ -948,7 +963,7 @@ impl<'a, T, P> DoubleEndedIterator<&'a [T]> for Splits<'a, T, P> where P: FnMut( } } -impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter<&'a [T]> for Split<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn finish(&mut self) -> Option<&'a [T]> { if self.finished { None } else { self.finished = true; Some(self.v) } @@ -957,14 +972,14 @@ impl<'a, T, P> SplitsIter<&'a [T]> for Splits<'a, T, P> where P: FnMut(&T) -> bo /// An iterator over the subslices of the vector which are separated /// by elements that match `pred`. -#[experimental = "needs review"] -pub struct MutSplits<'a, T:'a, P> where P: FnMut(&T) -> bool { +#[stable] +pub struct SplitMut<'a, T:'a, P> where P: FnMut(&T) -> bool { v: &'a mut [T], pred: P, finished: bool } -impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> SplitIter<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn finish(&mut self) -> Option<&'a mut [T]> { if self.finished { @@ -977,7 +992,7 @@ impl<'a, T, P> SplitsIter<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T } #[experimental = "needs review"] -impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) -> bool { +impl<'a, T, P> Iterator<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { if self.finished { return None; } @@ -1010,7 +1025,7 @@ impl<'a, T, P> Iterator<&'a mut [T]> for MutSplits<'a, T, P> where P: FnMut(&T) } #[experimental = "needs review"] -impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where +impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for SplitMut<'a, T, P> where P: FnMut(&T) -> bool, { #[inline] @@ -1033,17 +1048,17 @@ impl<'a, T, P> DoubleEndedIterator<&'a mut [T]> for MutSplits<'a, T, P> where } } -/// An iterator over subslices separated by elements that match a predicate -/// function, splitting at most a fixed number of times. -#[experimental = "needs review"] -pub struct SplitsN { +/// An private iterator over subslices separated by elements that +/// match a predicate function, splitting at most a fixed number of +/// times. +struct GenericSplitN { iter: I, count: uint, invert: bool } #[experimental = "needs review"] -impl> Iterator for SplitsN { +impl> Iterator for GenericSplitN { #[inline] fn next(&mut self) -> Option { if self.count == 0 { @@ -1061,6 +1076,55 @@ impl> Iterator for SplitsN { } } +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +pub struct SplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +/// An iterator over subslices separated by elements that match a +/// predicate function, limited to a given number of splits, starting +/// from the end of the slice. +pub struct RSplitN<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +/// An iterator over subslices separated by elements that match a predicate +/// function, limited to a given number of splits. +pub struct SplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +/// An iterator over subslices separated by elements that match a +/// predicate function, limited to a given number of splits, starting +/// from the end of the slice. +pub struct RSplitNMut<'a, T: 'a, P> where P: FnMut(&T) -> bool { + inner: GenericSplitN> +} + +macro_rules! forward_iterator { + ($name:ident: $elem:ident, $iter_of:ty) => { + impl<'a, $elem, P> Iterator<$iter_of> for $name<'a, $elem, P> where + P: FnMut(&T) -> bool + { + #[inline] + fn next(&mut self) -> Option<$iter_of> { + self.inner.next() + } + + #[inline] + fn size_hint(&self) -> (uint, Option) { + self.inner.size_hint() + } + } + } +} + +forward_iterator! { SplitN: T, &'a [T] } +forward_iterator! { RSplitN: T, &'a [T] } +forward_iterator! { SplitNMut: T, &'a mut [T] } +forward_iterator! { RSplitNMut: T, &'a mut [T] } + /// An iterator over overlapping subslices of length `size`. #[deriving(Clone)] #[experimental = "needs review"] @@ -1172,13 +1236,13 @@ impl<'a, T> RandomAccessIterator<&'a [T]> for Chunks<'a, T> { /// elements at a time). When the slice len is not evenly divided by the chunk /// size, the last slice of the iteration will be the remainder. #[experimental = "needs review"] -pub struct MutChunks<'a, T:'a> { +pub struct ChunksMut<'a, T:'a> { v: &'a mut [T], chunk_size: uint } #[experimental = "needs review"] -impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> { +impl<'a, T> Iterator<&'a mut [T]> for ChunksMut<'a, T> { #[inline] fn next(&mut self) -> Option<&'a mut [T]> { if self.v.len() == 0 { @@ -1206,7 +1270,7 @@ impl<'a, T> Iterator<&'a mut [T]> for MutChunks<'a, T> { } #[experimental = "needs review"] -impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> { +impl<'a, T> DoubleEndedIterator<&'a mut [T]> for ChunksMut<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a mut [T]> { if self.v.len() == 0 { @@ -1224,51 +1288,12 @@ impl<'a, T> DoubleEndedIterator<&'a mut [T]> for MutChunks<'a, T> { } - -/// The result of calling `binary_search`. -/// -/// `Found` means the search succeeded, and the contained value is the -/// index of the matching element. `NotFound` means the search -/// succeeded, and the contained value is an index where a matching -/// value could be inserted while maintaining sort order. -#[deriving(Copy, PartialEq, Show)] -#[experimental = "needs review"] -pub enum BinarySearchResult { - /// The index of the found value. - Found(uint), - /// The index where the value should have been found. - NotFound(uint) -} - -#[experimental = "needs review"] -impl BinarySearchResult { - /// Converts a `Found` to `Some`, `NotFound` to `None`. - /// Similar to `Result::ok`. - pub fn found(&self) -> Option { - match *self { - BinarySearchResult::Found(i) => Some(i), - BinarySearchResult::NotFound(_) => None - } - } - - /// Convert a `Found` to `None`, `NotFound` to `Some`. - /// Similar to `Result::err`. - pub fn not_found(&self) -> Option { - match *self { - BinarySearchResult::Found(_) => None, - BinarySearchResult::NotFound(i) => Some(i) - } - } -} - - - // // Free functions // /// Converts a pointer to A into a slice of length 1 (without copying). -#[unstable = "waiting for DST"] +#[unstable] pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { unsafe { transmute(RawSlice { data: s, len: 1 }) @@ -1276,7 +1301,7 @@ pub fn ref_slice<'a, A>(s: &'a A) -> &'a [A] { } /// Converts a pointer to A into a slice of length 1 (without copying). -#[unstable = "waiting for DST"] +#[unstable] pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { unsafe { let ptr: *const A = transmute(s); @@ -1310,7 +1335,7 @@ pub fn mut_ref_slice<'a, A>(s: &'a mut A) -> &'a mut [A] { /// } /// ``` #[inline] -#[unstable = "just renamed from `mod raw`"] +#[unstable = "should be renamed to from_raw_parts"] pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] { transmute(RawSlice { data: *p, len: len }) } @@ -1322,7 +1347,7 @@ pub unsafe fn from_raw_buf<'a, T>(p: &'a *const T, len: uint) -> &'a [T] { /// not being able to provide a non-aliasing guarantee of the returned mutable /// slice. #[inline] -#[unstable = "just renamed from `mod raw`"] +#[unstable = "jshould be renamed to from_raw_parts_mut"] pub unsafe fn from_raw_mut_buf<'a, T>(p: &'a *mut T, len: uint) -> &'a mut [T] { transmute(RawSlice { data: *p as *const T, len: len }) } @@ -1497,39 +1522,28 @@ impl PartialOrd for [T] { } } -/// Extension methods for immutable slices containing integers. +/// Extension methods for slices containing integers. #[experimental] -pub trait ImmutableIntSlice for Sized? { +pub trait IntSliceExt for Sized? { /// Converts the slice to an immutable slice of unsigned integers with the same width. fn as_unsigned<'a>(&'a self) -> &'a [U]; /// Converts the slice to an immutable slice of signed integers with the same width. fn as_signed<'a>(&'a self) -> &'a [S]; -} -/// Extension methods for mutable slices containing integers. -#[experimental] -pub trait MutableIntSlice for Sized?: ImmutableIntSlice { /// Converts the slice to a mutable slice of unsigned integers with the same width. fn as_unsigned_mut<'a>(&'a mut self) -> &'a mut [U]; /// Converts the slice to a mutable slice of signed integers with the same width. fn as_signed_mut<'a>(&'a mut self) -> &'a mut [S]; } -macro_rules! impl_immut_int_slice { +macro_rules! impl_int_slice { ($u:ty, $s:ty, $t:ty) => { #[experimental] - impl ImmutableIntSlice<$u, $s> for [$t] { + impl IntSliceExt<$u, $s> for [$t] { #[inline] fn as_unsigned(&self) -> &[$u] { unsafe { transmute(self) } } #[inline] fn as_signed(&self) -> &[$s] { unsafe { transmute(self) } } - } - } -} -macro_rules! impl_mut_int_slice { - ($u:ty, $s:ty, $t:ty) => { - #[experimental] - impl MutableIntSlice<$u, $s> for [$t] { #[inline] fn as_unsigned_mut(&mut self) -> &mut [$u] { unsafe { transmute(self) } } #[inline] @@ -1538,17 +1552,15 @@ macro_rules! impl_mut_int_slice { } } -macro_rules! impl_int_slice { +macro_rules! impl_int_slices { ($u:ty, $s:ty) => { - impl_immut_int_slice! { $u, $s, $u } - impl_immut_int_slice! { $u, $s, $s } - impl_mut_int_slice! { $u, $s, $u } - impl_mut_int_slice! { $u, $s, $s } + impl_int_slice! { $u, $s, $u } + impl_int_slice! { $u, $s, $s } } } -impl_int_slice! { u8, i8 } -impl_int_slice! { u16, i16 } -impl_int_slice! { u32, i32 } -impl_int_slice! { u64, i64 } -impl_int_slice! { uint, int } +impl_int_slices! { u8, i8 } +impl_int_slices! { u16, i16 } +impl_int_slices! { u32, i32 } +impl_int_slices! { u64, i64 } +impl_int_slices! { uint, int } diff --git a/src/libcoretest/slice.rs b/src/libcoretest/slice.rs index 987da903211..9ef7d603059 100644 --- a/src/libcoretest/slice.rs +++ b/src/libcoretest/slice.rs @@ -8,30 +8,30 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::slice::BinarySearchResult::{Found, NotFound}; +use core::result::Result::{Ok, Err}; #[test] fn binary_search_not_found() { let b = [1i, 2, 4, 6, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&6)) == Found(3)); + assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3)); let b = [1i, 2, 4, 6, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&5)) == NotFound(3)); + assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3)); let b = [1i, 2, 4, 6, 7, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&6)) == Found(3)); + assert!(b.binary_search_by(|v| v.cmp(&6)) == Ok(3)); let b = [1i, 2, 4, 6, 7, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&5)) == NotFound(3)); + assert!(b.binary_search_by(|v| v.cmp(&5)) == Err(3)); let b = [1i, 2, 4, 6, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&8)) == Found(4)); + assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(4)); let b = [1i, 2, 4, 6, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&7)) == NotFound(4)); + assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(4)); let b = [1i, 2, 4, 6, 7, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&8)) == Found(5)); + assert!(b.binary_search_by(|v| v.cmp(&8)) == Ok(5)); let b = [1i, 2, 4, 5, 6, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&7)) == NotFound(5)); + assert!(b.binary_search_by(|v| v.cmp(&7)) == Err(5)); let b = [1i, 2, 4, 5, 6, 8, 9]; - assert!(b.binary_search(|v| v.cmp(&0)) == NotFound(0)); + assert!(b.binary_search_by(|v| v.cmp(&0)) == Err(0)); let b = [1i, 2, 4, 5, 6, 8]; - assert!(b.binary_search(|v| v.cmp(&9)) == NotFound(6)); + assert!(b.binary_search_by(|v| v.cmp(&9)) == Err(6)); } #[test] diff --git a/src/libgetopts/lib.rs b/src/libgetopts/lib.rs index 0426f269376..0184222b9e0 100644 --- a/src/libgetopts/lib.rs +++ b/src/libgetopts/lib.rs @@ -578,7 +578,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result { fn f(_x: uint) -> Vec { return Vec::new(); } - let mut vals = Vec::from_fn(n_opts, f); + let mut vals: Vec<_> = range(0, n_opts).map(f).collect(); let mut free: Vec = Vec::new(); let l = args.len(); let mut i = 0; diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs index 3cb1f51a6a8..a76e5ebd08a 100644 --- a/src/librand/isaac.rs +++ b/src/librand/isaac.rs @@ -361,7 +361,7 @@ impl Isaac64Rng { const MP_VEC: [(uint, uint), .. 2] = [(0,MIDPOINT), (MIDPOINT, 0)]; macro_rules! ind ( ($x:expr) => { - *self.mem.unsafe_get(($x as uint >> 3) & (RAND_SIZE_64 - 1)) + *self.mem.get_unchecked(($x as uint >> 3) & (RAND_SIZE_64 - 1)) } ); @@ -375,13 +375,13 @@ impl Isaac64Rng { let mix = if $j == 0 {!mix} else {mix}; unsafe { - let x = *self.mem.unsafe_get(base + mr_offset); - a = mix + *self.mem.unsafe_get(base + m2_offset); + let x = *self.mem.get_unchecked(base + mr_offset); + a = mix + *self.mem.get_unchecked(base + m2_offset); let y = ind!(x) + a + b; - *self.mem.unsafe_mut(base + mr_offset) = y; + *self.mem.get_unchecked_mut(base + mr_offset) = y; b = ind!(y >> RAND_SIZE_64_LEN) + x; - *self.rsl.unsafe_mut(base + mr_offset) = b; + *self.rsl.get_unchecked_mut(base + mr_offset) = b; } }} ); @@ -392,13 +392,13 @@ impl Isaac64Rng { let mix = if $j == 0 {!mix} else {mix}; unsafe { - let x = *self.mem.unsafe_get(base + mr_offset); - a = mix + *self.mem.unsafe_get(base + m2_offset); + let x = *self.mem.get_unchecked(base + mr_offset); + a = mix + *self.mem.get_unchecked(base + m2_offset); let y = ind!(x) + a + b; - *self.mem.unsafe_mut(base + mr_offset) = y; + *self.mem.get_unchecked_mut(base + mr_offset) = y; b = ind!(y >> RAND_SIZE_64_LEN) + x; - *self.rsl.unsafe_mut(base + mr_offset) = b; + *self.rsl.get_unchecked_mut(base + mr_offset) = b; } }} ); diff --git a/src/librbml/io.rs b/src/librbml/io.rs index cbe69295050..fd0c54e8ed3 100644 --- a/src/librbml/io.rs +++ b/src/librbml/io.rs @@ -11,6 +11,7 @@ use std::io::{IoError, IoResult, SeekStyle}; use std::io; use std::slice; +use std::iter::repeat; static BUF_CAPACITY: uint = 128; @@ -87,7 +88,7 @@ impl Writer for SeekableMemWriter { // currently are let difference = self.pos as i64 - self.buf.len() as i64; if difference > 0 { - self.buf.grow(difference as uint, 0); + self.buf.extend(repeat(0).take(difference as uint)); } // Figure out what bytes will be used to overwrite what's currently diff --git a/src/libregex/compile.rs b/src/libregex/compile.rs index c361a25bf52..1476e6ab8a7 100644 --- a/src/libregex/compile.rs +++ b/src/libregex/compile.rs @@ -14,6 +14,7 @@ pub use self::Inst::*; use std::cmp; +use std::iter::repeat; use parse; use parse::{ Flags, FLAG_EMPTY, @@ -157,7 +158,7 @@ impl<'r> Compiler<'r> { Capture(cap, name, x) => { let len = self.names.len(); if cap >= len { - self.names.grow(10 + cap - len, None) + self.names.extend(repeat(None).take(10 + cap - len)) } self.names[cap] = name; diff --git a/src/libregex/parse.rs b/src/libregex/parse.rs index 86c02de76dc..692a065299c 100644 --- a/src/libregex/parse.rs +++ b/src/libregex/parse.rs @@ -18,7 +18,6 @@ use std::cmp; use std::fmt; use std::iter; use std::num; -use std::slice::BinarySearchResult; /// Static data containing Unicode ranges for general categories and scripts. use unicode::regex::{UNICODE_CLASSES, PERLD, PERLS, PERLW}; @@ -1028,9 +1027,9 @@ fn is_valid_cap(c: char) -> bool { } fn find_class(classes: NamedClasses, name: &str) -> Option> { - match classes.binary_search(|&(s, _)| s.cmp(name)) { - BinarySearchResult::Found(i) => Some(classes[i].1.to_vec()), - BinarySearchResult::NotFound(_) => None, + match classes.binary_search_by(|&(s, _)| s.cmp(name)) { + Ok(i) => Some(classes[i].1.to_vec()), + Err(_) => None, } } diff --git a/src/libregex/vm.rs b/src/libregex/vm.rs index 990d5a159f6..72e0e559c80 100644 --- a/src/libregex/vm.rs +++ b/src/libregex/vm.rs @@ -38,6 +38,7 @@ pub use self::StepState::*; use std::cmp; use std::mem; +use std::iter::repeat; use std::slice::SliceExt; use compile::{ Program, @@ -121,7 +122,7 @@ impl<'r, 't> Nfa<'r, 't> { let mut clist = &mut Threads::new(self.which, ninsts, ncaps); let mut nlist = &mut Threads::new(self.which, ninsts, ncaps); - let mut groups = Vec::from_elem(ncaps * 2, None); + let mut groups: Vec<_> = repeat(None).take(ncaps * 2).collect(); // Determine if the expression starts with a '^' so we can avoid // simulating .*? @@ -227,8 +228,7 @@ impl<'r, 't> Nfa<'r, 't> { let negate = flags & FLAG_NEGATED > 0; let casei = flags & FLAG_NOCASE > 0; let found = ranges.as_slice(); - let found = found.binary_search(|&rc| class_cmp(casei, c, rc)) - .found().is_some(); + let found = found.binary_search_by(|&rc| class_cmp(casei, c, rc)).is_ok(); if found ^ negate { self.add(nlist, pc+1, caps); } @@ -457,10 +457,10 @@ impl Threads { fn new(which: MatchKind, num_insts: uint, ncaps: uint) -> Threads { Threads { which: which, - queue: Vec::from_fn(num_insts, |_| { - Thread { pc: 0, groups: Vec::from_elem(ncaps * 2, None) } - }), - sparse: Vec::from_elem(num_insts, 0u), + queue: range(0, num_insts).map(|_| { + Thread { pc: 0, groups: repeat(None).take(ncaps * 2).collect() } + }).collect(), + sparse: repeat(0u).take(num_insts).collect(), size: 0, } } @@ -518,7 +518,7 @@ pub fn is_word(c: Option) -> bool { // Try the common ASCII case before invoking binary search. match c { '_' | '0' ... '9' | 'a' ... 'z' | 'A' ... 'Z' => true, - _ => PERLW.binary_search(|&(start, end)| { + _ => PERLW.binary_search_by(|&(start, end)| { if c >= start && c <= end { Equal } else if start > c { @@ -526,7 +526,7 @@ pub fn is_word(c: Option) -> bool { } else { Less } - }).found().is_some() + }).is_ok() } } diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index db29d0111f4..5d0532a6210 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -1599,7 +1599,7 @@ fn encode_index(rbml_w: &mut Encoder, index: Vec>, mut write_fn: F: FnMut(&mut SeekableMemWriter, &T), T: Hash, { - let mut buckets: Vec>> = Vec::from_fn(256, |_| Vec::new()); + let mut buckets: Vec>> = range(0, 256u16).map(|_| Vec::new()).collect(); for elt in index.into_iter() { let h = hash::hash(&elt.val) as uint; buckets[h % 256].push(elt); diff --git a/src/librustc/middle/check_match.rs b/src/librustc/middle/check_match.rs index b7e67ea4690..522e1d4d3b2 100644 --- a/src/librustc/middle/check_match.rs +++ b/src/librustc/middle/check_match.rs @@ -611,9 +611,9 @@ fn is_useful(cx: &MatchCheckCtxt, let arity = constructor_arity(cx, &c, left_ty); let mut result = { let pat_slice = pats[]; - let subpats = Vec::from_fn(arity, |i| { + let subpats: Vec<_> = range(0, arity).map(|i| { pat_slice.get(i).map_or(DUMMY_WILD_PAT, |p| &**p) - }); + }).collect(); vec![construct_witness(cx, &c, subpats, left_ty)] }; result.extend(pats.into_iter().skip(arity)); @@ -635,7 +635,7 @@ fn is_useful(cx: &MatchCheckCtxt, match is_useful(cx, &matrix, v.tail(), witness) { UsefulWithWitness(pats) => { let arity = constructor_arity(cx, &constructor, left_ty); - let wild_pats = Vec::from_elem(arity, DUMMY_WILD_PAT); + let wild_pats: Vec<_> = repeat(DUMMY_WILD_PAT).take(arity).collect(); let enum_pat = construct_witness(cx, &constructor, wild_pats, left_ty); let mut new_pats = vec![enum_pat]; new_pats.extend(pats.into_iter()); @@ -788,7 +788,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } = raw_pat(r[col]); let head: Option> = match *node { ast::PatWild(_) => - Some(Vec::from_elem(arity, DUMMY_WILD_PAT)), + Some(repeat(DUMMY_WILD_PAT).take(arity).collect()), ast::PatIdent(_, _, _) => { let opt_def = cx.tcx.def_map.borrow().get(&pat_id).cloned(); @@ -801,7 +801,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], } else { None }, - _ => Some(Vec::from_elem(arity, DUMMY_WILD_PAT)) + _ => Some(repeat(DUMMY_WILD_PAT).take(arity).collect()) } } @@ -815,7 +815,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], DefVariant(..) | DefStruct(..) => { Some(match args { &Some(ref args) => args.iter().map(|p| &**p).collect(), - &None => Vec::from_elem(arity, DUMMY_WILD_PAT) + &None => repeat(DUMMY_WILD_PAT).take(arity).collect(), }) } _ => None @@ -894,13 +894,13 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat], // Fixed-length vectors. Single => { let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect(); - pats.grow_fn(arity - before.len() - after.len(), |_| DUMMY_WILD_PAT); + pats.extend(repeat(DUMMY_WILD_PAT).take(arity - before.len() - after.len())); pats.extend(after.iter().map(|p| &**p)); Some(pats) }, Slice(length) if before.len() + after.len() <= length && slice.is_some() => { let mut pats: Vec<&Pat> = before.iter().map(|p| &**p).collect(); - pats.grow_fn(arity - before.len() - after.len(), |_| DUMMY_WILD_PAT); + pats.extend(repeat(DUMMY_WILD_PAT).take(arity - before.len() - after.len())); pats.extend(after.iter().map(|p| &**p)); Some(pats) }, diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index a2d417ca345..6cf6065de19 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -21,6 +21,7 @@ use middle::cfg::CFGIndex; use middle::ty; use std::io; use std::uint; +use std::iter::repeat; use syntax::ast; use syntax::ast_util::IdRange; use syntax::visit; @@ -203,9 +204,9 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { let entry = if oper.initial_value() { uint::MAX } else {0}; - let gens = Vec::from_elem(num_nodes * words_per_id, 0); - let kills = Vec::from_elem(num_nodes * words_per_id, 0); - let on_entry = Vec::from_elem(num_nodes * words_per_id, entry); + let gens: Vec<_> = repeat(0).take(num_nodes * words_per_id).collect(); + let kills: Vec<_> = repeat(0).take(num_nodes * words_per_id).collect(); + let on_entry: Vec<_> = repeat(entry).take(num_nodes * words_per_id).collect(); let nodeid_to_index = build_nodeid_to_index(decl, cfg); @@ -446,7 +447,7 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { changed: true }; - let mut temp = Vec::from_elem(words_per_id, 0u); + let mut temp: Vec<_> = repeat(0u).take(words_per_id).collect(); while propcx.changed { propcx.changed = false; propcx.reset(temp.as_mut_slice()); diff --git a/src/librustc/middle/infer/error_reporting.rs b/src/librustc/middle/infer/error_reporting.rs index e38b721ce2d..6f1c7af5b86 100644 --- a/src/librustc/middle/infer/error_reporting.rs +++ b/src/librustc/middle/infer/error_reporting.rs @@ -1187,7 +1187,7 @@ impl<'a, 'tcx> Rebuilder<'a, 'tcx> { let mut new_ty = P(ty.clone()); let mut ty_queue = vec!(ty); while !ty_queue.is_empty() { - let cur_ty = ty_queue.remove(0).unwrap(); + let cur_ty = ty_queue.remove(0); match cur_ty.node { ast::TyRptr(lt_opt, ref mut_ty) => { let rebuild = match lt_opt { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 386768bd9d6..91fbaca26d1 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -799,7 +799,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } pub fn next_ty_vars(&self, n: uint) -> Vec> { - Vec::from_fn(n, |_i| self.next_ty_var()) + range(0, n).map(|_i| self.next_ty_var()).collect() } pub fn next_int_var_id(&self) -> IntVid { diff --git a/src/librustc/middle/infer/region_inference/mod.rs b/src/librustc/middle/infer/region_inference/mod.rs index 97fab3bc939..7372bb267b0 100644 --- a/src/librustc/middle/infer/region_inference/mod.rs +++ b/src/librustc/middle/infer/region_inference/mod.rs @@ -34,6 +34,7 @@ use util::ppaux::Repr; use std::cell::{Cell, RefCell}; use std::u32; +use std::iter::repeat; use syntax::ast; mod doc; @@ -975,7 +976,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } fn construct_var_data(&self) -> Vec { - Vec::from_fn(self.num_vars() as uint, |_| { + range(0, self.num_vars() as uint).map(|_| { VarData { // All nodes are initially classified as contracting; during // the expansion phase, we will shift the classification for @@ -984,7 +985,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { classification: Contracting, value: NoValue, } - }) + }).collect() } fn dump_constraints(&self) { @@ -1247,7 +1248,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { // idea is to report errors that derive from independent // regions of the graph, but not those that derive from // overlapping locations. - let mut dup_vec = Vec::from_elem(self.num_vars() as uint, u32::MAX); + let mut dup_vec: Vec<_> = repeat(u32::MAX).take(self.num_vars() as uint).collect(); let mut opt_graph = None; @@ -1308,7 +1309,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> { } } - Vec::from_fn(self.num_vars() as uint, |idx| var_data[idx].value) + range(0, self.num_vars() as uint).map(|idx| var_data[idx].value).collect() } fn construct_graph(&self) -> RegionGraph { diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index d3859ca12a9..5be8d03e743 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -117,6 +117,7 @@ use util::nodemap::NodeMap; use std::{fmt, io, uint}; use std::rc::Rc; +use std::iter::repeat; use syntax::ast::{mod, NodeId, Expr}; use syntax::codemap::{BytePos, original_sp, Span}; use syntax::parse::token::{mod, special_idents}; @@ -575,8 +576,8 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { Liveness { ir: ir, s: specials, - successors: Vec::from_elem(num_live_nodes, invalid_node()), - users: Vec::from_elem(num_live_nodes * num_vars, invalid_users()), + successors: repeat(invalid_node()).take(num_live_nodes).collect(), + users: repeat(invalid_users()).take(num_live_nodes * num_vars).collect(), loop_scope: Vec::new(), break_ln: NodeMap::new(), cont_ln: NodeMap::new(), @@ -1068,7 +1069,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { // the same bindings, and we also consider the first pattern to be // the "authoritative" set of ids let arm_succ = - self.define_bindings_in_arm_pats(arm.pats.head().map(|p| &**p), + self.define_bindings_in_arm_pats(arm.pats.first().map(|p| &**p), guard_succ); self.merge_from_succ(ln, arm_succ, first_merge); first_merge = false; @@ -1436,7 +1437,7 @@ fn check_arm(this: &mut Liveness, arm: &ast::Arm) { // only consider the first pattern; any later patterns must have // the same bindings, and we also consider the first pattern to be // the "authoritative" set of ids - this.arm_pats_bindings(arm.pats.head().map(|p| &**p), |this, ln, var, sp, id| { + this.arm_pats_bindings(arm.pats.first().map(|p| &**p), |this, ln, var, sp, id| { this.warn_about_unused(sp, id, ln, var); }); visit::walk_arm(this, arm); @@ -1542,7 +1543,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } else { let ends_with_stmt = match body.expr { None if body.stmts.len() > 0 => - match body.stmts.last().unwrap().node { + match body.stmts.first().unwrap().node { ast::StmtSemi(ref e, _) => { ty::expr_ty(self.ir.tcx, &**e) == t_ret }, @@ -1553,7 +1554,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { self.ir.tcx.sess.span_err( sp, "not all control paths return a value"); if ends_with_stmt { - let last_stmt = body.stmts.last().unwrap(); + let last_stmt = body.stmts.first().unwrap(); let original_span = original_sp(self.ir.tcx.sess.codemap(), last_stmt.span, sp); let span_semicolon = Span { diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 730da26eda3..edba2839f37 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -751,10 +751,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> { let orig_def = self.tcx.def_map.borrow()[path_id].clone(); let ck = |tyname: &str| { let ck_public = |def: ast::DefId| { - let name = token::get_ident(path.segments - .last() - .unwrap() - .identifier); + let name = token::get_ident(path.segments.last().unwrap().identifier); let origdid = orig_def.def_id(); self.ensure_public(span, def, diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 4feafff3b92..e9504a92f7b 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -296,7 +296,7 @@ impl<'a> LifetimeContext<'a> { debug!("visit_early_late: referenced_idents={}", referenced_idents); - let (early, late) = generics.lifetimes.clone().partition( + let (early, late): (Vec<_>, _) = generics.lifetimes.iter().cloned().partition( |l| referenced_idents.iter().any(|&i| i == l.lifetime.name)); self.with(EarlyScope(early_space, &early, self.scope), move |old_scope, this| { diff --git a/src/librustc/middle/subst.rs b/src/librustc/middle/subst.rs index 3066ae5b479..07da9853e55 100644 --- a/src/librustc/middle/subst.rs +++ b/src/librustc/middle/subst.rs @@ -323,7 +323,11 @@ impl VecPerParamSpace { SelfSpace => { self.self_limit -= 1; } FnSpace => {} } - self.content.remove(limit - 1) + if self.content.is_empty() { + None + } else { + Some(self.content.remove(limit - 1)) + } } } diff --git a/src/librustc/util/lev_distance.rs b/src/librustc/util/lev_distance.rs index 24e98837444..e7c77b12499 100644 --- a/src/librustc/util/lev_distance.rs +++ b/src/librustc/util/lev_distance.rs @@ -14,7 +14,7 @@ pub fn lev_distance(me: &str, t: &str) -> uint { if me.is_empty() { return t.chars().count(); } if t.is_empty() { return me.chars().count(); } - let mut dcol = Vec::from_fn(t.len() + 1, |x| x); + let mut dcol: Vec<_> = range(0, t.len() + 1).collect(); let mut t_last = 0; for (i, sc) in me.chars().enumerate() { diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs index e1f0168d86b..a7d1d3a23bd 100644 --- a/src/librustc_back/sha2.rs +++ b/src/librustc_back/sha2.rs @@ -14,7 +14,7 @@ #![allow(deprecated)] // to_be32 -use std::iter::range_step; +use std::iter::{range_step, repeat}; use std::num::Int; use std::slice::bytes::{MutableByteVector, copy_memory}; use serialize::hex::ToHex; @@ -258,7 +258,7 @@ pub trait Digest { /// Convenience function that retrieves the result of a digest as a /// newly allocated vec of bytes. fn result_bytes(&mut self) -> Vec { - let mut buf = Vec::from_elem((self.output_bits()+7)/8, 0u8); + let mut buf: Vec = repeat(0u8).take((self.output_bits()+7)/8).collect(); self.result(buf.as_mut_slice()); buf } @@ -612,7 +612,7 @@ mod tests { /// correct. fn test_digest_1million_random(digest: &mut D, blocksize: uint, expected: &str) { let total_size = 1000000; - let buffer = Vec::from_elem(blocksize * 2, 'a' as u8); + let buffer: Vec = repeat('a' as u8).take(blocksize * 2).collect(); let mut rng = IsaacRng::new_unseeded(); let mut count = 0; diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index 7609554033c..070ae1151aa 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -25,7 +25,6 @@ use rustc::middle::mem_categorization as mc; use rustc::util::ppaux::{Repr, UserString}; use std::mem; use std::rc::Rc; -use std::slice; use syntax::ast; use syntax::ast_map; use syntax::attr::AttrMetaMethods; @@ -268,9 +267,9 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) { return; fn non_member(elem: MovePathIndex, set: &[MovePathIndex]) -> bool { - match set.binary_search_elem(&elem) { - slice::BinarySearchResult::Found(_) => false, - slice::BinarySearchResult::NotFound(_) => true, + match set.binary_search(&elem) { + Ok(_) => false, + Err(_) => true, } } } diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs index e71e9e5dfea..664d470b11b 100644 --- a/src/librustc_borrowck/lib.rs +++ b/src/librustc_borrowck/lib.rs @@ -37,4 +37,3 @@ pub use borrowck::FnPartsWithCFG; mod borrowck; pub mod graphviz; - diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index e20404bf638..0d98434d042 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -265,11 +265,13 @@ Available lint options: lints } - let (plugin, builtin) = lint_store.get_lints().partitioned(|&(_, p)| p); + let (plugin, builtin): (Vec<_>, _) = lint_store.get_lints() + .iter().cloned().partition(|&(_, p)| p); let plugin = sort_lints(plugin); let builtin = sort_lints(builtin); - let (plugin_groups, builtin_groups) = lint_store.get_lint_groups().partitioned(|&(_, _, p)| p); + let (plugin_groups, builtin_groups): (Vec<_>, _) = lint_store.get_lint_groups() + .iter().cloned().partition(|&(_, _, p)| p); let plugin_groups = sort_lint_groups(plugin_groups); let builtin_groups = sort_lint_groups(builtin_groups); @@ -377,7 +379,7 @@ fn describe_codegen_flags() { /// returns None. pub fn handle_options(mut args: Vec) -> Option { // Throw away the first argument, the name of the binary - let _binary = args.remove(0).unwrap(); + let _binary = args.remove(0); if args.is_empty() { // user did not write `-v` nor `-Z unstable-options`, so do not diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 6b504d6d16e..e371046a9b2 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3554,9 +3554,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(def) => { debug!("(resolving type) resolved `{}` to \ type {}", - token::get_ident(path.segments - .last().unwrap() - .identifier), + token::get_ident(path.segments.last().unwrap() .identifier), def); result_def = Some(def); } @@ -3747,19 +3745,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.resolve_error(path.span, format!("`{}` is not an enum variant, struct or const", token::get_ident( - path.segments - .last() - .unwrap() - .identifier))[]); + path.segments.last().unwrap().identifier))[]); } None => { self.resolve_error(path.span, format!("unresolved enum variant, struct or const `{}`", token::get_ident( - path.segments - .last() - .unwrap() - .identifier))[]); + path.segments.last().unwrap().identifier))[]); } } @@ -3913,9 +3905,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Try to find a path to an item in a module. let unqualified_def = - self.resolve_identifier(path.segments - .last().unwrap() - .identifier, + self.resolve_identifier(path.segments.last().unwrap().identifier, namespace, check_ribs, path.span); diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 0e37cd0f3b8..c6e4ce9457b 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -606,9 +606,9 @@ fn extract_variant_args<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, val: ValueRef) -> ExtractedBlock<'blk, 'tcx> { let _icx = push_ctxt("match::extract_variant_args"); - let args = Vec::from_fn(adt::num_args(repr, disr_val), |i| { + let args = range(0, adt::num_args(repr, disr_val)).map(|i| { adt::trans_field_ptr(bcx, repr, val, disr_val, i) - }); + }).collect(); ExtractedBlock { vals: args, bcx: bcx } } diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 9b678a4f3ae..fffdc9c97ab 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -23,6 +23,7 @@ use trans::context::CrateContext; use trans::type_::Type; use std::cmp; +use std::iter::repeat; #[deriving(Clone, Copy, PartialEq)] enum RegClass { @@ -286,7 +287,7 @@ fn classify_ty(ty: Type) -> Vec { } let words = (ty_size(ty) + 7) / 8; - let mut cls = Vec::from_elem(words, NoClass); + let mut cls: Vec<_> = repeat(NoClass).take(words).collect(); if words > 4 { all_mem(cls.as_mut_slice()); return cls; diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 0fd6d286e8b..1f01da8a124 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -25,6 +25,7 @@ use middle::ty::{mod, Ty}; use util::ppaux::{Repr, ty_to_string}; use std::c_str::ToCStr; +use std::iter::repeat; use libc::c_uint; use syntax::{ast, ast_util}; use syntax::ptr::P; @@ -608,7 +609,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef { const_eval::const_uint(i) => i as uint, _ => cx.sess().span_bug(count.span, "count must be integral const expression.") }; - let vs = Vec::from_elem(n, const_expr(cx, &**elem).0); + let vs: Vec<_> = repeat(const_expr(cx, &**elem).0).take(n).collect(); if vs.iter().any(|vi| val_ty(*vi) != llunitty) { C_struct(cx, vs[], false) } else { diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index 91989b5f7c0..589250430cd 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3405,10 +3405,7 @@ fn create_scope_map(cx: &CrateContext, if need_new_scope { // Create a new lexical scope and push it onto the stack let loc = cx.sess().codemap().lookup_char_pos(pat.span.lo); - let file_metadata = file_metadata(cx, - loc.file - .name - []); + let file_metadata = file_metadata(cx, loc.file.name[]); let parent_scope = scope_stack.last().unwrap().scope_metadata; let scope_metadata = unsafe { diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 5a20a297fdb..7587adae5b7 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -68,6 +68,7 @@ use syntax::print::pprust::{expr_to_string}; use syntax::ptr::P; use syntax::parse::token; use std::rc::Rc; +use std::iter::repeat; // Destinations @@ -1413,7 +1414,7 @@ fn trans_struct<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, let tcx = bcx.tcx(); with_field_tys(tcx, ty, Some(expr_id), |discr, field_tys| { - let mut need_base = Vec::from_elem(field_tys.len(), true); + let mut need_base: Vec<_> = repeat(true).take(field_tys.len()).collect(); let numbered_fields = fields.iter().map(|field| { let opt_pos = diff --git a/src/librustc_trans/trans/type_.rs b/src/librustc_trans/trans/type_.rs index 45a2a343066..2cc40a61795 100644 --- a/src/librustc_trans/trans/type_.rs +++ b/src/librustc_trans/trans/type_.rs @@ -22,6 +22,7 @@ use syntax::ast; use std::c_str::ToCStr; use std::mem; use std::cell::RefCell; +use std::iter::repeat; use libc::c_uint; @@ -282,7 +283,7 @@ impl Type { if n_elts == 0 { return Vec::new(); } - let mut elts = Vec::from_elem(n_elts, Type { rf: 0 as TypeRef }); + let mut elts: Vec<_> = repeat(Type { rf: 0 as TypeRef }).take(n_elts).collect(); llvm::LLVMGetStructElementTypes(self.to_ref(), elts.as_mut_ptr() as *mut TypeRef); elts @@ -296,7 +297,7 @@ impl Type { pub fn func_params(&self) -> Vec { unsafe { let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint; - let mut args = Vec::from_elem(n_args, Type { rf: 0 as TypeRef }); + let mut args: Vec<_> = repeat(Type { rf: 0 as TypeRef }).take(n_args).collect(); llvm::LLVMGetParamTypes(self.to_ref(), args.as_mut_ptr() as *mut TypeRef); args diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 587a85cfcba..dee9aafd06d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -62,7 +62,7 @@ use util::nodemap::DefIdMap; use util::ppaux::{mod, Repr, UserString}; use std::rc::Rc; -use std::iter::AdditiveIterator; +use std::iter::{repeat, AdditiveIterator}; use syntax::{abi, ast, ast_util}; use syntax::codemap::Span; use syntax::parse::token; @@ -317,8 +317,8 @@ fn create_substs_for_ast_path<'tcx,AC,RS>( match anon_regions { Ok(v) => v.into_iter().collect(), - Err(_) => Vec::from_fn(expected_num_region_params, - |_| ty::ReStatic) // hokey + Err(_) => range(0, expected_num_region_params) + .map(|_| ty::ReStatic).collect() // hokey } }; @@ -500,7 +500,7 @@ fn convert_parenthesized_parameters<'tcx,AC>(this: &AC, .map(|a_t| ast_ty_to_ty(this, &binding_rscope, &**a_t)) .collect::>>(); - let input_params = Vec::from_elem(inputs.len(), String::new()); + let input_params: Vec<_> = repeat(String::new()).take(inputs.len()).collect(); let (implied_output_region, params_lifetimes) = find_implied_output_region(&*inputs, input_params); @@ -734,8 +734,8 @@ pub fn ast_path_to_ty_relaxed<'tcx,AC,RS>( path.segments.iter().all(|s| s.parameters.is_empty()); let substs = if needs_defaults { - let type_params = Vec::from_fn(generics.types.len(TypeSpace), - |_| this.ty_infer(path.span)); + let type_params: Vec<_> = range(0, generics.types.len(TypeSpace)) + .map(|_| this.ty_infer(path.span)).collect(); let region_params = rscope.anon_regions(path.span, generics.regions.len(TypeSpace)) .unwrap(); @@ -1528,21 +1528,18 @@ fn conv_ty_poly_trait_ref<'tcx, AC, RS>( let mut partitioned_bounds = partition_bounds(this.tcx(), span, ast_bounds[]); let mut projection_bounds = Vec::new(); - let main_trait_bound = match partitioned_bounds.trait_bounds.remove(0) { - Some(trait_bound) => { - let ptr = instantiate_poly_trait_ref(this, - rscope, - trait_bound, - None, - &mut projection_bounds); - Some(ptr) - } - None => { - this.tcx().sess.span_err( - span, - "at least one non-builtin trait is required for an object type"); - None - } + let main_trait_bound = if !partitioned_bounds.trait_bounds.is_empty() { + let trait_bound = partitioned_bounds.trait_bounds.remove(0); + Some(instantiate_poly_trait_ref(this, + rscope, + trait_bound, + None, + &mut projection_bounds)) + } else { + this.tcx().sess.span_err( + span, + "at least one non-builtin trait is required for an object type"); + None }; let bounds = diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 0e8b5b373f1..7c431b4fc0b 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -124,7 +124,8 @@ pub fn check_pat<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, check_pat_struct(pcx, pat, path, fields.as_slice(), etc, expected); } ast::PatTup(ref elements) => { - let element_tys = Vec::from_fn(elements.len(), |_| fcx.infcx().next_ty_var()); + let element_tys: Vec<_> = range(0, elements.len()).map(|_| fcx.infcx() + .next_ty_var()).collect(); let pat_ty = ty::mk_tup(tcx, element_tys.clone()); fcx.write_ty(pat.id, pat_ty); demand::eqtype(fcx, pat.span, expected, pat_ty); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index a189f780b0c..a751b65a0f8 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -24,6 +24,7 @@ use syntax::ast; use syntax::codemap::Span; use std::rc::Rc; use std::mem; +use std::iter::repeat; use util::ppaux::Repr; struct ConfirmContext<'a, 'tcx:'a> { @@ -339,7 +340,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> { } else if num_supplied_types != num_method_types { span_err!(self.tcx().sess, self.span, E0036, "incorrect number of type parameters given for this method"); - Vec::from_elem(num_method_types, self.tcx().types.err) + repeat(self.tcx().types.err).take(num_method_types).collect() } else { supplied_method_types } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8069d00dda8..f3a4a8d177e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -110,6 +110,7 @@ use util::nodemap::{DefIdMap, FnvHashMap, NodeMap}; use std::cell::{Cell, Ref, RefCell}; use std::mem::replace; use std::rc::Rc; +use std::iter::repeat; use syntax::{mod, abi, attr}; use syntax::ast::{mod, ProvidedMethod, RequiredMethod, TypeTraitItem, DefId}; use syntax::ast_util::{mod, local_def, PostExpansionMethod}; @@ -2130,9 +2131,9 @@ impl<'a, 'tcx> RegionScope for FnCtxt<'a, 'tcx> { fn anon_regions(&self, span: Span, count: uint) -> Result, Option>> { - Ok(Vec::from_fn(count, |_| { + Ok(range(0, count).map(|_| { self.infcx().next_region_var(infer::MiscVariable(span)) - })) + }).collect()) } } @@ -2810,7 +2811,7 @@ fn check_argument_types<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // FIXME(#17596) Ty<'tcx> is incorrectly invariant w.r.t 'tcx. fn err_args<'tcx>(tcx: &ty::ctxt<'tcx>, len: uint) -> Vec> { - Vec::from_fn(len, |_| tcx.types.err) + range(0, len).map(|_| tcx.types.err).collect() } fn write_call<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, @@ -5166,7 +5167,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, // The first step then is to categorize the segments appropriately. assert!(path.segments.len() >= 1); - let mut segment_spaces; + let mut segment_spaces: Vec<_>; match def { // Case 1 and 1b. Reference to a *type* or *enum variant*. def::DefSelfTy(..) | @@ -5181,7 +5182,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, def::DefTyParam(..) => { // Everything but the final segment should have no // parameters at all. - segment_spaces = Vec::from_elem(path.segments.len() - 1, None); + segment_spaces = repeat(None).take(path.segments.len() - 1).collect(); segment_spaces.push(Some(subst::TypeSpace)); } @@ -5189,7 +5190,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, def::DefFn(..) | def::DefConst(..) | def::DefStatic(..) => { - segment_spaces = Vec::from_elem(path.segments.len() - 1, None); + segment_spaces = repeat(None).take(path.segments.len() - 1).collect(); segment_spaces.push(Some(subst::FnSpace)); } @@ -5205,7 +5206,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, def::FromImpl(_) => {} } - segment_spaces = Vec::from_elem(path.segments.len() - 2, None); + segment_spaces = repeat(None).take(path.segments.len() - 2).collect(); segment_spaces.push(Some(subst::TypeSpace)); segment_spaces.push(Some(subst::FnSpace)); } @@ -5220,7 +5221,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, def::DefRegion(..) | def::DefLabel(..) | def::DefUpvar(..) => { - segment_spaces = Vec::from_elem(path.segments.len(), None); + segment_spaces = repeat(None).take(path.segments.len()).collect(); } } assert_eq!(segment_spaces.len(), path.segments.len()); @@ -5489,8 +5490,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>, "too few type parameters provided: expected {}{} parameter(s) \ , found {} parameter(s)", qualifier, required_len, provided_len); - substs.types.replace(space, - Vec::from_elem(desired.len(), fcx.tcx().types.err)); + substs.types.replace(space, repeat(fcx.tcx().types.err).take(desired.len()).collect()); return; } @@ -5614,7 +5614,7 @@ pub fn check_bounds_are_used<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, // make a vector of booleans initially false, set to true when used if tps.len() == 0u { return; } - let mut tps_used = Vec::from_elem(tps.len(), false); + let mut tps_used: Vec<_> = repeat(false).take(tps.len()).collect(); ty::walk_ty(ty, |t| { match t.sty { diff --git a/src/librustc_typeck/check/regionmanip.rs b/src/librustc_typeck/check/regionmanip.rs index bb051ab1525..42ffe2d5327 100644 --- a/src/librustc_typeck/check/regionmanip.rs +++ b/src/librustc_typeck/check/regionmanip.rs @@ -409,4 +409,3 @@ impl<'tcx> Repr<'tcx> for WfConstraint<'tcx> { } } } - diff --git a/src/librustc_typeck/rscope.rs b/src/librustc_typeck/rscope.rs index a97dce88a57..c62218313f4 100644 --- a/src/librustc_typeck/rscope.rs +++ b/src/librustc_typeck/rscope.rs @@ -13,6 +13,7 @@ use middle::ty; use middle::ty_fold; use std::cell::Cell; +use std::iter::repeat; use syntax::codemap::Span; /// Defines strategies for handling regions that are omitted. For @@ -99,7 +100,7 @@ impl RegionScope for SpecificRscope { count: uint) -> Result, Option>> { - Ok(Vec::from_elem(count, self.default)) + Ok(repeat(self.default).take(count).collect()) } } @@ -134,7 +135,7 @@ impl RegionScope for BindingRscope { count: uint) -> Result, Option>> { - Ok(Vec::from_fn(count, |_| self.next_region())) + Ok(range(0, count).map(|_| self.next_region()).collect()) } } diff --git a/src/librustc_typeck/variance.rs b/src/librustc_typeck/variance.rs index c4c33f24f87..de0b0a7ad35 100644 --- a/src/librustc_typeck/variance.rs +++ b/src/librustc_typeck/variance.rs @@ -199,6 +199,7 @@ use middle::subst::{ParamSpace, FnSpace, TypeSpace, SelfSpace, VecPerParamSpace} use middle::ty::{mod, Ty}; use std::fmt; use std::rc::Rc; +use std::iter::repeat; use syntax::ast; use syntax::ast_map; use syntax::ast_util; @@ -971,7 +972,7 @@ struct SolveContext<'a, 'tcx: 'a> { fn solve_constraints(constraints_cx: ConstraintContext) { let ConstraintContext { terms_cx, constraints, .. } = constraints_cx; - let solutions = Vec::from_elem(terms_cx.num_inferred(), ty::Bivariant); + let solutions: Vec<_> = repeat(ty::Bivariant).take(terms_cx.num_inferred()).collect(); let mut solutions_cx = SolveContext { terms_cx: terms_cx, constraints: constraints, diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index dc264a5b5aa..3c09a10f3d9 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -398,7 +398,7 @@ fn primitive_link(f: &mut fmt::Formatter, Some(root) => { try!(write!(f, "", root, - path.0.head().unwrap(), + path.0.first().unwrap(), prim.to_url_str())); needs_termination = true; } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index bfb03cb2589..f8a0b88b408 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1799,7 +1799,7 @@ fn item_trait(w: &mut fmt::Formatter, cx: &Context, it: &clean::Item, try!(write!(w, r#""#, - root_path = Vec::from_elem(cx.current.len(), "..").connect("/"), + root_path = repeat("..").take(cx.current.len()).collect::>().connect("/"), path = if ast_util::is_local(it.def_id) { cx.current.connect("/") } else { @@ -2055,7 +2055,8 @@ fn render_struct(w: &mut fmt::Formatter, it: &clean::Item, fn render_methods(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { match cache().impls.get(&it.def_id) { Some(v) => { - let (non_trait, traits) = v.partitioned(|i| i.impl_.trait_.is_none()); + let (non_trait, traits): (Vec<_>, _) = v.iter().cloned() + .partition(|i| i.impl_.trait_.is_none()); if non_trait.len() > 0 { try!(write!(w, "

Methods

")); for i in non_trait.iter() { @@ -2065,7 +2066,8 @@ fn render_methods(w: &mut fmt::Formatter, it: &clean::Item) -> fmt::Result { if traits.len() > 0 { try!(write!(w, "

Trait \ Implementations

")); - let (derived, manual) = traits.partition(|i| i.impl_.derived); + let (derived, manual): (Vec<_>, _) = traits.into_iter() + .partition(|i| i.impl_.derived); for i in manual.iter() { try!(render_impl(w, i)); } diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index 8dbaab564ba..4e22fc60080 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -74,7 +74,7 @@ use fmt; use hash; use mem; use ptr; -use slice::{mod, ImmutableIntSlice}; +use slice::{mod, IntSliceExt}; use str; use string::String; use core::kinds::marker; diff --git a/src/libstd/comm/sync.rs b/src/libstd/comm/sync.rs index 82ec1814ebd..a8004155af0 100644 --- a/src/libstd/comm/sync.rs +++ b/src/libstd/comm/sync.rs @@ -148,7 +148,7 @@ impl Packet { tail: 0 as *mut Node, }, buf: Buffer { - buf: Vec::from_fn(cap + if cap == 0 {1} else {0}, |_| None), + buf: range(0, cap + if cap == 0 {1} else {0}).map(|_| None).collect(), start: 0, size: 0, }, diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index fdbce101c1d..0fba0f6704b 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -439,9 +439,10 @@ mod test { impl Reader for ShortReader { fn read(&mut self, _: &mut [u8]) -> io::IoResult { - match self.lengths.remove(0) { - Some(i) => Ok(i), - None => Err(io::standard_error(io::EndOfFile)) + if self.lengths.is_empty() { + Err(io::standard_error(io::EndOfFile)) + } else { + Ok(self.lengths.remove(0)) } } } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 5c70340fe10..181c4c04c51 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -158,6 +158,7 @@ pub use alloc::rc; pub use core_collections::slice; pub use core_collections::str; pub use core_collections::string; +#[stable] pub use core_collections::vec; pub use unicode::char; diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 989f44f7b8e..a9d9607395c 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -620,10 +620,11 @@ pub fn get_exit_status() -> int { unsafe fn load_argc_and_argv(argc: int, argv: *const *const c_char) -> Vec> { use c_str::CString; + use iter::range; - Vec::from_fn(argc as uint, |i| { + range(0, argc as uint).map(|i| { CString::new(*argv.offset(i as int), false).as_bytes_no_nul().to_vec() - }) + }).collect() } /// Returns the command line arguments @@ -721,7 +722,7 @@ fn real_args() -> Vec { let lpCmdLine = unsafe { GetCommandLineW() }; let szArgList = unsafe { CommandLineToArgvW(lpCmdLine, lpArgCount) }; - let args = Vec::from_fn(nArgs as uint, |i| unsafe { + let args: Vec<_> = range(0, nArgs as uint).map(|i| unsafe { // Determine the length of this argument. let ptr = *szArgList.offset(i as int); let mut len = 0; @@ -732,7 +733,7 @@ fn real_args() -> Vec { let buf = slice::from_raw_buf(&ptr, len); let opt_s = String::from_utf16(sys::os::truncate_utf16_at_nul(buf)); opt_s.ok().expect("CommandLineToArgvW returned invalid UTF-16") - }); + }).collect(); unsafe { LocalFree(szArgList as *mut c_void); diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 60f147eac9b..bd4031e6230 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -22,14 +22,14 @@ use option::Option::{None, Some}; use kinds::Sized; use str::{FromStr, Str}; use str; -use slice::{CloneSliceExt, Splits, AsSlice, VectorVector, +use slice::{CloneSliceExt, Split, AsSlice, SliceConcatExt, PartialEqSliceExt, SliceExt}; use vec::Vec; use super::{BytesContainer, GenericPath, GenericPathUnsafe}; /// Iterator that yields successive components of a Path as &[u8] -pub type Components<'a> = Splits<'a, u8, fn(&u8) -> bool>; +pub type Components<'a> = Split<'a, u8, fn(&u8) -> bool>; /// Iterator that yields successive components of a Path as Option<&str> pub type StrComponents<'a> = @@ -306,7 +306,7 @@ impl GenericPath for Path { } } } - Some(Path::new(comps.connect_vec(&SEP_BYTE))) + Some(Path::new(comps.as_slice().connect(&SEP_BYTE))) } } diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 879a96e8026..751ed4b70fb 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -25,8 +25,8 @@ use iter::{Iterator, IteratorExt, Map, repeat}; use mem; use option::Option; use option::Option::{Some, None}; -use slice::SliceExt; -use str::{SplitTerminator, FromStr, StrVector, StrExt}; +use slice::{SliceExt, SliceConcatExt}; +use str::{SplitTerminator, FromStr, StrExt}; use string::{String, ToString}; use unicode::char::UnicodeChar; use vec::Vec; diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index fc59f06ae6c..f016683e3d0 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -66,7 +66,7 @@ #[doc(no_inline)] pub use iter::{FromIterator, Extend, ExactSizeIterator}; #[doc(no_inline)] pub use iter::{Iterator, IteratorExt, DoubleEndedIterator}; #[doc(no_inline)] pub use iter::{DoubleEndedIteratorExt, CloneIteratorExt}; -#[doc(no_inline)] pub use iter::{RandomAccessIterator, IteratorCloneExt}; +#[doc(no_inline)] pub use iter::{RandomAccessIterator, IteratorCloneExt, IteratorPairExt}; #[doc(no_inline)] pub use iter::{IteratorOrdExt, MutableDoubleEndedIterator}; #[doc(no_inline)] pub use num::{ToPrimitive, FromPrimitive}; #[doc(no_inline)] pub use boxed::Box; @@ -80,10 +80,9 @@ #[doc(no_inline)] pub use core::prelude::{Tuple1, Tuple2, Tuple3, Tuple4}; #[doc(no_inline)] pub use core::prelude::{Tuple5, Tuple6, Tuple7, Tuple8}; #[doc(no_inline)] pub use core::prelude::{Tuple9, Tuple10, Tuple11, Tuple12}; -#[doc(no_inline)] pub use str::{Str, StrVector}; -#[doc(no_inline)] pub use str::StrExt; +#[doc(no_inline)] pub use str::{Str, StrExt}; #[doc(no_inline)] pub use slice::AsSlice; -#[doc(no_inline)] pub use slice::{VectorVector, PartialEqSliceExt}; +#[doc(no_inline)] pub use slice::{SliceConcatExt, PartialEqSliceExt}; #[doc(no_inline)] pub use slice::{CloneSliceExt, OrdSliceExt, SliceExt}; #[doc(no_inline)] pub use slice::{BoxedSliceExt}; #[doc(no_inline)] pub use string::{IntoString, String, ToString}; diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs index b1f268597c7..98eff621ce0 100644 --- a/src/libstd/rt/args.rs +++ b/src/libstd/rt/args.rs @@ -95,14 +95,14 @@ mod imp { } unsafe fn load_argc_and_argv(argc: int, argv: *const *const u8) -> Vec> { - Vec::from_fn(argc as uint, |i| { + range(0, argc as uint).map(|i| { let arg = *argv.offset(i as int); let mut len = 0u; while *arg.offset(len as int) != 0 { len += 1u; } slice::from_raw_buf(&arg, len).to_vec() - }) + }).collect() } #[cfg(test)] diff --git a/src/libstd/sys/unix/timer.rs b/src/libstd/sys/unix/timer.rs index 1ababbc0d85..150ec6aad8a 100644 --- a/src/libstd/sys/unix/timer.rs +++ b/src/libstd/sys/unix/timer.rs @@ -120,9 +120,9 @@ fn helper(input: libc::c_int, messages: Receiver, _: ()) { // signals the first requests in the queue, possible re-enqueueing it. fn signal(active: &mut Vec>, dead: &mut Vec<(uint, Box)>) { - let mut timer = match active.remove(0) { - Some(timer) => timer, None => return - }; + if active.is_empty() { return } + + let mut timer = active.remove(0); let mut cb = timer.cb.take().unwrap(); cb.call(); if timer.repeat { @@ -185,7 +185,7 @@ fn helper(input: libc::c_int, messages: Receiver, _: ()) { Ok(RemoveTimer(id, ack)) => { match dead.iter().position(|&(i, _)| id == i) { Some(i) => { - let (_, i) = dead.remove(i).unwrap(); + let (_, i) = dead.remove(i); ack.send(i); continue } @@ -193,7 +193,7 @@ fn helper(input: libc::c_int, messages: Receiver, _: ()) { } let i = active.iter().position(|i| i.id == id); let i = i.expect("no timer found"); - let t = active.remove(i).unwrap(); + let t = active.remove(i); ack.send(t); } Err(..) => break diff --git a/src/libstd/sys/windows/os.rs b/src/libstd/sys/windows/os.rs index 5a7be63e39f..235ebf211ac 100644 --- a/src/libstd/sys/windows/os.rs +++ b/src/libstd/sys/windows/os.rs @@ -16,13 +16,14 @@ use prelude::*; use io::{IoResult, IoError}; +use iter::repeat; use libc::{c_int, c_void}; use libc; use os; use path::BytesContainer; use ptr; -use sys::fs::FileDesc; use slice; +use sys::fs::FileDesc; use os::TMPBUF_SZ; use libc::types::os::arch::extra::DWORD; @@ -128,7 +129,7 @@ pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD) -> Option = repeat(0u16).take(n).collect(); let k = f(buf.as_mut_ptr(), n); if k == (0 as DWORD) { done = true; diff --git a/src/libstd/sys/windows/tty.rs b/src/libstd/sys/windows/tty.rs index 607bb05f54f..415524733ff 100644 --- a/src/libstd/sys/windows/tty.rs +++ b/src/libstd/sys/windows/tty.rs @@ -33,6 +33,7 @@ use libc::{c_int, HANDLE, LPDWORD, DWORD, LPVOID}; use libc::{get_osfhandle, CloseHandle}; use libc::types::os::arch::extra::LPCVOID; use io::{mod, IoError, IoResult, MemReader}; +use iter::repeat; use prelude::*; use ptr; use str::from_utf8; @@ -90,7 +91,7 @@ impl TTY { pub fn read(&mut self, buf: &mut [u8]) -> IoResult { // Read more if the buffer is empty if self.utf8.eof() { - let mut utf16 = Vec::from_elem(0x1000, 0u16); + let mut utf16: Vec = repeat(0u16).take(0x1000).collect(); let mut num: DWORD = 0; match unsafe { ReadConsoleW(self.handle, utf16.as_mut_ptr() as LPVOID, diff --git a/src/libsyntax/ast_map/mod.rs b/src/libsyntax/ast_map/mod.rs index 5a4f5731be5..b5395d09ca7 100644 --- a/src/libsyntax/ast_map/mod.rs +++ b/src/libsyntax/ast_map/mod.rs @@ -26,7 +26,7 @@ use arena::TypedArena; use std::cell::RefCell; use std::fmt; use std::io::IoResult; -use std::iter; +use std::iter::{mod, repeat}; use std::mem; use std::slice; @@ -726,7 +726,7 @@ impl<'ast> NodeCollector<'ast> { debug!("ast_map: {} => {}", id, entry); let len = self.map.len(); if id as uint >= len { - self.map.grow(id as uint - len + 1, NotPresent); + self.map.extend(repeat(NotPresent).take(id as uint - len + 1)); } self.map[id as uint] = entry; } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index d2d624fa05e..9fcaf2210c1 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -470,7 +470,7 @@ pub fn expand_item(it: P, fld: &mut MacroExpander) fn expand_item_modifiers(mut it: P, fld: &mut MacroExpander) -> P { // partition the attributes into ItemModifiers and others - let (modifiers, other_attrs) = it.attrs.partitioned(|attr| { + let (modifiers, other_attrs): (Vec<_>, _) = it.attrs.iter().cloned().partition(|attr| { match fld.cx.syntax_env.find(&intern(attr.name().get())) { Some(rc) => match *rc { Modifier(_) => true, _ => false }, _ => false diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 6474d92953f..500070a14d2 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -22,6 +22,7 @@ use parse::token; use ptr::P; use std::collections::HashMap; +use std::iter::repeat; #[deriving(PartialEq)] enum ArgumentType { @@ -477,7 +478,7 @@ impl<'a, 'b> Context<'a, 'b> { /// to fn into_expr(mut self) -> P { let mut locals = Vec::new(); - let mut names = Vec::from_fn(self.name_positions.len(), |_| None); + let mut names: Vec<_> = repeat(None).take(self.name_positions.len()).collect(); let mut pats = Vec::new(); let mut heads = Vec::new(); @@ -664,7 +665,7 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, name_ordering: Vec, names: HashMap>) -> P { - let arg_types = Vec::from_fn(args.len(), |_| None); + let arg_types: Vec<_> = range(0, args.len()).map(|_| None).collect(); let mut cx = Context { ecx: ecx, args: args, @@ -707,13 +708,10 @@ pub fn expand_preparsed_format_args(ecx: &mut ExtCtxt, sp: Span, None => break } } - match parser.errors.remove(0) { - Some(error) => { - cx.ecx.span_err(cx.fmtsp, - format!("invalid format string: {}", error)[]); - return DummyResult::raw_expr(sp); - } - None => {} + if !parser.errors.is_empty() { + cx.ecx.span_err(cx.fmtsp, format!("invalid format string: {}", + parser.errors.remove(0))[]); + return DummyResult::raw_expr(sp); } if !cx.literal.is_empty() { let s = cx.trans_literal_string(); diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs index 73ef18b8449..65ecf701e8d 100644 --- a/src/libsyntax/ext/tt/macro_parser.rs +++ b/src/libsyntax/ext/tt/macro_parser.rs @@ -166,7 +166,7 @@ pub fn count_names(ms: &[TokenTree]) -> uint { pub fn initial_matcher_pos(ms: Rc>, sep: Option, lo: BytePos) -> Box { let match_idx_hi = count_names(ms[]); - let matches = Vec::from_fn(match_idx_hi, |_i| Vec::new()); + let matches: Vec<_> = range(0, match_idx_hi).map(|_| Vec::new()).collect(); box MatcherPos { stack: vec![], top_elts: TtSeq(ms), @@ -392,7 +392,8 @@ pub fn parse(sess: &ParseSess, cur_eis.push(new_ei); } - let matches = Vec::from_elem(ei.matches.len(), Vec::new()); + let matches: Vec<_> = range(0, ei.matches.len()) + .map(|_| Vec::new()).collect(); let ei_t = ei; cur_eis.push(box MatcherPos { stack: vec![], diff --git a/src/libsyntax/print/pp.rs b/src/libsyntax/print/pp.rs index ab0e0f9585c..a15f1ca354b 100644 --- a/src/libsyntax/print/pp.rs +++ b/src/libsyntax/print/pp.rs @@ -65,6 +65,7 @@ pub use self::Token::*; use std::io; use std::string; +use std::iter::repeat; #[deriving(Clone, Copy, PartialEq)] pub enum Breaks { @@ -166,9 +167,9 @@ pub fn mk_printer(out: Box, linewidth: uint) -> Printer { // fall behind. let n: uint = 3 * linewidth; debug!("mk_printer {}", linewidth); - let token: Vec = Vec::from_elem(n, Eof); - let size: Vec = Vec::from_elem(n, 0i); - let scan_stack: Vec = Vec::from_elem(n, 0u); + let token: Vec = repeat(Eof).take(n).collect(); + let size: Vec = repeat(0i).take(n).collect(); + let scan_stack: Vec = repeat(0u).take(n).collect(); Printer { out: out, buf_len: n, diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs index e1c8ff5011b..c1823231e24 100644 --- a/src/libsyntax/std_inject.rs +++ b/src/libsyntax/std_inject.rs @@ -163,7 +163,7 @@ impl<'a> fold::Folder for PreludeInjector<'a> { }), }; - let (crates, uses) = view_items.partitioned(|x| { + let (crates, uses): (Vec<_>, _) = view_items.iter().cloned().partition(|x| { match x.node { ast::ViewItemExternCrate(..) => true, _ => false, diff --git a/src/libterm/terminfo/parm.rs b/src/libterm/terminfo/parm.rs index bac2452524e..680ed55cd98 100644 --- a/src/libterm/terminfo/parm.rs +++ b/src/libterm/terminfo/parm.rs @@ -16,6 +16,7 @@ use self::FormatState::*; use self::FormatOp::*; use std::ascii::OwnedAsciiExt; use std::mem::replace; +use std::iter::repeat; #[deriving(Copy, PartialEq)] enum States { @@ -508,7 +509,7 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { if flags.precision > s.len() { let mut s_ = Vec::with_capacity(flags.precision); let n = flags.precision - s.len(); - s_.grow(n, b'0'); + s_.extend(repeat(b'0').take(n)); s_.extend(s.into_iter()); s = s_; } @@ -560,10 +561,10 @@ fn format(val: Param, op: FormatOp, flags: Flags) -> Result ,String> { if flags.width > s.len() { let n = flags.width - s.len(); if flags.left { - s.grow(n, b' '); + s.extend(repeat(b' ').take(n)); } else { let mut s_ = Vec::with_capacity(flags.width); - s_.grow(n, b' '); + s_.extend(repeat(b' ').take(n)); s_.extend(s.into_iter()); s = s_; } diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index 88dd6fce88f..c097e933790 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -990,8 +990,8 @@ fn run_tests(opts: &TestOpts, try!(callback(TeFiltered(filtered_descs))); - let (filtered_tests, filtered_benchs_and_metrics) = - filtered_tests.partition(|e| { + let (filtered_tests, filtered_benchs_and_metrics): (Vec<_>, _) = + filtered_tests.into_iter().partition(|e| { match e.testfn { StaticTestFn(_) | DynTestFn(_) => true, _ => false diff --git a/src/libunicode/normalize.rs b/src/libunicode/normalize.rs index d239cb82896..9e4aa071247 100644 --- a/src/libunicode/normalize.rs +++ b/src/libunicode/normalize.rs @@ -13,21 +13,21 @@ use core::cmp::Ordering::{Equal, Less, Greater}; use core::option::Option; use core::option::Option::{Some, None}; -use core::slice; use core::slice::SliceExt; +use core::result::Result::{Ok, Err}; use tables::normalization::{canonical_table, compatibility_table, composition_table}; fn bsearch_table(c: char, r: &'static [(char, &'static [T])]) -> Option<&'static [T]> { - match r.binary_search(|&(val, _)| { + match r.binary_search_by(|&(val, _)| { if c == val { Equal } else if val < c { Less } else { Greater } }) { - slice::BinarySearchResult::Found(idx) => { + Ok(idx) => { let (_, result) = r[idx]; Some(result) } - slice::BinarySearchResult::NotFound(_) => None + Err(_) => None } } @@ -81,16 +81,16 @@ pub fn compose(a: char, b: char) -> Option { match bsearch_table(a, composition_table) { None => None, Some(candidates) => { - match candidates.binary_search(|&(val, _)| { + match candidates.binary_search_by(|&(val, _)| { if b == val { Equal } else if val < b { Less } else { Greater } }) { - slice::BinarySearchResult::Found(idx) => { + Ok(idx) => { let (_, result) = candidates[idx]; Some(result) } - slice::BinarySearchResult::NotFound(_) => None + Err(_) => None } } } diff --git a/src/libunicode/tables.rs b/src/libunicode/tables.rs index a219aefad19..5a8f63f207e 100644 --- a/src/libunicode/tables.rs +++ b/src/libunicode/tables.rs @@ -19,11 +19,11 @@ pub const UNICODE_VERSION: (uint, uint, uint) = (7, 0, 0); fn bsearch_range_table(c: char, r: &'static [(char,char)]) -> bool { use core::cmp::Ordering::{Equal, Less, Greater}; use core::slice::SliceExt; - r.binary_search(|&(lo,hi)| { + r.binary_search_by(|&(lo,hi)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } - }).found().is_some() + }).is_ok() } pub mod general_category { @@ -6826,17 +6826,17 @@ pub mod normalization { fn bsearch_range_value_table(c: char, r: &'static [(char, char, u8)]) -> u8 { use core::cmp::Ordering::{Equal, Less, Greater}; use core::slice::SliceExt; - use core::slice; - match r.binary_search(|&(lo, hi, _)| { + use core::result::Result::{Ok, Err}; + match r.binary_search_by(|&(lo, hi, _)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } }) { - slice::BinarySearchResult::Found(idx) => { + Ok(idx) => { let (_, _, result) = r[idx]; result } - slice::BinarySearchResult::NotFound(_) => 0 + Err(_) => 0 } } @@ -6961,7 +6961,7 @@ pub mod conversions { use core::slice::SliceExt; use core::option::Option; use core::option::Option::{Some, None}; - use core::slice; + use core::result::Result::{Ok, Err}; pub fn to_lower(c: char) -> char { match bsearch_case_table(c, LuLl_table) { @@ -6978,13 +6978,13 @@ pub mod conversions { } fn bsearch_case_table(c: char, table: &'static [(char, char)]) -> Option { - match table.binary_search(|&(key, _)| { + match table.binary_search_by(|&(key, _)| { if c == key { Equal } else if key < c { Less } else { Greater } }) { - slice::BinarySearchResult::Found(i) => Some(i), - slice::BinarySearchResult::NotFound(_) => None, + Ok(i) => Some(i), + Err(_) => None, } } @@ -7596,20 +7596,20 @@ pub mod charwidth { use core::option::Option; use core::option::Option::{Some, None}; use core::slice::SliceExt; - use core::slice; + use core::result::Result::{Ok, Err}; fn bsearch_range_value_table(c: char, is_cjk: bool, r: &'static [(char, char, u8, u8)]) -> u8 { use core::cmp::Ordering::{Equal, Less, Greater}; - match r.binary_search(|&(lo, hi, _, _)| { + match r.binary_search_by(|&(lo, hi, _, _)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } }) { - slice::BinarySearchResult::Found(idx) => { + Ok(idx) => { let (_, _, r_ncjk, r_cjk) = r[idx]; if is_cjk { r_cjk } else { r_ncjk } } - slice::BinarySearchResult::NotFound(_) => 1 + Err(_) => 1 } } @@ -7804,7 +7804,7 @@ pub mod grapheme { use core::kinds::Copy; use core::slice::SliceExt; pub use self::GraphemeCat::*; - use core::slice; + use core::result::Result::{Ok, Err}; #[allow(non_camel_case_types)] #[deriving(Clone)] @@ -7825,16 +7825,16 @@ pub mod grapheme { fn bsearch_range_value_table(c: char, r: &'static [(char, char, GraphemeCat)]) -> GraphemeCat { use core::cmp::Ordering::{Equal, Less, Greater}; - match r.binary_search(|&(lo, hi, _)| { + match r.binary_search_by(|&(lo, hi, _)| { if lo <= c && c <= hi { Equal } else if hi < c { Less } else { Greater } }) { - slice::BinarySearchResult::Found(idx) => { + Ok(idx) => { let (_, _, cat) = r[idx]; cat } - slice::BinarySearchResult::NotFound(_) => GC_Any + Err(_) => GC_Any } } diff --git a/src/test/bench/core-std.rs b/src/test/bench/core-std.rs index d9a4aede7d7..26d4ec25c64 100644 --- a/src/test/bench/core-std.rs +++ b/src/test/bench/core-std.rs @@ -65,7 +65,7 @@ fn shift_push() { let mut v2 = Vec::new(); while v1.len() > 0 { - v2.push(v1.remove(0).unwrap()); + v2.push(v1.remove(0)); } } diff --git a/src/test/bench/shootout-reverse-complement.rs b/src/test/bench/shootout-reverse-complement.rs index 6ee2233f168..909f8afc34a 100644 --- a/src/test/bench/shootout-reverse-complement.rs +++ b/src/test/bench/shootout-reverse-complement.rs @@ -181,7 +181,7 @@ fn reverse_complement(seq: &mut [u8], tables: &Tables) { unsafe { copy_memory(seq.as_mut_ptr().offset((i - off + 1) as int), seq.as_ptr().offset((i - off) as int), off); - *seq.unsafe_mut(i - off) = b'\n'; + *seq.get_unchecked_mut(i - off) = b'\n'; } i += LINE_LEN + 1; } diff --git a/src/test/compile-fail/issue-15756.rs b/src/test/compile-fail/issue-15756.rs index df19de7731a..5be3b960ec6 100644 --- a/src/test/compile-fail/issue-15756.rs +++ b/src/test/compile-fail/issue-15756.rs @@ -9,9 +9,9 @@ // except according to those terms. use std::slice::Chunks; -use std::slice::MutChunks; +use std::slice::ChunksMut; -fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: MutChunks<'a,T>) +fn dft_iter<'a, T>(arg1: Chunks<'a,T>, arg2: ChunksMut<'a,T>) { for &something diff --git a/src/test/compile-fail/resolve-conflict-type-vs-import.rs b/src/test/compile-fail/resolve-conflict-type-vs-import.rs index de934286a7c..45b0314d2c0 100644 --- a/src/test/compile-fail/resolve-conflict-type-vs-import.rs +++ b/src/test/compile-fail/resolve-conflict-type-vs-import.rs @@ -15,4 +15,3 @@ struct Iter; fn main() { } -