@@ -963,90 +963,12 @@ impl<T> Vec<T> {
963963 /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
964964 /// ```
965965 #[ stable( feature = "dedup_by" , since = "1.16.0" ) ]
966- pub fn dedup_by < F > ( & mut self , mut same_bucket : F ) where F : FnMut ( & mut T , & mut T ) -> bool {
967- unsafe {
968- // Although we have a mutable reference to `self`, we cannot make
969- // *arbitrary* changes. The `same_bucket` calls could panic, so we
970- // must ensure that the vector is in a valid state at all time.
971- //
972- // The way that we handle this is by using swaps; we iterate
973- // over all the elements, swapping as we go so that at the end
974- // the elements we wish to keep are in the front, and those we
975- // wish to reject are at the back. We can then truncate the
976- // vector. This operation is still O(n).
977- //
978- // Example: We start in this state, where `r` represents "next
979- // read" and `w` represents "next_write`.
980- //
981- // r
982- // +---+---+---+---+---+---+
983- // | 0 | 1 | 1 | 2 | 3 | 3 |
984- // +---+---+---+---+---+---+
985- // w
986- //
987- // Comparing self[r] against self[w-1], this is not a duplicate, so
988- // we swap self[r] and self[w] (no effect as r==w) and then increment both
989- // r and w, leaving us with:
990- //
991- // r
992- // +---+---+---+---+---+---+
993- // | 0 | 1 | 1 | 2 | 3 | 3 |
994- // +---+---+---+---+---+---+
995- // w
996- //
997- // Comparing self[r] against self[w-1], this value is a duplicate,
998- // so we increment `r` but leave everything else unchanged:
999- //
1000- // r
1001- // +---+---+---+---+---+---+
1002- // | 0 | 1 | 1 | 2 | 3 | 3 |
1003- // +---+---+---+---+---+---+
1004- // w
1005- //
1006- // Comparing self[r] against self[w-1], this is not a duplicate,
1007- // so swap self[r] and self[w] and advance r and w:
1008- //
1009- // r
1010- // +---+---+---+---+---+---+
1011- // | 0 | 1 | 2 | 1 | 3 | 3 |
1012- // +---+---+---+---+---+---+
1013- // w
1014- //
1015- // Not a duplicate, repeat:
1016- //
1017- // r
1018- // +---+---+---+---+---+---+
1019- // | 0 | 1 | 2 | 3 | 1 | 3 |
1020- // +---+---+---+---+---+---+
1021- // w
1022- //
1023- // Duplicate, advance r. End of vec. Truncate to w.
1024-
1025- let ln = self . len ( ) ;
1026- if ln <= 1 {
1027- return ;
1028- }
1029-
1030- // Avoid bounds checks by using raw pointers.
1031- let p = self . as_mut_ptr ( ) ;
1032- let mut r: usize = 1 ;
1033- let mut w: usize = 1 ;
1034-
1035- while r < ln {
1036- let p_r = p. add ( r) ;
1037- let p_wm1 = p. add ( w - 1 ) ;
1038- if !same_bucket ( & mut * p_r, & mut * p_wm1) {
1039- if r != w {
1040- let p_w = p_wm1. offset ( 1 ) ;
1041- mem:: swap ( & mut * p_r, & mut * p_w) ;
1042- }
1043- w += 1 ;
1044- }
1045- r += 1 ;
1046- }
1047-
1048- self . truncate ( w) ;
1049- }
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) ;
1050972 }
1051973
1052974 /// Appends an element to the back of a collection.
0 commit comments