@@ -947,10 +947,9 @@ impl<T> Vec<T> {
947
947
/// Removes all but the first of consecutive elements in the vector satisfying a given equality
948
948
/// relation.
949
949
///
950
- /// The `same_bucket` function is passed references to two elements from the vector, and
951
- /// returns `true` if the elements compare equal, or `false` if they do not. The elements are
952
- /// passed in opposite order from their order in the vector, so if `same_bucket(a, b)` returns
953
- /// `true`, `a` is removed.
950
+ /// The `same_bucket` function is passed references to two elements from the vector and
951
+ /// must determine if the elements compare equal. The elements are passed in opposite order
952
+ /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.
954
953
///
955
954
/// If the vector is sorted, this removes all duplicates.
956
955
///
@@ -964,90 +963,12 @@ impl<T> Vec<T> {
964
963
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
965
964
/// ```
966
965
#[ stable( feature = "dedup_by" , since = "1.16.0" ) ]
967
- pub fn dedup_by < F > ( & mut self , mut same_bucket : F ) where F : FnMut ( & mut T , & mut T ) -> bool {
968
- unsafe {
969
- // Although we have a mutable reference to `self`, we cannot make
970
- // *arbitrary* changes. The `same_bucket` calls could panic, so we
971
- // must ensure that the vector is in a valid state at all time.
972
- //
973
- // The way that we handle this is by using swaps; we iterate
974
- // over all the elements, swapping as we go so that at the end
975
- // the elements we wish to keep are in the front, and those we
976
- // wish to reject are at the back. We can then truncate the
977
- // vector. This operation is still O(n).
978
- //
979
- // Example: We start in this state, where `r` represents "next
980
- // read" and `w` represents "next_write`.
981
- //
982
- // r
983
- // +---+---+---+---+---+---+
984
- // | 0 | 1 | 1 | 2 | 3 | 3 |
985
- // +---+---+---+---+---+---+
986
- // w
987
- //
988
- // Comparing self[r] against self[w-1], this is not a duplicate, so
989
- // we swap self[r] and self[w] (no effect as r==w) and then increment both
990
- // r and w, leaving us with:
991
- //
992
- // r
993
- // +---+---+---+---+---+---+
994
- // | 0 | 1 | 1 | 2 | 3 | 3 |
995
- // +---+---+---+---+---+---+
996
- // w
997
- //
998
- // Comparing self[r] against self[w-1], this value is a duplicate,
999
- // so we increment `r` but leave everything else unchanged:
1000
- //
1001
- // r
1002
- // +---+---+---+---+---+---+
1003
- // | 0 | 1 | 1 | 2 | 3 | 3 |
1004
- // +---+---+---+---+---+---+
1005
- // w
1006
- //
1007
- // Comparing self[r] against self[w-1], this is not a duplicate,
1008
- // so swap self[r] and self[w] and advance r and w:
1009
- //
1010
- // r
1011
- // +---+---+---+---+---+---+
1012
- // | 0 | 1 | 2 | 1 | 3 | 3 |
1013
- // +---+---+---+---+---+---+
1014
- // w
1015
- //
1016
- // Not a duplicate, repeat:
1017
- //
1018
- // r
1019
- // +---+---+---+---+---+---+
1020
- // | 0 | 1 | 2 | 3 | 1 | 3 |
1021
- // +---+---+---+---+---+---+
1022
- // w
1023
- //
1024
- // Duplicate, advance r. End of vec. Truncate to w.
1025
-
1026
- let ln = self . len ( ) ;
1027
- if ln <= 1 {
1028
- return ;
1029
- }
1030
-
1031
- // Avoid bounds checks by using raw pointers.
1032
- let p = self . as_mut_ptr ( ) ;
1033
- let mut r: usize = 1 ;
1034
- let mut w: usize = 1 ;
1035
-
1036
- while r < ln {
1037
- let p_r = p. add ( r) ;
1038
- let p_wm1 = p. add ( w - 1 ) ;
1039
- if !same_bucket ( & mut * p_r, & mut * p_wm1) {
1040
- if r != w {
1041
- let p_w = p_wm1. offset ( 1 ) ;
1042
- mem:: swap ( & mut * p_r, & mut * p_w) ;
1043
- }
1044
- w += 1 ;
1045
- }
1046
- r += 1 ;
1047
- }
1048
-
1049
- self . truncate ( w) ;
1050
- }
966
+ pub fn dedup_by < F > ( & mut self , same_bucket : F ) where F : FnMut ( & mut T , & mut T ) -> bool {
967
+ let len = {
968
+ let ( dedup, _) = self . as_mut_slice ( ) . partition_dedup_by ( same_bucket) ;
969
+ dedup. len ( )
970
+ } ;
971
+ self . truncate ( len) ;
1051
972
}
1052
973
1053
974
/// Appends an element to the back of a collection.
@@ -1533,7 +1454,8 @@ impl<'a> Drop for SetLenOnDrop<'a> {
1533
1454
}
1534
1455
1535
1456
impl < T : PartialEq > Vec < T > {
1536
- /// Removes consecutive repeated elements in the vector.
1457
+ /// Removes consecutive repeated elements in the vector according to the
1458
+ /// [`PartialEq`] trait implementation.
1537
1459
///
1538
1460
/// If the vector is sorted, this removes all duplicates.
1539
1461
///
0 commit comments