use std::{ borrow::Borrow, fmt, hash::{BuildHasher, Hash, Hasher}, iter::{Chain, FromIterator}, ops::{BitAnd, BitOr, BitXor, Sub}, }; use hashbrown::hash_map::DefaultHashBuilder; use crate::linked_hash_map::{self, LinkedHashMap, TryReserveError}; pub struct LinkedHashSet { map: LinkedHashMap, } impl LinkedHashSet { #[inline] pub fn new() -> LinkedHashSet { LinkedHashSet { map: LinkedHashMap::new(), } } #[inline] pub fn with_capacity(capacity: usize) -> LinkedHashSet { LinkedHashSet { map: LinkedHashMap::with_capacity(capacity), } } } impl LinkedHashSet { #[inline] pub fn capacity(&self) -> usize { self.map.capacity() } #[inline] pub fn iter(&self) -> Iter<'_, T> { Iter { iter: self.map.keys(), } } #[inline] pub fn len(&self) -> usize { self.map.len() } #[inline] pub fn is_empty(&self) -> bool { self.map.is_empty() } #[inline] pub fn drain(&mut self) -> Drain { Drain { iter: self.map.drain(), } } #[inline] pub fn clear(&mut self) { self.map.clear() } #[inline] pub fn retain(&mut self, mut f: F) where F: FnMut(&T) -> bool, { self.map.retain(|k, _| f(k)); } } impl LinkedHashSet where T: Eq + Hash, S: BuildHasher, { #[inline] pub fn with_hasher(hasher: S) -> LinkedHashSet { LinkedHashSet { map: LinkedHashMap::with_hasher(hasher), } } #[inline] pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> LinkedHashSet { LinkedHashSet { map: LinkedHashMap::with_capacity_and_hasher(capacity, hasher), } } #[inline] pub fn hasher(&self) -> &S { self.map.hasher() } #[inline] pub fn reserve(&mut self, additional: usize) { self.map.reserve(additional) } #[inline] pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> { self.map.try_reserve(additional) } #[inline] pub fn shrink_to_fit(&mut self) { self.map.shrink_to_fit() } #[inline] pub fn difference<'a>(&'a self, other: &'a LinkedHashSet) -> Difference<'a, T, S> { Difference { iter: self.iter(), other, } } #[inline] pub fn symmetric_difference<'a>( &'a self, other: &'a LinkedHashSet, ) -> SymmetricDifference<'a, T, S> { SymmetricDifference { iter: self.difference(other).chain(other.difference(self)), } } #[inline] pub fn intersection<'a>(&'a self, other: &'a LinkedHashSet) -> Intersection<'a, T, S> { Intersection { iter: self.iter(), other, } } #[inline] pub fn union<'a>(&'a self, other: &'a LinkedHashSet) -> Union<'a, T, S> { Union { iter: self.iter().chain(other.difference(self)), } } #[inline] pub fn contains(&self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq, { self.map.contains_key(value) } #[inline] pub fn get(&self, value: &Q) -> Option<&T> where T: Borrow, Q: Hash + Eq, { self.map.raw_entry().from_key(value).map(|p| p.0) } #[inline] pub fn get_or_insert(&mut self, value: T) -> &T { self.map .raw_entry_mut() .from_key(&value) .or_insert(value, ()) .0 } #[inline] pub fn get_or_insert_with(&mut self, value: &Q, f: F) -> &T where T: Borrow, Q: Hash + Eq, F: FnOnce(&Q) -> T, { self.map .raw_entry_mut() .from_key(value) .or_insert_with(|| (f(value), ())) .0 } #[inline] pub fn is_disjoint(&self, other: &LinkedHashSet) -> bool { self.iter().all(|v| !other.contains(v)) } #[inline] pub fn is_subset(&self, other: &LinkedHashSet) -> bool { self.iter().all(|v| other.contains(v)) } #[inline] pub fn is_superset(&self, other: &LinkedHashSet) -> bool { other.is_subset(self) } /// Inserts the given value into the set. /// /// If the set did not have this value present, inserts it at the *back* of the internal linked /// list and returns true, otherwise it moves the existing value to the *back* of the internal /// linked list and returns false. #[inline] pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()).is_none() } /// Adds the given value to the set, replacing the existing value. /// /// If a previous value existed, returns the replaced value. In this case, the value's position /// in the internal linked list is *not* changed. #[inline] pub fn replace(&mut self, value: T) -> Option { match self.map.entry(value) { linked_hash_map::Entry::Occupied(occupied) => Some(occupied.replace_key()), linked_hash_map::Entry::Vacant(vacant) => { vacant.insert(()); None } } } #[inline] pub fn remove(&mut self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq, { self.map.remove(value).is_some() } #[inline] pub fn take(&mut self, value: &Q) -> Option where T: Borrow, Q: Hash + Eq, { match self.map.raw_entry_mut().from_key(value) { linked_hash_map::RawEntryMut::Occupied(occupied) => Some(occupied.remove_entry().0), linked_hash_map::RawEntryMut::Vacant(_) => None, } } #[inline] pub fn front(&self) -> Option<&T> { self.map.front().map(|(k, _)| k) } #[inline] pub fn pop_front(&mut self) -> Option { self.map.pop_front().map(|(k, _)| k) } #[inline] pub fn back(&self) -> Option<&T> { self.map.back().map(|(k, _)| k) } #[inline] pub fn pop_back(&mut self) -> Option { self.map.pop_back().map(|(k, _)| k) } #[inline] pub fn to_front(&mut self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq, { match self.map.raw_entry_mut().from_key(value) { linked_hash_map::RawEntryMut::Occupied(mut occupied) => { occupied.to_front(); true } linked_hash_map::RawEntryMut::Vacant(_) => false, } } #[inline] pub fn to_back(&mut self, value: &Q) -> bool where T: Borrow, Q: Hash + Eq, { match self.map.raw_entry_mut().from_key(value) { linked_hash_map::RawEntryMut::Occupied(mut occupied) => { occupied.to_back(); true } linked_hash_map::RawEntryMut::Vacant(_) => false, } } #[inline] pub fn retain_with_order(&mut self, mut f: F) where F: FnMut(&T) -> bool, { self.map.retain_with_order(|k, _| f(k)); } } impl Clone for LinkedHashSet { #[inline] fn clone(&self) -> Self { let map = self.map.clone(); Self { map } } } impl PartialEq for LinkedHashSet where T: Eq + Hash, S: BuildHasher, { #[inline] fn eq(&self, other: &Self) -> bool { self.len() == other.len() && self.iter().eq(other) } } impl Hash for LinkedHashSet where T: Eq + Hash, S: BuildHasher, { #[inline] fn hash(&self, state: &mut H) { for e in self { e.hash(state); } } } impl Eq for LinkedHashSet where T: Eq + Hash, S: BuildHasher, { } impl fmt::Debug for LinkedHashSet where T: fmt::Debug, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_set().entries(self.iter()).finish() } } impl FromIterator for LinkedHashSet where T: Eq + Hash, S: BuildHasher + Default, { #[inline] fn from_iter>(iter: I) -> LinkedHashSet { let mut set = LinkedHashSet::with_hasher(Default::default()); set.extend(iter); set } } impl Extend for LinkedHashSet where T: Eq + Hash, S: BuildHasher, { #[inline] fn extend>(&mut self, iter: I) { self.map.extend(iter.into_iter().map(|k| (k, ()))); } } impl<'a, T, S> Extend<&'a T> for LinkedHashSet where T: 'a + Eq + Hash + Copy, S: BuildHasher, { #[inline] fn extend>(&mut self, iter: I) { self.extend(iter.into_iter().cloned()); } } impl Default for LinkedHashSet where S: Default, { #[inline] fn default() -> LinkedHashSet { LinkedHashSet { map: LinkedHashMap::default(), } } } impl<'a, 'b, T, S> BitOr<&'b LinkedHashSet> for &'a LinkedHashSet where T: Eq + Hash + Clone, S: BuildHasher + Default, { type Output = LinkedHashSet; #[inline] fn bitor(self, rhs: &LinkedHashSet) -> LinkedHashSet { self.union(rhs).cloned().collect() } } impl<'a, 'b, T, S> BitAnd<&'b LinkedHashSet> for &'a LinkedHashSet where T: Eq + Hash + Clone, S: BuildHasher + Default, { type Output = LinkedHashSet; #[inline] fn bitand(self, rhs: &LinkedHashSet) -> LinkedHashSet { self.intersection(rhs).cloned().collect() } } impl<'a, 'b, T, S> BitXor<&'b LinkedHashSet> for &'a LinkedHashSet where T: Eq + Hash + Clone, S: BuildHasher + Default, { type Output = LinkedHashSet; #[inline] fn bitxor(self, rhs: &LinkedHashSet) -> LinkedHashSet { self.symmetric_difference(rhs).cloned().collect() } } impl<'a, 'b, T, S> Sub<&'b LinkedHashSet> for &'a LinkedHashSet where T: Eq + Hash + Clone, S: BuildHasher + Default, { type Output = LinkedHashSet; #[inline] fn sub(self, rhs: &LinkedHashSet) -> LinkedHashSet { self.difference(rhs).cloned().collect() } } pub struct Iter<'a, K> { iter: linked_hash_map::Keys<'a, K, ()>, } pub struct IntoIter { iter: linked_hash_map::IntoIter, } pub struct Drain<'a, K: 'a> { iter: linked_hash_map::Drain<'a, K, ()>, } pub struct Intersection<'a, T, S> { iter: Iter<'a, T>, other: &'a LinkedHashSet, } pub struct Difference<'a, T, S> { iter: Iter<'a, T>, other: &'a LinkedHashSet, } pub struct SymmetricDifference<'a, T, S> { iter: Chain, Difference<'a, T, S>>, } pub struct Union<'a, T, S> { iter: Chain, Difference<'a, T, S>>, } impl<'a, T, S> IntoIterator for &'a LinkedHashSet { type Item = &'a T; type IntoIter = Iter<'a, T>; #[inline] fn into_iter(self) -> Iter<'a, T> { self.iter() } } impl IntoIterator for LinkedHashSet { type Item = T; type IntoIter = IntoIter; #[inline] fn into_iter(self) -> IntoIter { IntoIter { iter: self.map.into_iter(), } } } impl<'a, K> Clone for Iter<'a, K> { #[inline] fn clone(&self) -> Iter<'a, K> { Iter { iter: self.iter.clone(), } } } impl<'a, K> Iterator for Iter<'a, K> { type Item = &'a K; #[inline] fn next(&mut self) -> Option<&'a K> { self.iter.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, K> ExactSizeIterator for Iter<'a, K> {} impl<'a, T> DoubleEndedIterator for Iter<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a T> { self.iter.next_back() } } impl<'a, K: fmt::Debug> fmt::Debug for Iter<'a, K> { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } impl Iterator for IntoIter { type Item = K; #[inline] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl ExactSizeIterator for IntoIter {} impl DoubleEndedIterator for IntoIter { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|(k, _)| k) } } impl<'a, K> Iterator for Drain<'a, K> { type Item = K; #[inline] fn next(&mut self) -> Option { self.iter.next().map(|(k, _)| k) } #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, K> DoubleEndedIterator for Drain<'a, K> { #[inline] fn next_back(&mut self) -> Option { self.iter.next_back().map(|(k, _)| k) } } impl<'a, K> ExactSizeIterator for Drain<'a, K> {} impl<'a, T, S> Clone for Intersection<'a, T, S> { #[inline] fn clone(&self) -> Intersection<'a, T, S> { Intersection { iter: self.iter.clone(), ..*self } } } impl<'a, T, S> Iterator for Intersection<'a, T, S> where T: Eq + Hash, S: BuildHasher, { type Item = &'a T; #[inline] fn next(&mut self) -> Option<&'a T> { loop { match self.iter.next() { None => return None, Some(elt) => { if self.other.contains(elt) { return Some(elt); } } } } } #[inline] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) } } impl<'a, T, S> fmt::Debug for Intersection<'a, T, S> where T: fmt::Debug + Eq + Hash, S: BuildHasher, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } impl<'a, T, S> Clone for Difference<'a, T, S> { #[inline] fn clone(&self) -> Difference<'a, T, S> { 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; #[inline] fn next(&mut self) -> Option<&'a T> { loop { match self.iter.next() { None => return None, Some(elt) => { if !self.other.contains(elt) { return Some(elt); } } } } } #[inline] fn size_hint(&self) -> (usize, Option) { let (_, upper) = self.iter.size_hint(); (0, upper) } } impl<'a, T, S> fmt::Debug for Difference<'a, T, S> where T: fmt::Debug + Eq + Hash, S: BuildHasher, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } impl<'a, T, S> Clone for SymmetricDifference<'a, T, S> { #[inline] fn clone(&self) -> SymmetricDifference<'a, T, S> { SymmetricDifference { iter: self.iter.clone(), } } } impl<'a, T, S> Iterator for SymmetricDifference<'a, T, S> where T: Eq + Hash, S: BuildHasher, { type Item = &'a T; #[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } } impl<'a, T, S> fmt::Debug for SymmetricDifference<'a, T, S> where T: fmt::Debug + Eq + Hash, S: BuildHasher, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } impl<'a, T, S> Clone for Union<'a, T, S> { #[inline] fn clone(&self) -> Union<'a, T, S> { Union { iter: self.iter.clone(), } } } impl<'a, T, S> fmt::Debug for Union<'a, T, S> where T: fmt::Debug + Eq + Hash, S: BuildHasher, { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_list().entries(self.clone()).finish() } } impl<'a, T, S> Iterator for Union<'a, T, S> where T: Eq + Hash, S: BuildHasher, { type Item = &'a T; #[inline] fn next(&mut self) -> Option<&'a T> { self.iter.next() } #[inline] fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } }