use core::fmt;
use core::hash::Hash;
use core::iter::{Chain, FusedIterator};
use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Sub, SubAssign};
use alloc::boxed::Box;
use allocator_api2::alloc::Global;
use equivalent::Equivalent;
#[cfg(feature = "default-hasher")]
use crate::common::DefaultHashBuilder;
use crate::common::error::TryReserveError;
use crate::map::{self, TableBackend};
type SetExtractPred<'a, T> = Box<dyn FnMut(&T, &mut ()) -> bool + 'a>;
pub struct HashSet<T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
map: map::HashMap<T, (), P>,
}
#[cfg(feature = "default-hasher")]
impl<T, P> HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, (), Hasher = DefaultHashBuilder, Alloc = Global>,
{
#[must_use]
pub fn new() -> Self {
Self {
map: map::HashMap::new(),
}
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self {
map: map::HashMap::with_capacity(capacity),
}
}
#[must_use]
pub fn with_reserve_fraction(reserve_fraction: f64) -> Self {
Self {
map: map::HashMap::with_reserve_fraction(reserve_fraction),
}
}
#[must_use]
pub fn with_capacity_and_reserve_fraction(capacity: usize, reserve_fraction: f64) -> Self {
Self {
map: map::HashMap::with_capacity_and_reserve_fraction(capacity, reserve_fraction),
}
}
}
impl<T, P> HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, (), Alloc = Global>,
{
#[must_use]
pub fn with_hasher(hash_builder: P::Hasher) -> Self {
Self {
map: map::HashMap::with_hasher(hash_builder),
}
}
#[must_use]
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: P::Hasher) -> Self {
Self {
map: map::HashMap::with_capacity_and_hasher(capacity, hash_builder),
}
}
#[must_use]
pub fn with_reserve_fraction_and_hasher(
reserve_fraction: f64,
hash_builder: P::Hasher,
) -> Self {
Self {
map: map::HashMap::with_reserve_fraction_and_hasher(reserve_fraction, hash_builder),
}
}
#[must_use]
pub fn with_capacity_and_reserve_fraction_and_hasher(
capacity: usize,
reserve_fraction: f64,
hash_builder: P::Hasher,
) -> Self {
Self {
map: map::HashMap::with_capacity_and_reserve_fraction_and_hasher(
capacity,
reserve_fraction,
hash_builder,
),
}
}
}
#[cfg(feature = "default-hasher")]
impl<T, P> HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, (), Hasher = DefaultHashBuilder>,
{
#[must_use]
pub fn new_in(alloc: P::Alloc) -> Self {
Self {
map: map::HashMap::new_in(alloc),
}
}
#[must_use]
pub fn with_capacity_in(capacity: usize, alloc: P::Alloc) -> Self {
Self {
map: map::HashMap::with_capacity_in(capacity, alloc),
}
}
}
impl<T, P> HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
#[must_use]
pub fn with_capacity_and_reserve_fraction_and_hasher_in(
capacity: usize,
reserve_fraction: f64,
hash_builder: P::Hasher,
alloc: P::Alloc,
) -> Self {
Self {
map: map::HashMap::with_capacity_and_reserve_fraction_and_hasher_in(
capacity,
reserve_fraction,
hash_builder,
alloc,
),
}
}
pub fn allocator(&self) -> &P::Alloc {
self.map.allocator()
}
pub fn hasher(&self) -> &P::Hasher {
self.map.hasher()
}
pub fn len(&self) -> usize {
self.map.len()
}
pub fn is_empty(&self) -> bool {
self.map.is_empty()
}
pub fn capacity(&self) -> usize {
self.map.capacity()
}
pub fn reserve(&mut self, additional: usize) {
self.map.reserve(additional);
}
pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
where
P::Hasher: Clone,
{
self.map.try_reserve(additional)
}
pub fn shrink_to_fit(&mut self) {
self.map.shrink_to_fit();
}
pub fn shrink_to(&mut self, min_capacity: usize) {
self.map.shrink_to(min_capacity);
}
pub fn contains<Q>(&self, value: &Q) -> bool
where
Q: Hash + Equivalent<T> + ?Sized,
{
self.map.contains_key(value)
}
pub fn get<Q>(&self, value: &Q) -> Option<&T>
where
Q: Hash + Equivalent<T> + ?Sized,
{
self.map.get_key_value(value).map(|(k, ())| k)
}
pub fn get_or_insert(&mut self, value: T) -> &T {
match self.map.entry(value) {
map::Entry::Occupied(entry) => entry.into_key(),
map::Entry::Vacant(entry) => entry.insert_entry(()).into_key(),
}
}
pub fn get_or_insert_with<Q, F>(&mut self, value: &Q, f: F) -> &T
where
Q: Hash + Equivalent<T> + ?Sized,
F: FnOnce(&Q) -> T,
{
self.map.get_or_insert_key_with(value, (), f)
}
pub fn insert(&mut self, value: T) -> bool {
self.map.insert(value, ()).is_none()
}
pub fn replace(&mut self, value: T) -> Option<T> {
let replaced = self.map.remove_entry(&value).map(|(k, ())| k);
self.map.insert(value, ());
replaced
}
pub fn remove<Q>(&mut self, value: &Q) -> bool
where
Q: Hash + Equivalent<T> + ?Sized,
{
self.map.remove(value).is_some()
}
pub fn take<Q>(&mut self, value: &Q) -> Option<T>
where
Q: Hash + Equivalent<T> + ?Sized,
{
self.map.remove_entry(value).map(|(k, ())| k)
}
pub fn clear(&mut self) {
self.map.clear();
}
pub fn iter(&self) -> Iter<'_, T, P> {
Iter {
inner: self.map.keys(),
}
}
pub fn drain(&mut self) -> Drain<'_, T, P> {
Drain {
inner: self.map.drain(),
}
}
pub fn extract_if<'s, F>(&'s mut self, mut f: F) -> ExtractIf<'s, T, P>
where
T: 's,
F: FnMut(&T) -> bool + 's,
{
let pred: SetExtractPred<'s, T> = Box::new(move |value, ()| f(value));
ExtractIf {
inner: self.map.extract_if(pred),
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&T) -> bool,
{
self.map.retain(|value, ()| f(value));
}
pub fn entry(&mut self, value: T) -> Entry<'_, T, P> {
match self.map.entry(value) {
map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
}
}
pub fn difference<'a>(&'a self, other: &'a Self) -> Difference<'a, T, P> {
Difference {
iter: self.iter(),
other,
}
}
pub fn symmetric_difference<'a>(&'a self, other: &'a Self) -> SymmetricDifference<'a, T, P> {
SymmetricDifference {
iter: self.difference(other).chain(other.difference(self)),
}
}
pub fn intersection<'a>(&'a self, other: &'a Self) -> Intersection<'a, T, P> {
let (smaller, larger) = if self.len() <= other.len() {
(self, other)
} else {
(other, self)
};
Intersection {
iter: smaller.iter(),
other: larger,
}
}
pub fn union<'a>(&'a self, other: &'a Self) -> Union<'a, T, P> {
let (smaller, larger) = if self.len() <= other.len() {
(self, other)
} else {
(other, self)
};
Union {
iter: larger.iter().chain(smaller.difference(larger)),
}
}
pub fn is_disjoint(&self, other: &Self) -> bool {
self.intersection(other).next().is_none()
}
pub fn is_subset(&self, other: &Self) -> bool {
self.len() <= other.len() && self.iter().all(|value| other.contains(value))
}
pub fn is_superset(&self, other: &Self) -> bool {
other.is_subset(self)
}
}
#[cfg(feature = "default-hasher")]
impl<T, P> Default for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, (), Hasher = DefaultHashBuilder, Alloc = Global>,
{
fn default() -> Self {
Self::new()
}
}
impl<T, P> Clone for HashSet<T, P>
where
T: Clone + Eq + Hash,
P: TableBackend<T, ()>,
P::Hasher: Clone,
{
fn clone(&self) -> Self {
Self {
map: self.map.clone(),
}
}
}
impl<T, P> fmt::Debug for HashSet<T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_set().entries(self.iter()).finish()
}
}
impl<T, P> PartialEq for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
fn eq(&self, other: &Self) -> bool {
self.len() == other.len() && self.iter().all(|value| other.contains(value))
}
}
impl<T, P> Eq for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> FromIterator<T> for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, (), Alloc = Global>,
P::Hasher: Default,
{
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut set = Self::with_hasher(P::Hasher::default());
set.extend(iter);
set
}
}
#[cfg(feature = "default-hasher")]
impl<T, P, const N: usize> From<[T; N]> for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, (), Hasher = DefaultHashBuilder, Alloc = Global>,
{
fn from(arr: [T; N]) -> Self {
arr.into_iter().collect()
}
}
impl<T, P> Extend<T> for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
self.map.extend(iter.into_iter().map(|value| (value, ())));
}
}
impl<'a, T, P> Extend<&'a T> for HashSet<T, P>
where
T: 'a + Eq + Hash + Copy,
P: TableBackend<T, ()>,
{
fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
self.extend(iter.into_iter().copied());
}
}
impl<'a, T, P> IntoIterator for &'a HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = &'a T;
type IntoIter = Iter<'a, T, P>;
fn into_iter(self) -> Iter<'a, T, P> {
self.iter()
}
}
impl<T, P> IntoIterator for HashSet<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = T;
type IntoIter = IntoIter<T, P>;
fn into_iter(self) -> IntoIter<T, P> {
IntoIter {
inner: self.map.into_keys(),
}
}
}
impl<T, P> BitOr<&HashSet<T, P>> for &HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, (), Alloc = Global>,
P::Hasher: Default,
{
type Output = HashSet<T, P>;
fn bitor(self, rhs: &HashSet<T, P>) -> HashSet<T, P> {
self.union(rhs).cloned().collect()
}
}
impl<T, P> BitAnd<&HashSet<T, P>> for &HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, (), Alloc = Global>,
P::Hasher: Default,
{
type Output = HashSet<T, P>;
fn bitand(self, rhs: &HashSet<T, P>) -> HashSet<T, P> {
self.intersection(rhs).cloned().collect()
}
}
impl<T, P> BitXor<&HashSet<T, P>> for &HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, (), Alloc = Global>,
P::Hasher: Default,
{
type Output = HashSet<T, P>;
fn bitxor(self, rhs: &HashSet<T, P>) -> HashSet<T, P> {
self.symmetric_difference(rhs).cloned().collect()
}
}
impl<T, P> Sub<&HashSet<T, P>> for &HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, (), Alloc = Global>,
P::Hasher: Default,
{
type Output = HashSet<T, P>;
fn sub(self, rhs: &HashSet<T, P>) -> HashSet<T, P> {
self.difference(rhs).cloned().collect()
}
}
impl<T, P> BitOrAssign<&HashSet<T, P>> for HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, ()>,
{
fn bitor_assign(&mut self, rhs: &HashSet<T, P>) {
for value in rhs {
if !self.contains(value) {
self.insert(value.clone());
}
}
}
}
impl<T, P> BitAndAssign<&HashSet<T, P>> for HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, ()>,
{
fn bitand_assign(&mut self, rhs: &HashSet<T, P>) {
self.retain(|value| rhs.contains(value));
}
}
impl<T, P> BitXorAssign<&HashSet<T, P>> for HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, ()>,
{
fn bitxor_assign(&mut self, rhs: &HashSet<T, P>) {
for value in rhs {
if self.contains(value) {
self.remove(value);
} else {
self.insert(value.clone());
}
}
}
}
impl<T, P> SubAssign<&HashSet<T, P>> for HashSet<T, P>
where
T: Eq + Hash + Clone,
P: TableBackend<T, ()>,
{
fn sub_assign(&mut self, rhs: &HashSet<T, P>) {
if rhs.len() < self.len() {
for value in rhs {
self.remove(value);
}
} else {
self.retain(|value| !rhs.contains(value));
}
}
}
pub struct Iter<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
inner: map::Keys<'a, T, (), P>,
}
impl<T, P> Clone for Iter<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}
impl<'a, T, P> Iterator for Iter<'a, T, P>
where
T: 'a + Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<'a, T, P> ExactSizeIterator for Iter<'a, T, P>
where
T: 'a + Eq + Hash,
P: TableBackend<T, ()>,
{
fn len(&self) -> usize {
self.inner.len()
}
}
impl<'a, T, P> FusedIterator for Iter<'a, T, P>
where
T: 'a + Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for Iter<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
pub struct IntoIter<T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
inner: map::IntoKeys<T, (), P>,
}
impl<T, P> Iterator for IntoIter<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.inner.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, P> ExactSizeIterator for IntoIter<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
fn len(&self) -> usize {
self.inner.len()
}
}
impl<T, P> FusedIterator for IntoIter<T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for IntoIter<T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("IntoIter").finish_non_exhaustive()
}
}
pub struct Drain<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
inner: map::Drain<'a, T, (), P>,
}
impl<T, P> Iterator for Drain<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.inner.next().map(|(value, ())| value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<T, P> ExactSizeIterator for Drain<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
fn len(&self) -> usize {
self.inner.len()
}
}
impl<T, P> FusedIterator for Drain<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for Drain<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Drain").finish_non_exhaustive()
}
}
pub struct ExtractIf<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
inner: map::ExtractIf<'a, T, (), P, SetExtractPred<'a, T>>,
}
impl<T, P> Iterator for ExtractIf<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = T;
fn next(&mut self) -> Option<T> {
self.inner.next().map(|(value, ())| value)
}
fn size_hint(&self) -> (usize, Option<usize>) {
(0, self.inner.size_hint().1)
}
}
impl<T, P> FusedIterator for ExtractIf<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for ExtractIf<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("ExtractIf").finish_non_exhaustive()
}
}
pub struct Difference<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
iter: Iter<'a, T, P>,
other: &'a HashSet<T, P>,
}
impl<T, P> Clone for Difference<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
other: self.other,
}
}
}
impl<'a, T, P> Iterator for Difference<'a, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let value = self.iter.next()?;
if !self.other.contains(value) {
return Some(value);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<T, P> FusedIterator for Difference<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for Difference<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
pub struct Intersection<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
iter: Iter<'a, T, P>,
other: &'a HashSet<T, P>,
}
impl<T, P> Clone for Intersection<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
other: self.other,
}
}
}
impl<'a, T, P> Iterator for Intersection<'a, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
loop {
let value = self.iter.next()?;
if self.other.contains(value) {
return Some(value);
}
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (_, upper) = self.iter.size_hint();
(0, upper)
}
}
impl<T, P> FusedIterator for Intersection<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for Intersection<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
pub struct SymmetricDifference<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
iter: Chain<Difference<'a, T, P>, Difference<'a, T, P>>,
}
impl<T, P> Clone for SymmetricDifference<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
}
}
}
impl<'a, T, P> Iterator for SymmetricDifference<'a, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T, P> FusedIterator for SymmetricDifference<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for SymmetricDifference<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
pub struct Union<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
iter: Chain<Iter<'a, T, P>, Difference<'a, T, P>>,
}
impl<T, P> Clone for Union<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn clone(&self) -> Self {
Self {
iter: self.iter.clone(),
}
}
}
impl<'a, T, P> Iterator for Union<'a, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
type Item = &'a T;
fn next(&mut self) -> Option<&'a T> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<T, P> FusedIterator for Union<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
}
impl<T, P> fmt::Debug for Union<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
P::Scan: Clone,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.clone()).finish()
}
}
pub enum Entry<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
Occupied(OccupiedEntry<'a, T, P>),
Vacant(VacantEntry<'a, T, P>),
}
pub struct OccupiedEntry<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
inner: map::OccupiedEntry<'a, T, (), P>,
}
pub struct VacantEntry<'a, T, P: TableBackend<T, ()>>
where
T: Eq + Hash,
{
inner: map::VacantEntry<'a, T, (), P>,
}
impl<'a, T, P> Entry<'a, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
pub fn insert(self) -> OccupiedEntry<'a, T, P> {
match self {
Entry::Occupied(entry) => entry,
Entry::Vacant(entry) => entry.insert(),
}
}
pub fn or_insert(self) {
if let Entry::Vacant(entry) = self {
entry.insert();
}
}
pub fn get(&self) -> &T {
match self {
Entry::Occupied(entry) => entry.get(),
Entry::Vacant(entry) => entry.get(),
}
}
}
impl<T, P> OccupiedEntry<'_, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
pub fn get(&self) -> &T {
self.inner.key()
}
pub fn remove(self) -> T {
self.inner.remove_entry().0
}
}
impl<'a, T, P> VacantEntry<'a, T, P>
where
T: Eq + Hash,
P: TableBackend<T, ()>,
{
pub fn get(&self) -> &T {
self.inner.key()
}
pub fn into_value(self) -> T {
self.inner.into_key()
}
pub fn insert(self) -> OccupiedEntry<'a, T, P> {
OccupiedEntry {
inner: self.inner.insert_entry(()),
}
}
}
impl<T, P> fmt::Debug for OccupiedEntry<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry")
.field("value", self.get())
.finish()
}
}
impl<T, P> fmt::Debug for VacantEntry<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VacantEntry").field(self.get()).finish()
}
}
impl<T, P> fmt::Debug for Entry<'_, T, P>
where
T: fmt::Debug + Eq + Hash,
P: TableBackend<T, ()>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Entry::Occupied(entry) => f.debug_tuple("Entry").field(entry).finish(),
Entry::Vacant(entry) => f.debug_tuple("Entry").field(entry).finish(),
}
}
}