about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-26 23:07:41 -0700
committerbors <bors@rust-lang.org>2013-06-26 23:07:41 -0700
commitf1e09d6f1faa6e4d7d4d19123d1633fce370e145 (patch)
tree660935f34a057fbf3178197e5cec40e8de89d309 /src/libstd
parenteda5e40b79f7aaa51765f59c21a76fe033c937b1 (diff)
parentab428b648001030a0ea71c61dd89a531109c0cdd (diff)
downloadrust-f1e09d6f1faa6e4d7d4d19123d1633fce370e145.tar.gz
rust-f1e09d6f1faa6e4d7d4d19123d1633fce370e145.zip
auto merge of #7420 : mozilla/rust/rollup, r=thestinger
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/vec.rs141
1 files changed, 101 insertions, 40 deletions
diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs
index 2e18a588fae..56e6bacf93e 100644
--- a/src/libstd/vec.rs
+++ b/src/libstd/vec.rs
@@ -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 iterator::{FromIterator, Iterator, IteratorUtil};
@@ -1299,44 +1300,6 @@ pub fn reverse<T>(v: &mut [T]) {
     }
 }
 
-/**
- * Reverse part of a vector in place.
- *
- * Reverse the elements in the vector between `start` and `end - 1`.
- *
- * If either start or end do not represent valid positions in the vector, the
- * vector is returned unchanged.
- *
- * # Arguments
- *
- * * `v` - The mutable vector to be modified
- *
- * * `start` - Index of the first element of the slice
- *
- * * `end` - Index one past the final element to be reversed.
- *
- * # Example
- *
- * Assume a mutable vector `v` contains `[1,2,3,4,5]`. After the call:
- *
- * ~~~ {.rust}
- * reverse_part(v, 1, 4);
- * ~~~
- *
- * `v` now contains `[1,4,3,2,5]`.
- */
-pub fn reverse_part<T>(v: &mut [T], start: uint, end : uint) {
-    let sz = v.len();
-    if start >= sz || end > sz { return; }
-    let mut i = start;
-    let mut j = end - 1;
-    while i < j {
-        vec::swap(v, i, j);
-        i += 1;
-        j -= 1;
-    }
-}
-
 /// Returns a vector with the order of elements reversed
 pub fn reversed<T:Copy>(v: &const [T]) -> ~[T] {
     let mut rs: ~[T] = ~[];
@@ -1393,7 +1356,7 @@ pub fn each_permutation<T:Copy>(values: &[T], fun: &fn(perm : &[T]) -> bool) ->
         // swap indices[k] and indices[l]; sort indices[k+1..]
         // (they're just reversed)
         vec::swap(indices, k, l);
-        reverse_part(indices, k+1, length);
+        reverse(indices.mut_slice(k+1, length));
         // fixup permutation based on indices
         for uint::range(k, length) |i| {
             permutation[i] = copy values[indices[i]];
@@ -2059,6 +2022,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);
 }
@@ -2088,6 +2066,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);
         let (ptr, _) = *pair_ptr;
@@ -2100,6 +2086,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
 *
@@ -2288,6 +2291,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 {
@@ -3880,9 +3899,41 @@ mod tests {
     }
 
     #[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];
-        reverse_part(values,1,4);
+        reverse(values.mut_slice(1, 4));
         assert_eq!(values, [1,4,3,2,5]);
     }
 
@@ -3941,4 +3992,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]);
+    }
 }