about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/slice.rs24
-rw-r--r--src/libcollectionstest/lib.rs1
-rw-r--r--src/libcollectionstest/slice.rs24
-rw-r--r--src/libcore/slice.rs14
5 files changed, 63 insertions, 1 deletions
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index abf50a5fe3e..9c6fdc217dc 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -27,6 +27,7 @@
        test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
 
 #![cfg_attr(test, allow(deprecated))] // rand
+#![cfg_attr(not(test), feature(copy_from_slice))] // impl [T]
 #![cfg_attr(not(stage0), deny(warnings))]
 
 #![feature(alloc)]
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 6252e4888eb..21c5e712861 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -837,6 +837,30 @@ impl<T> [T] {
         core_slice::SliceExt::clone_from_slice(self, src)
     }
 
+    /// Copies all elements from `src` into `self`, using a memcpy.
+    ///
+    /// The length of `src` must be the same as `self`.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the two slices have different lengths.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// #![feature(copy_from_slice)]
+    /// let mut dst = [0, 0, 0];
+    /// let src = [1, 2, 3];
+    ///
+    /// dst.copy_from_slice(&src);
+    /// assert_eq!(src, dst);
+    /// ```
+    #[unstable(feature = "copy_from_slice", issue = "31755")]
+    pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
+        core_slice::SliceExt::copy_from_slice(self, src)
+    }
+
+
     /// Copies `self` into a new `Vec`.
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index 891ca22265e..bf76d0b847c 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -16,6 +16,7 @@
 #![feature(btree_range)]
 #![feature(collections)]
 #![feature(collections_bound)]
+#![feature(copy_from_slice)]
 #![feature(const_fn)]
 #![feature(fn_traits)]
 #![feature(enumset)]
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
index cde7fcaaf51..f3bb58ba45b 100644
--- a/src/libcollectionstest/slice.rs
+++ b/src/libcollectionstest/slice.rs
@@ -1138,6 +1138,30 @@ fn test_box_slice_clone_panics() {
     assert_eq!(drop_count.load(Ordering::SeqCst), 8);
 }
 
+#[test]
+fn test_copy_from_slice() {
+    let src = [0, 1, 2, 3, 4, 5];
+    let mut dst = [0; 6];
+    dst.copy_from_slice(&src);
+    assert_eq!(src, dst)
+}
+
+#[test]
+#[should_panic(expected = "destination and source slices have different lengths")]
+fn test_copy_from_slice_dst_longer() {
+    let src = [0, 1, 2, 3];
+    let mut dst = [0; 5];
+    dst.copy_from_slice(&src);
+}
+
+#[test]
+#[should_panic(expected = "destination and source slices have different lengths")]
+fn test_copy_from_slice_dst_shorter() {
+    let src = [0, 1, 2, 3];
+    let mut dst = [0; 3];
+    dst.copy_from_slice(&src);
+}
+
 mod bench {
     use std::{mem, ptr};
     use std::__rand::{Rng, thread_rng};
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index 40041c748e7..afda70f4fcc 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -48,7 +48,7 @@ use result::Result;
 use result::Result::{Ok, Err};
 use ptr;
 use mem;
-use marker::{Send, Sync, self};
+use marker::{Copy, Send, Sync, self};
 use raw::Repr;
 // Avoid conflicts with *both* the Slice trait (buggy) and the `slice::raw` module.
 use raw::Slice as RawSlice;
@@ -152,6 +152,8 @@ pub trait SliceExt {
 
     #[stable(feature = "clone_from_slice", since = "1.7.0")]
     fn clone_from_slice(&mut self, &[Self::Item]) where Self::Item: Clone;
+    #[unstable(feature = "copy_from_slice", issue = "31755")]
+    fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
 }
 
 // Use macros to be generic over const/mut
@@ -488,6 +490,16 @@ impl<T> SliceExt for [T] {
             self[i].clone_from(&src[i]);
         }
     }
+
+    #[inline]
+    fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
+        assert!(self.len() == src.len(),
+                "destination and source slices have different lengths");
+        unsafe {
+            ptr::copy_nonoverlapping(
+                src.as_ptr(), self.as_mut_ptr(), self.len());
+        }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]