about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorClément Renault <renault.cle@gmail.com>2018-09-16 23:32:16 +0200
committerClément Renault <renault.cle@gmail.com>2018-09-23 09:10:18 +0200
commitd560292a87a89587e0345e13b9714c90495ea50f (patch)
tree692cc0e59911e34216a61ffde239e67523b96427 /src/liballoc
parent78bccb3540ae8082d34e45be5abb19ed720e9a32 (diff)
downloadrust-d560292a87a89587e0345e13b9714c90495ea50f.tar.gz
rust-d560292a87a89587e0345e13b9714c90495ea50f.zip
Make the `Vec::dedup` method use `slice::partition_dedup` internally
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/vec.rs90
2 files changed, 7 insertions, 84 deletions
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 089480c06d2..6ce24b65990 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -119,6 +119,7 @@
 #![feature(exact_chunks)]
 #![feature(rustc_const_unstable)]
 #![feature(const_vec_new)]
+#![feature(slice_partition_dedup)]
 #![feature(maybe_uninit)]
 
 // Allow testing this library
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 3f49d99989d..e845438c0a8 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -963,90 +963,12 @@ impl<T> Vec<T> {
     /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
     /// ```
     #[stable(feature = "dedup_by", since = "1.16.0")]
-    pub fn dedup_by<F>(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
-        unsafe {
-            // Although we have a mutable reference to `self`, we cannot make
-            // *arbitrary* changes. The `same_bucket` calls could panic, so we
-            // must ensure that the vector is in a valid state at all time.
-            //
-            // The way that we handle this is by using swaps; we iterate
-            // over all the elements, swapping as we go so that at the end
-            // the elements we wish to keep are in the front, and those we
-            // wish to reject are at the back. We can then truncate the
-            // vector. This operation is still O(n).
-            //
-            // Example: We start in this state, where `r` represents "next
-            // read" and `w` represents "next_write`.
-            //
-            //           r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //           w
-            //
-            // Comparing self[r] against self[w-1], this is not a duplicate, so
-            // we swap self[r] and self[w] (no effect as r==w) and then increment both
-            // r and w, leaving us with:
-            //
-            //               r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //               w
-            //
-            // Comparing self[r] against self[w-1], this value is a duplicate,
-            // so we increment `r` but leave everything else unchanged:
-            //
-            //                   r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 1 | 2 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //               w
-            //
-            // Comparing self[r] against self[w-1], this is not a duplicate,
-            // so swap self[r] and self[w] and advance r and w:
-            //
-            //                       r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 2 | 1 | 3 | 3 |
-            //     +---+---+---+---+---+---+
-            //                   w
-            //
-            // Not a duplicate, repeat:
-            //
-            //                           r
-            //     +---+---+---+---+---+---+
-            //     | 0 | 1 | 2 | 3 | 1 | 3 |
-            //     +---+---+---+---+---+---+
-            //                       w
-            //
-            // Duplicate, advance r. End of vec. Truncate to w.
-
-            let ln = self.len();
-            if ln <= 1 {
-                return;
-            }
-
-            // Avoid bounds checks by using raw pointers.
-            let p = self.as_mut_ptr();
-            let mut r: usize = 1;
-            let mut w: usize = 1;
-
-            while r < ln {
-                let p_r = p.add(r);
-                let p_wm1 = p.add(w - 1);
-                if !same_bucket(&mut *p_r, &mut *p_wm1) {
-                    if r != w {
-                        let p_w = p_wm1.offset(1);
-                        mem::swap(&mut *p_r, &mut *p_w);
-                    }
-                    w += 1;
-                }
-                r += 1;
-            }
-
-            self.truncate(w);
-        }
+    pub fn dedup_by<F>(&mut self, same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
+        let len = {
+            let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
+            dedup.len()
+        };
+        self.truncate(len);
     }
 
     /// Appends an element to the back of a collection.