about summary refs log tree commit diff
path: root/src/libcore/slice/mod.rs
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2017-04-30 23:50:59 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2017-05-21 01:55:43 -0700
commitc05676b97f2151242a07e98bbde53e9c5d7f1e7a (patch)
tree39dddd3ba1fe72fb5d21b6049ec02b178dcf2683 /src/libcore/slice/mod.rs
parent0bd9e1f5e6e9832691d033f1cc32409f5e2a9145 (diff)
Add an in-place rotate method for slices to libcore
A helpful primitive for moving chunks of data around inside a slice.
In particular, adding elements to the end of a Vec then moving them
somewhere else, as a way to do efficient multiple-insert.  (There's
drain for efficient block-remove, but no easy way to block-insert.)

Talk with another example: <https://youtu.be/qH6sSOr-yk8?t=560>
Diffstat (limited to 'src/libcore/slice/mod.rs')
-rw-r--r--src/libcore/slice/mod.rs16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index e15eb8f2444..744dd791a7e 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -51,6 +51,7 @@ use mem;
 use marker::{Copy, Send, Sync, Sized, self};
 use iter_private::TrustedRandomAccess;
 
+mod rotate;
 mod sort;
 
 #[repr(C)]
@@ -202,6 +203,9 @@ pub trait SliceExt {
     #[stable(feature = "core", since = "1.6.0")]
     fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
 
+    #[unstable(feature = "slice_rotate", issue = "123456789")]
+    fn rotate(&mut self, mid: usize) -> usize;
+
     #[stable(feature = "clone_from_slice", since = "1.7.0")]
     fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
 
@@ -635,6 +639,18 @@ impl<T> SliceExt for [T] {
         self.binary_search_by(|p| p.borrow().cmp(x))
     }
 
+    fn rotate(&mut self, mid: usize) -> usize {
+        assert!(mid <= self.len());
+        let k = self.len() - mid;
+
+        unsafe {
+            let p = self.as_mut_ptr();
+            rotate::ptr_rotate(mid, p.offset(mid as isize), k);
+        }
+
+        k
+    }
+
     #[inline]
     fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
         assert!(self.len() == src.len(),