about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-02-18 21:36:51 -0800
committerPatrick Walton <pcwalton@mimiga.net>2014-02-21 10:54:14 -0800
commit03b791095d6f6a0b4900ca9ad2e17fb4eb590fb7 (patch)
tree4284f2d4c053438d0ec6d412cf3a79b50f571461
parentf8893ed5d97180dc51d82df1bdbab989c4bde46d (diff)
downloadrust-03b791095d6f6a0b4900ca9ad2e17fb4eb590fb7.tar.gz
rust-03b791095d6f6a0b4900ca9ad2e17fb4eb590fb7.zip
libstd: Implement some convenience methods on vectors
-rw-r--r--src/libserialize/serialize.rs21
-rw-r--r--src/libstd/macros.rs10
-rw-r--r--src/libstd/str.rs13
-rw-r--r--src/libstd/to_bytes.rs8
-rw-r--r--src/libstd/vec_ng.rs178
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> {
         }
     }
 }
+