use linked_hash_map::{self, Keys, LinkedHashMap};
use std::collections::hash_map::DefaultHasher;
use std::hash::{BuildHasher, BuildHasherDefault, Hash};
use std::iter::Extend;
type DefaultBuildHasher = BuildHasherDefault<DefaultHasher>;
pub struct LinkedHashSet<T, S = DefaultBuildHasher> {
map: LinkedHashMap<T, (), S>,
}
pub struct Iter<'a, K: 'a> {
iter: Keys<'a, K, ()>,
}
impl<K> Clone for Iter<'_, K> {
fn clone(&self) -> Self {
Iter {
iter: self.iter.clone(),
}
}
}
impl<'a, K> Iterator for Iter<'a, K>
where
K: Eq + Hash,
{
type Item = &'a K;
fn next(&mut self) -> Option<&'a K> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
pub struct Difference<'a, T: 'a, S: 'a> {
iter: Iter<'a, T>,
other: &'a LinkedHashSet<T, S>,
}
impl<T, S> Clone for Difference<'_, T, S> {
fn clone(&self) -> Self {
Difference {
iter: self.iter.clone(),
..*self
}
}
}
impl<'a, T, S> Iterator for Difference<'a, T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let elt = self.iter.next()?;
if !self.other.contains(elt) {
return Some(elt);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<T: Hash + Eq> LinkedHashSet<T, DefaultBuildHasher> {
pub fn new() -> LinkedHashSet<T, DefaultBuildHasher> {
LinkedHashSet {
map: LinkedHashMap::default(),
}
}
pub fn with_capacity(capacity: usize) -> LinkedHashSet<T, DefaultBuildHasher> {
LinkedHashSet {
map: LinkedHashMap::with_capacity_and_hasher(capacity, Default::default()),
}
}
}
impl<T, S> LinkedHashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
pub fn contains(&self, value: &T) -> bool {
self.map.contains_key(value)
}
pub fn capacity(&self) -> usize {
self.map.capacity()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn insert(&mut self, value: T) -> bool {
self.map.insert(value, ()).is_none()
}
pub fn iter(&self) -> Iter<'_, T> {
Iter {
iter: self.map.keys(),
}
}
pub fn difference<'a>(&'a self, other: &'a LinkedHashSet<T, S>) -> Difference<'a, T, S> {
Difference {
iter: self.iter(),
other,
}
}
pub fn clear(&mut self) {
self.map.clear();
}
}
impl<T: Hash + Eq> Default for LinkedHashSet<T, DefaultBuildHasher> {
fn default() -> LinkedHashSet<T, DefaultBuildHasher> {
LinkedHashSet {
map: LinkedHashMap::default(),
}
}
}
impl<T, S> Extend<T> for LinkedHashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.map.extend(iter.into_iter().map(|k| (k, ())));
}
}
impl<'a, T, S> IntoIterator for &'a LinkedHashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
type Item = &'a T;
type IntoIter = Iter<'a, T>;
fn into_iter(self) -> Iter<'a, T> {
self.iter()
}
}
impl<T, S> IntoIterator for LinkedHashSet<T, S>
where
T: Eq + Hash,
S: BuildHasher,
{
type Item = T;
type IntoIter = IntoIter<T>;
fn into_iter(self) -> IntoIter<T> {
IntoIter {
iter: self.map.into_iter(),
}
}
}
pub struct IntoIter<K> {
iter: linked_hash_map::IntoIter<K, ()>,
}
impl<K> Iterator for IntoIter<K> {
type Item = K;
fn next(&mut self) -> Option<K> {
self.iter.next().map(|(k, _)| k)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<K> ExactSizeIterator for IntoIter<K> {
fn len(&self) -> usize {
self.iter.len()
}
}