Skip to content

libstd: Implement some convenience methods on new vectors #12253

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 21, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions src/libserialize/serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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| {
Expand Down
10 changes: 10 additions & 0 deletions src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
})
)

13 changes: 13 additions & 0 deletions src/libstd/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions src/libstd/to_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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 {
Expand Down
178 changes: 169 additions & 9 deletions src/libstd/vec_ng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to keep using this definition of map on the new vectors? As I understand it, map on ~[T] is considered deprecated for a long time, as iterators allow one to express the same, and if we ever get Iterable it would conflict anyway.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it makes landing the ~[] removable easier, keep it: someone else can remove it later if necessary.

}

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> {
Expand Down Expand Up @@ -233,3 +392,4 @@ impl<T> Drop for MoveItems<T> {
}
}
}