Skip to content
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

Add some more methods to vec and vec::bytes #7210

Closed
wants to merge 2 commits into from
Closed
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
99 changes: 99 additions & 0 deletions src/libstd/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use cast::transmute;
use cast;
use container::{Container, Mutable};
use cmp;
use cmp::{Eq, Ord, TotalEq, TotalOrd, Ordering, Less, Equal, Greater};
use clone::Clone;
use old_iter::BaseIter;
Expand Down Expand Up @@ -2116,6 +2117,21 @@ pub trait MutableVector<'self, T> {
fn mut_iter(self) -> VecMutIterator<'self, T>;
fn mut_rev_iter(self) -> VecMutRevIterator<'self, T>;

/**
* 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 `str` to stop copying from
*/
fn move_from(self, src: ~[T], start: uint, end: uint) -> uint;

unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T;
unsafe fn unsafe_set(&self, index: uint, val: T);
}
Expand Down Expand Up @@ -2144,6 +2160,14 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
}
}

#[inline]
fn move_from(self, mut src: ~[T], start: uint, end: uint) -> uint {
for self.mut_iter().zip(src.mut_slice(start, end).mut_iter()).advance |(a, b)| {
util::swap(a, b);
}
cmp::min(self.len(), end-start)
}

#[inline]
unsafe fn unsafe_mut_ref(&self, index: uint) -> *mut T {
let pair_ptr: &(*mut T, uint) = transmute(self);
Expand All @@ -2157,6 +2181,23 @@ impl<'self,T> MutableVector<'self, T> for &'self mut [T] {
}
}

/// Trait for ~[T] where T is Cloneable
pub trait MutableCloneableVector<T> {
/// 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.
fn copy_from(self, &[T]) -> uint;
}

impl<'self, T:Clone> MutableCloneableVector<T> for &'self mut [T] {
#[inline]
fn copy_from(self, src: &[T]) -> uint {
for self.mut_iter().zip(src.iter()).advance |(a, b)| {
*a = b.clone();
}
cmp::min(self.len(), src.len())
}
}

/**
* Constructs a vector from an unsafe pointer to a buffer
*
Expand Down Expand Up @@ -2345,6 +2386,22 @@ pub mod bytes {
use uint;
use vec::raw;
use vec;
use ptr;

/// A trait for operations on mutable operations on `[u8]`
pub trait MutableByteVector {
/// Sets all bytes of the receiver to the given value.
pub fn set_memory(self, value: u8);
}

impl<'self> MutableByteVector for &'self mut [u8] {
#[inline]
fn set_memory(self, value: u8) {
do vec::as_mut_buf(self) |p, len| {
unsafe { ptr::set_memory(p, value, len) };
}
}
}

/// Bytewise string comparison
pub fn memcmp(a: &~[u8], b: &~[u8]) -> int {
Expand Down Expand Up @@ -3955,6 +4012,38 @@ mod tests {
assert_eq!(xs, [5, 5, 5, 5, 5])
}

#[test]
fn test_move_from() {
let mut a = [1,2,3,4,5];
let b = ~[6,7,8];
assert_eq!(a.move_from(b, 0, 3), 3);
assert_eq!(a, [6,7,8,4,5]);
let mut a = [7,2,8,1];
let b = ~[3,1,4,1,5,9];
assert_eq!(a.move_from(b, 0, 6), 4);
assert_eq!(a, [3,1,4,1]);
let mut a = [1,2,3,4];
let b = ~[5,6,7,8,9,0];
assert_eq!(a.move_from(b, 2, 3), 1);
assert_eq!(a, [7,2,3,4]);
let mut a = [1,2,3,4,5];
let b = ~[5,6,7,8,9,0];
assert_eq!(a.mut_slice(2,4).move_from(b,1,6), 2);
assert_eq!(a, [1,2,6,7,5]);
}

#[test]
fn test_copy_from() {
let mut a = [1,2,3,4,5];
let b = [6,7,8];
assert_eq!(a.copy_from(b), 3);
assert_eq!(a, [6,7,8,4,5]);
let mut c = [7,2,8,1];
let d = [3,1,4,1,5,9];
assert_eq!(c.copy_from(d), 4);
assert_eq!(c, [3,1,4,1]);
}

#[test]
fn test_reverse_part() {
let mut values = [1,2,3,4,5];
Expand Down Expand Up @@ -4017,4 +4106,14 @@ mod tests {
t!(@[int]);
t!(~[int]);
}

#[test]
fn test_bytes_set_memory() {
use vec::bytes::MutableByteVector;
let mut values = [1u8,2,3,4,5];
values.mut_slice(0,5).set_memory(0xAB);
assert_eq!(values, [0xAB, 0xAB, 0xAB, 0xAB, 0xAB]);
values.mut_slice(2,4).set_memory(0xFF);
assert_eq!(values, [0xAB, 0xAB, 0xFF, 0xFF, 0xAB]);
}
}