about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-09-25 22:52:16 +0000
committerbors <bors@rust-lang.org>2018-09-25 22:52:16 +0000
commit92aff72a0503baa6cf0448555f649957de802b03 (patch)
tree7d88f60555c884da79b470c76d1afa299b195f74 /src/liballoc
parent4141a4079e3e6b2c4ac104fed042a9b7241467eb (diff)
parentcc9dea43be5ab201421b41dbb027f6ba36973cac (diff)
downloadrust-92aff72a0503baa6cf0448555f649957de802b03.tar.gz
rust-92aff72a0503baa6cf0448555f649957de802b03.zip
Auto merge of #54575 - pietroalbini:rollup, r=pietroalbini
Rollup of 12 pull requests

Successful merges:

 - #53518 (Add doc for impl From in char_convert)
 - #54058 (Introduce the partition_dedup/by/by_key methods for slices)
 - #54281 (Search box)
 - #54368 (Reduce code block sides padding)
 - #54498 (The project moved under the Mozilla umbrella)
 - #54518 (resolve: Do not block derive helper resolutions on single import resolutions)
 - #54522 (Fixed three small typos.)
 - #54529 (aarch64-pc-windows-msvc: Don't link libpanic_unwind to libtest.)
 - #54537 (Rename slice::exact_chunks() to slice::chunks_exact())
 - #54539 (Fix js error)
 - #54557 (incr.comp.: Don't automatically enable -Zshare-generics for incr. comp. builds.)
 - #54558 (Improvements to finding LLVM's FileCheck)

Failed merges:

r? @ghost
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/lib.rs3
-rw-r--r--src/liballoc/slice.rs4
-rw-r--r--src/liballoc/tests/lib.rs2
-rw-r--r--src/liballoc/tests/slice.rs30
-rw-r--r--src/liballoc/vec.rs100
5 files changed, 31 insertions, 108 deletions
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 089480c06d2..7960936dad6 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -116,9 +116,10 @@
 #![feature(unsize)]
 #![feature(allocator_internals)]
 #![feature(on_unimplemented)]
-#![feature(exact_chunks)]
+#![feature(chunks_exact)]
 #![feature(rustc_const_unstable)]
 #![feature(const_vec_new)]
+#![feature(slice_partition_dedup)]
 #![feature(maybe_uninit)]
 
 // Allow testing this library
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 6c0b1c33a1f..33d28bef2d7 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -123,8 +123,8 @@ pub use core::slice::{from_raw_parts, from_raw_parts_mut};
 pub use core::slice::{from_ref, from_mut};
 #[stable(feature = "slice_get_slice", since = "1.28.0")]
 pub use core::slice::SliceIndex;
-#[unstable(feature = "exact_chunks", issue = "47115")]
-pub use core::slice::{ExactChunks, ExactChunksMut};
+#[unstable(feature = "chunks_exact", issue = "47115")]
+pub use core::slice::{ChunksExact, ChunksExactMut};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Basic slice extension methods
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index 710c659ac53..6ff39227555 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -20,7 +20,7 @@
 #![feature(str_escape)]
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
-#![feature(exact_chunks)]
+#![feature(chunks_exact)]
 #![feature(repeat_generic_slice)]
 
 extern crate alloc_system;
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index f33bf64d40b..c214c59618d 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -975,27 +975,27 @@ fn test_chunksator_0() {
 }
 
 #[test]
-fn test_exact_chunksator() {
+fn test_chunks_exactator() {
     let v = &[1, 2, 3, 4, 5];
 
-    assert_eq!(v.exact_chunks(2).len(), 2);
+    assert_eq!(v.chunks_exact(2).len(), 2);
 
     let chunks: &[&[_]] = &[&[1, 2], &[3, 4]];
-    assert_eq!(v.exact_chunks(2).collect::<Vec<_>>(), chunks);
+    assert_eq!(v.chunks_exact(2).collect::<Vec<_>>(), chunks);
     let chunks: &[&[_]] = &[&[1, 2, 3]];
-    assert_eq!(v.exact_chunks(3).collect::<Vec<_>>(), chunks);
+    assert_eq!(v.chunks_exact(3).collect::<Vec<_>>(), chunks);
     let chunks: &[&[_]] = &[];
-    assert_eq!(v.exact_chunks(6).collect::<Vec<_>>(), chunks);
+    assert_eq!(v.chunks_exact(6).collect::<Vec<_>>(), chunks);
 
     let chunks: &[&[_]] = &[&[3, 4], &[1, 2]];
-    assert_eq!(v.exact_chunks(2).rev().collect::<Vec<_>>(), chunks);
+    assert_eq!(v.chunks_exact(2).rev().collect::<Vec<_>>(), chunks);
 }
 
 #[test]
 #[should_panic]
-fn test_exact_chunksator_0() {
+fn test_chunks_exactator_0() {
     let v = &[1, 2, 3, 4];
-    let _it = v.exact_chunks(0);
+    let _it = v.chunks_exact(0);
 }
 
 #[test]
@@ -1235,10 +1235,10 @@ fn test_mut_chunks_0() {
 }
 
 #[test]
-fn test_mut_exact_chunks() {
+fn test_mut_chunks_exact() {
     let mut v = [0, 1, 2, 3, 4, 5, 6];
-    assert_eq!(v.exact_chunks_mut(2).len(), 3);
-    for (i, chunk) in v.exact_chunks_mut(3).enumerate() {
+    assert_eq!(v.chunks_exact_mut(2).len(), 3);
+    for (i, chunk) in v.chunks_exact_mut(3).enumerate() {
         for x in chunk {
             *x = i as u8;
         }
@@ -1248,9 +1248,9 @@ fn test_mut_exact_chunks() {
 }
 
 #[test]
-fn test_mut_exact_chunks_rev() {
+fn test_mut_chunks_exact_rev() {
     let mut v = [0, 1, 2, 3, 4, 5, 6];
-    for (i, chunk) in v.exact_chunks_mut(3).rev().enumerate() {
+    for (i, chunk) in v.chunks_exact_mut(3).rev().enumerate() {
         for x in chunk {
             *x = i as u8;
         }
@@ -1261,9 +1261,9 @@ fn test_mut_exact_chunks_rev() {
 
 #[test]
 #[should_panic]
-fn test_mut_exact_chunks_0() {
+fn test_mut_chunks_exact_0() {
     let mut v = [1, 2, 3, 4];
-    let _it = v.exact_chunks_mut(0);
+    let _it = v.chunks_exact_mut(0);
 }
 
 #[test]
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index 7fc4453fec5..e845438c0a8 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -947,10 +947,9 @@ impl<T> Vec<T> {
     /// Removes all but the first of consecutive elements in the vector satisfying a given equality
     /// relation.
     ///
-    /// The `same_bucket` function is passed references to two elements from the vector, and
-    /// returns `true` if the elements compare equal, or `false` if they do not. The elements are
-    /// passed in opposite order from their order in the vector, so if `same_bucket(a, b)` returns
-    /// `true`, `a` is removed.
+    /// The `same_bucket` function is passed references to two elements from the vector and
+    /// must determine if the elements compare equal. The elements are passed in opposite order
+    /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.
     ///
     /// If the vector is sorted, this removes all duplicates.
     ///
@@ -964,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.
@@ -1533,7 +1454,8 @@ impl<'a> Drop for SetLenOnDrop<'a> {
 }
 
 impl<T: PartialEq> Vec<T> {
-    /// Removes consecutive repeated elements in the vector.
+    /// Removes consecutive repeated elements in the vector according to the
+    /// [`PartialEq`] trait implementation.
     ///
     /// If the vector is sorted, this removes all duplicates.
     ///