diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2014-02-18 21:36:51 -0800 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2014-02-21 10:54:14 -0800 |
| commit | 03b791095d6f6a0b4900ca9ad2e17fb4eb590fb7 (patch) | |
| tree | 4284f2d4c053438d0ec6d412cf3a79b50f571461 | |
| parent | f8893ed5d97180dc51d82df1bdbab989c4bde46d (diff) | |
| download | rust-03b791095d6f6a0b4900ca9ad2e17fb4eb590fb7.tar.gz rust-03b791095d6f6a0b4900ca9ad2e17fb4eb590fb7.zip | |
libstd: Implement some convenience methods on vectors
| -rw-r--r-- | src/libserialize/serialize.rs | 21 | ||||
| -rw-r--r-- | src/libstd/macros.rs | 10 | ||||
| -rw-r--r-- | src/libstd/str.rs | 13 | ||||
| -rw-r--r-- | src/libstd/to_bytes.rs | 8 | ||||
| -rw-r--r-- | src/libstd/vec_ng.rs | 178 |
5 files changed, 221 insertions, 9 deletions
diff --git a/src/libserialize/serialize.rs b/src/libserialize/serialize.rs index c4f0a7a1830..e57e7adcf8d 100644 --- a/src/libserialize/serialize.rs +++ b/src/libserialize/serialize.rs @@ -18,6 +18,7 @@ use std::hashmap::{HashMap, HashSet}; use std::rc::Rc; use std::trie::{TrieMap, TrieSet}; use std::vec; +use std::vec_ng::Vec; pub trait Encoder { // Primitive types: @@ -435,6 +436,26 @@ impl<D:Decoder,T:Decodable<D>> Decodable<D> for ~[T] { } } +impl<S:Encoder,T:Encodable<S>> Encodable<S> for Vec<T> { + fn encode(&self, s: &mut S) { + s.emit_seq(self.len(), |s| { + for (i, e) in self.iter().enumerate() { + s.emit_seq_elt(i, |s| e.encode(s)) + } + }) + } +} + +impl<D:Decoder,T:Decodable<D>> Decodable<D> for Vec<T> { + fn decode(d: &mut D) -> Vec<T> { + d.read_seq(|d, len| { + Vec::from_fn(len, |i| { + d.read_seq_elt(i, |d| Decodable::decode(d)) + }) + }) + } +} + impl<S:Encoder,T:Encodable<S>> Encodable<S> for Option<T> { fn encode(&self, s: &mut S) { s.emit_option(|s| { diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index 3e8a4d24f3e..490f2c9b198 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -358,3 +358,13 @@ macro_rules! local_data_key( macro_rules! try( ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) }) ) + +#[macro_export] +macro_rules! vec( + ($($e:expr),*) => ({ + let mut temp = ::std::vec_ng::Vec::new(); + $(temp.push($e);)* + temp + }) +) + diff --git a/src/libstd/str.rs b/src/libstd/str.rs index c3f79ff7139..123b4957599 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -101,6 +101,7 @@ use to_str::ToStr; use from_str::FromStr; use vec; use vec::{OwnedVector, OwnedCloneableVector, ImmutableVector, MutableVector}; +use vec_ng::Vec; use default::Default; use to_bytes::{IterBytes, Cb}; use unstable::raw::Repr; @@ -222,6 +223,18 @@ impl<'a, S: Str> StrVector for &'a [S] { } } +impl<'a, S: Str> StrVector for Vec<S> { + #[inline] + fn concat(&self) -> ~str { + self.as_slice().concat() + } + + #[inline] + fn connect(&self, sep: &str) -> ~str { + self.as_slice().connect(sep) + } +} + /// Something that can be used to compare against a character pub trait CharEq { /// Determine if the splitter should split at the given character diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index c8bd1907c5c..5518fa11684 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -21,6 +21,7 @@ use option::{None, Option, Some}; use rc::Rc; use str::{Str, StrSlice}; use vec::{Vector, ImmutableVector}; +use vec_ng::Vec; pub type Cb<'a> = 'a |buf: &[u8]| -> bool; @@ -266,6 +267,13 @@ impl<A:IterBytes> IterBytes for ~[A] { } } +impl<A:IterBytes> IterBytes for Vec<A> { + #[inline] + fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { + self.as_slice().iter_bytes(lsb0, f) + } +} + impl<'a> IterBytes for &'a str { #[inline] fn iter_bytes(&self, _lsb0: bool, f: Cb) -> bool { diff --git a/src/libstd/vec_ng.rs b/src/libstd/vec_ng.rs index a450aab127b..114f34963e2 100644 --- a/src/libstd/vec_ng.rs +++ b/src/libstd/vec_ng.rs @@ -11,20 +11,21 @@ // Migrate documentation over from `std::vec` when it is removed. #[doc(hidden)]; -use ops::Drop; -use option::{None, Option, Some}; +use cast::{forget, transmute}; use clone::Clone; -use iter::{DoubleEndedIterator, Iterator}; -use num::CheckedMul; +use cmp::{Eq, Ordering, TotalEq, TotalOrd}; use container::Container; +use iter::{DoubleEndedIterator, FromIterator, Iterator}; +use libc::{free, c_void}; use mem::{size_of, move_val_init}; -use cast::{forget, transmute}; +use num::CheckedMul; +use ops::Drop; +use option::{None, Option, Some}; +use ptr::RawPtr; +use ptr; use rt::global_heap::{malloc_raw, realloc_raw}; -use vec::{ImmutableVector, Items, MutableVector}; use unstable::raw::Slice; -use ptr; -use ptr::RawPtr; -use libc::{free, c_void}; +use vec::{ImmutableVector, Items, MutItems, MutableVector, RevItems}; pub struct Vec<T> { priv len: uint, @@ -71,6 +72,55 @@ impl<T: Clone> Vec<T> { xs } } + + #[inline] + pub fn push_all(&mut self, other: &[T]) { + for element in other.iter() { + self.push((*element).clone()) + } + } +} + +impl<T:Clone> Clone for Vec<T> { + fn clone(&self) -> Vec<T> { + let mut vector = Vec::with_capacity(self.len()); + for element in self.iter() { + vector.push((*element).clone()) + } + vector + } +} + +impl<T> FromIterator<T> for Vec<T> { + fn from_iterator<I:Iterator<T>>(iterator: &mut I) -> Vec<T> { + let (lower, _) = iterator.size_hint(); + let mut vector = Vec::with_capacity(lower); + for element in *iterator { + vector.push(element) + } + vector + } +} + +impl<T:Eq> Eq for Vec<T> { + #[inline] + fn eq(&self, other: &Vec<T>) -> bool { + self.as_slice() == other.as_slice() + } +} + +impl<T:TotalEq> TotalEq for Vec<T> { + #[inline] + fn equals(&self, other: &Vec<T>) -> bool { + self.as_slice().equals(&other.as_slice()) + } +} + +impl<T:TotalOrd> TotalOrd for Vec<T> { + #[inline] + fn cmp(&self, other: &Vec<T>) -> Ordering { + self.as_slice().cmp(&other.as_slice()) + } } impl<T> Container for Vec<T> { @@ -180,8 +230,117 @@ impl<T> Vec<T> { pub unsafe fn set_len(&mut self, len: uint) { self.len = len; } + + #[inline] + pub fn get<'a>(&'a self, index: uint) -> &'a T { + &self.as_slice()[index] + } + + #[inline] + pub fn get_mut<'a>(&'a mut self, index: uint) -> &'a mut T { + &mut self.as_mut_slice()[index] + } + + #[inline] + pub fn iter<'a>(&'a self) -> Items<'a,T> { + self.as_slice().iter() + } + + #[inline] + pub fn mut_iter<'a>(&'a mut self) -> MutItems<'a,T> { + self.as_mut_slice().mut_iter() + } + + #[inline] + pub fn sort_by(&mut self, compare: |&T, &T| -> Ordering) { + self.as_mut_slice().sort_by(compare) + } + + #[inline] + pub fn slice<'a>(&'a self, start: uint, end: uint) -> &'a [T] { + self.as_slice().slice(start, end) + } + + #[inline] + pub fn tail<'a>(&'a self) -> &'a [T] { + self.as_slice().tail() + } + + #[inline] + pub fn last<'a>(&'a self) -> Option<&'a T> { + self.as_slice().last() + } + + #[inline] + pub fn mut_last<'a>(&'a mut self) -> Option<&'a mut T> { + self.as_mut_slice().mut_last() + } + + #[inline] + pub fn swap_remove(&mut self, index: uint) -> T { + let length = self.len(); + if index >= length { + fail!("Vec::swap_remove - index {} >= length {}", index, length); + } + if index < length - 1 { + self.as_mut_slice().swap(index, length - 1); + } + self.pop().unwrap() + } + + #[inline] + pub fn unshift(&mut self, element: T) { + self.insert(0, element) + } + + pub fn insert(&mut self, index: uint, element: T) { + let len = self.len(); + assert!(index <= len); + // space for the new element + self.reserve_exact(len + 1); + + unsafe { // infallible + // The spot to put the new value + { + let slice = self.as_mut_slice(); + let p = slice.as_mut_ptr().offset(index as int); + // Shift everything over to make space. (Duplicating the + // `index`th element into two consecutive places.) + ptr::copy_memory(p.offset(1), &*p, len - index); + // Write it in, overwriting the first copy of the `index`th + // element. + move_val_init(&mut *p, element); + } + self.set_len(len + 1); + } + } + + #[inline] + pub fn rev_iter<'a>(&'a self) -> RevItems<'a,T> { + self.as_slice().rev_iter() + } + + #[inline] + pub fn map<U>(&self, f: |t: &T| -> U) -> Vec<U> { + self.iter().map(f).collect() + } + + pub fn push_all_move(&mut self, other: Vec<T>) { + for element in other.move_iter() { + self.push(element) + } + } + + pub fn slice_from<'a>(&'a self, start: uint) -> &'a [T] { + self.as_slice().slice_from(start) + } } +#[inline] +pub fn append<T:Clone>(mut first: Vec<T>, second: &[T]) -> Vec<T> { + first.push_all(second); + first +} #[unsafe_destructor] impl<T> Drop for Vec<T> { @@ -233,3 +392,4 @@ impl<T> Drop for MoveItems<T> { } } } + |
