mirror of
https://github.com/openharmony/third_party_rust_rust-smallvec.git
synced 2026-07-21 01:55:25 -04:00
Auto merge of #72 - hoggetaylor:master, r=mbrubeck
Add support for dedup, dedup_by, and dedup_by_key <!-- Reviewable:start --> This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/72) <!-- Reviewable:end -->
This commit is contained in:
@@ -650,6 +650,50 @@ impl<A: Array> SmallVec<A> {
|
||||
}
|
||||
self.truncate(len - del);
|
||||
}
|
||||
|
||||
/// Removes consecutive duplicate elements.
|
||||
pub fn dedup(&mut self) where A::Item: PartialEq<A::Item> {
|
||||
self.dedup_by(|a, b| a == b);
|
||||
}
|
||||
|
||||
/// Removes consecutive duplicate elements using the given equality relation.
|
||||
pub fn dedup_by<F>(&mut self, mut same_bucket: F)
|
||||
where F: FnMut(&mut A::Item, &mut A::Item) -> bool
|
||||
{
|
||||
// See the implementation of Vec::dedup_by in the
|
||||
// standard library for an explanation of this algorithm.
|
||||
let len = self.len;
|
||||
if len <= 1 {
|
||||
return;
|
||||
}
|
||||
|
||||
let ptr = self.as_mut_ptr();
|
||||
let mut w: usize = 1;
|
||||
|
||||
unsafe {
|
||||
for r in 1..len {
|
||||
let p_r = ptr.offset(r as isize);
|
||||
let p_wm1 = ptr.offset((w - 1) as isize);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.truncate(w);
|
||||
}
|
||||
|
||||
/// Removes consecutive elements that map to the same key.
|
||||
pub fn dedup_by_key<F, K>(&mut self, mut key: F)
|
||||
where F: FnMut(&mut A::Item) -> K,
|
||||
K: PartialEq<K>
|
||||
{
|
||||
self.dedup_by(|a, b| key(a) == key(b));
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: Array> SmallVec<A> where A::Item: Copy {
|
||||
@@ -1683,6 +1727,25 @@ pub mod tests {
|
||||
assert_eq!(Rc::strong_count(&one), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dedup() {
|
||||
let mut dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 2, 3, 3]);
|
||||
dupes.dedup();
|
||||
assert_eq!(&*dupes, &[1, 2, 3]);
|
||||
|
||||
let mut empty: SmallVec<[i32; 5]> = SmallVec::new();
|
||||
empty.dedup();
|
||||
assert!(empty.is_empty());
|
||||
|
||||
let mut all_ones: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 1, 1, 1, 1]);
|
||||
all_ones.dedup();
|
||||
assert_eq!(all_ones.len(), 1);
|
||||
|
||||
let mut no_dupes: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 4, 5]);
|
||||
no_dupes.dedup();
|
||||
assert_eq!(no_dupes.len(), 5);
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[test]
|
||||
fn test_write() {
|
||||
|
||||
Reference in New Issue
Block a user