1
Fork 0

libstd: Implement some convenience methods on vectors

This commit is contained in:
Patrick Walton 2014-02-18 21:36:51 -08:00
parent f8893ed5d9
commit 03b791095d
5 changed files with 223 additions and 11 deletions

View file

@ -11,20 +11,21 @@
// Migrate documentation over from `std::vec` when it is removed.
#[doc(hidden)];
use cast::{forget, transmute};
use clone::Clone;
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 num::CheckedMul;
use ops::Drop;
use option::{None, Option, Some};
use clone::Clone;
use iter::{DoubleEndedIterator, Iterator};
use num::CheckedMul;
use container::Container;
use mem::{size_of, move_val_init};
use cast::{forget, transmute};
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 ptr;
use rt::global_heap::{malloc_raw, realloc_raw};
use unstable::raw::Slice;
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> {
}
}
}