Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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() {
Expand Down