Skip to content

Commit 401f1c4

Browse files
committed
Merge two impl<T> Vec<T> blocks.
The show up separately in rustdoc. This is a separate commit to keep the previous one’s diff shorter.
1 parent be34bac commit 401f1c4

File tree

1 file changed

+124
-126
lines changed

1 file changed

+124
-126
lines changed

src/libcollections/vec.rs

+124-126
Original file line numberDiff line numberDiff line change
@@ -782,6 +782,130 @@ impl<T> Vec<T> {
782782
}
783783
}
784784

785+
/// Removes consecutive elements in the vector that resolve to the same key.
786+
///
787+
/// If the vector is sorted, this removes all duplicates.
788+
///
789+
/// # Examples
790+
///
791+
/// ```
792+
/// #![feature(dedup_by)]
793+
///
794+
/// let mut vec = vec![10, 20, 21, 30, 20];
795+
///
796+
/// vec.dedup_by_key(|i| *i / 10);
797+
///
798+
/// assert_eq!(vec, [10, 20, 30, 20]);
799+
/// ```
800+
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
801+
#[inline]
802+
pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq {
803+
self.dedup_by(|a, b| key(a) == key(b))
804+
}
805+
806+
/// Removes consecutive elements in the vector that resolve to the same key.
807+
///
808+
/// If the vector is sorted, this removes all duplicates.
809+
///
810+
/// # Examples
811+
///
812+
/// ```
813+
/// #![feature(dedup_by)]
814+
/// use std::ascii::AsciiExt;
815+
///
816+
/// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
817+
///
818+
/// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
819+
///
820+
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
821+
/// ```
822+
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
823+
pub fn dedup_by<F>(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
824+
unsafe {
825+
// Although we have a mutable reference to `self`, we cannot make
826+
// *arbitrary* changes. The `PartialEq` comparisons could panic, so we
827+
// must ensure that the vector is in a valid state at all time.
828+
//
829+
// The way that we handle this is by using swaps; we iterate
830+
// over all the elements, swapping as we go so that at the end
831+
// the elements we wish to keep are in the front, and those we
832+
// wish to reject are at the back. We can then truncate the
833+
// vector. This operation is still O(n).
834+
//
835+
// Example: We start in this state, where `r` represents "next
836+
// read" and `w` represents "next_write`.
837+
//
838+
// r
839+
// +---+---+---+---+---+---+
840+
// | 0 | 1 | 1 | 2 | 3 | 3 |
841+
// +---+---+---+---+---+---+
842+
// w
843+
//
844+
// Comparing self[r] against self[w-1], this is not a duplicate, so
845+
// we swap self[r] and self[w] (no effect as r==w) and then increment both
846+
// r and w, leaving us with:
847+
//
848+
// r
849+
// +---+---+---+---+---+---+
850+
// | 0 | 1 | 1 | 2 | 3 | 3 |
851+
// +---+---+---+---+---+---+
852+
// w
853+
//
854+
// Comparing self[r] against self[w-1], this value is a duplicate,
855+
// so we increment `r` but leave everything else unchanged:
856+
//
857+
// r
858+
// +---+---+---+---+---+---+
859+
// | 0 | 1 | 1 | 2 | 3 | 3 |
860+
// +---+---+---+---+---+---+
861+
// w
862+
//
863+
// Comparing self[r] against self[w-1], this is not a duplicate,
864+
// so swap self[r] and self[w] and advance r and w:
865+
//
866+
// r
867+
// +---+---+---+---+---+---+
868+
// | 0 | 1 | 2 | 1 | 3 | 3 |
869+
// +---+---+---+---+---+---+
870+
// w
871+
//
872+
// Not a duplicate, repeat:
873+
//
874+
// r
875+
// +---+---+---+---+---+---+
876+
// | 0 | 1 | 2 | 3 | 1 | 3 |
877+
// +---+---+---+---+---+---+
878+
// w
879+
//
880+
// Duplicate, advance r. End of vec. Truncate to w.
881+
882+
let ln = self.len();
883+
if ln <= 1 {
884+
return;
885+
}
886+
887+
// Avoid bounds checks by using raw pointers.
888+
let p = self.as_mut_ptr();
889+
let mut r: usize = 1;
890+
let mut w: usize = 1;
891+
892+
while r < ln {
893+
let p_r = p.offset(r as isize);
894+
let p_wm1 = p.offset((w - 1) as isize);
895+
if !same_bucket(&mut *p_r, &mut *p_wm1) {
896+
if r != w {
897+
let p_w = p_wm1.offset(1);
898+
mem::swap(&mut *p_r, &mut *p_w);
899+
}
900+
w += 1;
901+
}
902+
r += 1;
903+
}
904+
905+
self.truncate(w);
906+
}
907+
}
908+
785909
/// Appends an element to the back of a collection.
786910
///
787911
/// # Panics
@@ -1162,132 +1286,6 @@ impl<T: PartialEq> Vec<T> {
11621286
}
11631287
}
11641288

1165-
impl<T> Vec<T> {
1166-
/// Removes consecutive elements in the vector that resolve to the same key.
1167-
///
1168-
/// If the vector is sorted, this removes all duplicates.
1169-
///
1170-
/// # Examples
1171-
///
1172-
/// ```
1173-
/// #![feature(dedup_by)]
1174-
///
1175-
/// let mut vec = vec![10, 20, 21, 30, 20];
1176-
///
1177-
/// vec.dedup_by_key(|i| *i / 10);
1178-
///
1179-
/// assert_eq!(vec, [10, 20, 30, 20]);
1180-
/// ```
1181-
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
1182-
#[inline]
1183-
pub fn dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut T) -> K, K: PartialEq {
1184-
self.dedup_by(|a, b| key(a) == key(b))
1185-
}
1186-
1187-
/// Removes consecutive elements in the vector that resolve to the same key.
1188-
///
1189-
/// If the vector is sorted, this removes all duplicates.
1190-
///
1191-
/// # Examples
1192-
///
1193-
/// ```
1194-
/// #![feature(dedup_by)]
1195-
/// use std::ascii::AsciiExt;
1196-
///
1197-
/// let mut vec = vec!["foo", "bar", "Bar", "baz", "bar"];
1198-
///
1199-
/// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
1200-
///
1201-
/// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
1202-
/// ```
1203-
#[unstable(feature = "dedup_by", reason = "recently added", issue = "37087")]
1204-
pub fn dedup_by<F>(&mut self, mut same_bucket: F) where F: FnMut(&mut T, &mut T) -> bool {
1205-
unsafe {
1206-
// Although we have a mutable reference to `self`, we cannot make
1207-
// *arbitrary* changes. The `PartialEq` comparisons could panic, so we
1208-
// must ensure that the vector is in a valid state at all time.
1209-
//
1210-
// The way that we handle this is by using swaps; we iterate
1211-
// over all the elements, swapping as we go so that at the end
1212-
// the elements we wish to keep are in the front, and those we
1213-
// wish to reject are at the back. We can then truncate the
1214-
// vector. This operation is still O(n).
1215-
//
1216-
// Example: We start in this state, where `r` represents "next
1217-
// read" and `w` represents "next_write`.
1218-
//
1219-
// r
1220-
// +---+---+---+---+---+---+
1221-
// | 0 | 1 | 1 | 2 | 3 | 3 |
1222-
// +---+---+---+---+---+---+
1223-
// w
1224-
//
1225-
// Comparing self[r] against self[w-1], this is not a duplicate, so
1226-
// we swap self[r] and self[w] (no effect as r==w) and then increment both
1227-
// r and w, leaving us with:
1228-
//
1229-
// r
1230-
// +---+---+---+---+---+---+
1231-
// | 0 | 1 | 1 | 2 | 3 | 3 |
1232-
// +---+---+---+---+---+---+
1233-
// w
1234-
//
1235-
// Comparing self[r] against self[w-1], this value is a duplicate,
1236-
// so we increment `r` but leave everything else unchanged:
1237-
//
1238-
// r
1239-
// +---+---+---+---+---+---+
1240-
// | 0 | 1 | 1 | 2 | 3 | 3 |
1241-
// +---+---+---+---+---+---+
1242-
// w
1243-
//
1244-
// Comparing self[r] against self[w-1], this is not a duplicate,
1245-
// so swap self[r] and self[w] and advance r and w:
1246-
//
1247-
// r
1248-
// +---+---+---+---+---+---+
1249-
// | 0 | 1 | 2 | 1 | 3 | 3 |
1250-
// +---+---+---+---+---+---+
1251-
// w
1252-
//
1253-
// Not a duplicate, repeat:
1254-
//
1255-
// r
1256-
// +---+---+---+---+---+---+
1257-
// | 0 | 1 | 2 | 3 | 1 | 3 |
1258-
// +---+---+---+---+---+---+
1259-
// w
1260-
//
1261-
// Duplicate, advance r. End of vec. Truncate to w.
1262-
1263-
let ln = self.len();
1264-
if ln <= 1 {
1265-
return;
1266-
}
1267-
1268-
// Avoid bounds checks by using raw pointers.
1269-
let p = self.as_mut_ptr();
1270-
let mut r: usize = 1;
1271-
let mut w: usize = 1;
1272-
1273-
while r < ln {
1274-
let p_r = p.offset(r as isize);
1275-
let p_wm1 = p.offset((w - 1) as isize);
1276-
if !same_bucket(&mut *p_r, &mut *p_wm1) {
1277-
if r != w {
1278-
let p_w = p_wm1.offset(1);
1279-
mem::swap(&mut *p_r, &mut *p_w);
1280-
}
1281-
w += 1;
1282-
}
1283-
r += 1;
1284-
}
1285-
1286-
self.truncate(w);
1287-
}
1288-
}
1289-
}
1290-
12911289
////////////////////////////////////////////////////////////////////////////////
12921290
// Internal methods and functions
12931291
////////////////////////////////////////////////////////////////////////////////

0 commit comments

Comments
 (0)