use std::fmt;
use std::iter::{FromIterator, IntoIterator};
use std::slice::Iter;
extern crate smallvec;
use smallvec::{Array, SmallVec};
pub struct SmallSet<A: Array>
where
A::Item: PartialEq + Eq,
{
elements: SmallVec<A>,
}
impl<A: Array> SmallSet<A>
where
A::Item: PartialEq + Eq,
{
pub fn new() -> SmallSet<A> {
SmallSet {
elements: SmallVec::new(),
}
}
pub fn insert(&mut self, elem: A::Item) -> bool {
if !self.contains(&elem) {
self.elements.push(elem);
true
} else {
false
}
}
pub fn remove(&mut self, elem: &A::Item) -> bool {
if let Some(pos) = self.elements.iter().position(|e| *e == *elem) {
self.elements.remove(pos);
true
} else {
false
}
}
pub fn contains(&self, elem: &A::Item) -> bool {
self.elements.iter().any(|e| *e == *elem)
}
pub fn iter(&self) -> Iter<A::Item> {
self.elements.iter()
}
pub fn len(&self) -> usize {
self.elements.len()
}
pub fn clear(&mut self) {
self.elements.clear();
}
}
impl<A: Array> Clone for SmallSet<A>
where
A::Item: PartialEq + Eq + Clone,
{
fn clone(&self) -> SmallSet<A> {
SmallSet {
elements: self.elements.clone(),
}
}
}
impl<A: Array> fmt::Debug for SmallSet<A>
where
A::Item: PartialEq + Eq + fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.elements.fmt(f)
}
}
impl<A: Array> FromIterator<A::Item> for SmallSet<A>
where
A::Item: PartialEq + Eq,
{
fn from_iter<T>(iter: T) -> Self
where
T: IntoIterator<Item = A::Item>,
{
SmallSet {
elements: SmallVec::from_iter(iter),
}
}
}
#[cfg(test)]
mod test {
use super::*;
use std::fmt::Write;
#[test]
fn test_basic_set() {
let mut s: SmallSet<[u32; 2]> = SmallSet::new();
assert!(s.insert(1) == true);
assert!(s.insert(2) == true);
assert!(s.insert(2) == false);
assert!(s.insert(3) == true);
assert!(s.insert(2) == false);
assert!(s.insert(3) == false);
assert!(s.contains(&1));
assert!(s.contains(&2));
assert!(s.contains(&3));
assert!(!s.contains(&4));
assert!(s.len() == 3);
assert!(s.iter().map(|r| *r).collect::<Vec<u32>>() == vec![1, 2, 3]);
s.clear();
assert!(!s.contains(&1));
}
#[test]
fn test_remove() {
let mut s: SmallSet<[u32; 2]> = SmallSet::new();
assert!(s.insert(1) == true);
assert!(s.insert(2) == true);
assert!(s.len() == 2);
assert!(s.contains(&1));
assert!(s.remove(&1) == true);
assert!(s.remove(&1) == false);
assert!(s.len() == 1);
assert!(!s.contains(&1));
assert!(s.insert(1) == true);
assert!(s.iter().map(|r| *r).collect::<Vec<u32>>() == vec![2, 1]);
}
#[test]
fn test_clone() {
let mut s: SmallSet<[u32; 2]> = SmallSet::new();
s.insert(1);
s.insert(2);
let c = s.clone();
assert!(c.contains(&1));
assert!(c.contains(&2));
assert!(!c.contains(&3));
}
#[test]
fn test_debug() {
let mut s: SmallSet<[u32; 2]> = SmallSet::new();
s.insert(1);
s.insert(2);
let mut buf = String::new();
write!(buf, "{:?}", s).unwrap();
assert!(&buf == "[1, 2]");
}
#[test]
fn test_fromiter() {
let s: SmallSet<[usize; 4]> = vec![1, 2, 3, 4].into_iter().collect();
assert!(s.len() == 4);
}
}