Skip to main content

bevy_ecs/entity/
hash_set.rs

1//! Contains the [`EntityEquivalentHashSet`] type, a [`HashSet`] pre-configured to use [`EntityHash`] hashing.
2//!
3//! This module is a lightweight wrapper around Bevy's [`HashSet`] that is more performant for [`Entity`] keys.
4
5use core::{
6    fmt::{self, Debug, Formatter},
7    hash::Hash,
8    iter::FusedIterator,
9    marker::PhantomData,
10    ops::{
11        BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Deref, DerefMut, Sub,
12        SubAssign,
13    },
14};
15
16use bevy_platform::collections::hash_set::{self, HashSet};
17#[cfg(feature = "bevy_reflect")]
18use bevy_reflect::Reflect;
19
20use super::{
21    Entity, EntityEquivalent, EntityHash, EntitySet, EntitySetIterator, FromEntitySetIterator,
22};
23
24/// A [`HashSet`] pre-configured to use [`EntityHash`] hashing.
25#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl<K: EntityEquivalent + Hash> bevy_reflect::GetTypeRegistration for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <HashSet<K, EntityHash> as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl<K: EntityEquivalent + Hash> bevy_reflect::Typed for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::GenericTypeInfoCell =
                    bevy_reflect::utility::GenericTypeInfoCell::new();
                CELL.get_or_insert::<Self,
                    _>(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::TupleStruct(bevy_reflect::tuple_struct::TupleStructInfo::new::<Self>(&[bevy_reflect::UnnamedField::new::<HashSet<K,
                                                            EntityHash>>(0usize)]).with_generics(bevy_reflect::Generics::from_iter([bevy_reflect::GenericInfo::Type(bevy_reflect::TypeParamInfo::new::<K>(bevy_reflect::__macro_exports::alloc_utils::Cow::Borrowed("K")))])))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl<K: EntityEquivalent + Hash> bevy_reflect::TypePath for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath {
            fn type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(#[inline(never)] ||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("bevy_ecs::entity::hash_set::EntityEquivalentHashSet<"),
                                    <K as bevy_reflect::TypePath>::type_path()), ">")
                        })
            }
            fn short_type_path() -> &'static str {
                static CELL: bevy_reflect::utility::GenericTypePathCell =
                    bevy_reflect::utility::GenericTypePathCell::new();
                CELL.get_or_insert::<Self,
                    _>(#[inline(never)] ||
                        {
                            ::core::ops::Add::<&str>::add(::core::ops::Add::<&str>::add(bevy_reflect::__macro_exports::alloc_utils::ToString::to_string("EntityEquivalentHashSet<"),
                                    <K as bevy_reflect::TypePath>::short_type_path()), ">")
                        })
            }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("EntityEquivalentHashSet")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::entity::hash_set".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::entity::hash_set")
            }
        }
        impl<K: EntityEquivalent + Hash> bevy_reflect::Reflect for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl<K: EntityEquivalent + Hash>
            bevy_reflect::func::args::GetOwnership for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl<K: EntityEquivalent + Hash> bevy_reflect::func::args::FromArg for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            type This<'from_arg> = EntityEquivalentHashSet<K>;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl<K: EntityEquivalent + Hash> bevy_reflect::func::IntoReturn for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl<K: EntityEquivalent + Hash>
            bevy_reflect::tuple_struct::TupleStruct for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn field(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.0),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.0),
                    _ => ::core::option::Option::None,
                }
            }
            #[inline]
            fn field_len(&self) -> usize { 1usize }
            #[inline]
            fn iter_fields(&self)
                -> bevy_reflect::tuple_struct::TupleStructFieldIter {
                bevy_reflect::tuple_struct::TupleStructFieldIter::new(self)
            }
            fn to_dynamic_tuple_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::tuple_struct::DynamicTupleStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic:
                        bevy_reflect::tuple_struct::DynamicTupleStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed(bevy_reflect::PartialReflect::to_dynamic(&self.0)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl<K: EntityEquivalent + Hash> bevy_reflect::PartialReflect for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::TupleStruct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (i, value) in
                        ::core::iter::Iterator::enumerate(bevy_reflect::tuple_struct::TupleStruct::iter_fields(struct_value))
                        {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::tuple_struct::TupleStruct::field_mut(self, i)
                            {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::TupleStruct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::TupleStruct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::TupleStruct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::TupleStruct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::TupleStruct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::tuple_struct::tuple_struct_partial_eq)(self,
                    value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::tuple_struct::tuple_struct_partial_cmp)(self,
                    value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            0: <HashSet<K, EntityHash> as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.0)?,
                        }))
            }
        }
        impl<K: EntityEquivalent + Hash> bevy_reflect::FromReflect for
            EntityEquivalentHashSet<K> where
            EntityEquivalentHashSet<K>: ::core::any::Any +
            ::core::marker::Send + ::core::marker::Sync,
            K: bevy_reflect::TypePath,
            HashSet<K, EntityHash>: bevy_reflect::FromReflect +
            bevy_reflect::TypePath + bevy_reflect::MaybeTyped +
            bevy_reflect::__macro_exports::RegisterForReflection {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::TupleStruct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            0: <HashSet<K, EntityHash> as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::tuple_struct::TupleStruct::field(__ref_struct,
                                            0)?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
26#[cfg_attr(feature = "serialize", derive(#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de, K: EntityEquivalent + Hash> _serde::Deserialize<'de> for
            EntityEquivalentHashSet<K> where K: _serde::Deserialize<'de> {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private229::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[doc(hidden)]
                struct __Visitor<'de, K: EntityEquivalent + Hash> where
                    K: _serde::Deserialize<'de> {
                    marker: _serde::__private229::PhantomData<EntityEquivalentHashSet<K>>,
                    lifetime: _serde::__private229::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de, K: EntityEquivalent + Hash> _serde::de::Visitor<'de>
                    for __Visitor<'de, K> where K: _serde::Deserialize<'de> {
                    type Value = EntityEquivalentHashSet<K>;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private229::Formatter)
                        -> _serde::__private229::fmt::Result {
                        _serde::__private229::Formatter::write_str(__formatter,
                            "tuple struct EntityEquivalentHashSet")
                    }
                    #[inline]
                    fn visit_newtype_struct<__E>(self, __e: __E)
                        -> _serde::__private229::Result<Self::Value, __E::Error>
                        where __E: _serde::Deserializer<'de> {
                        let __field0: HashSet<K, EntityHash> =
                            <HashSet<K, EntityHash> as
                                        _serde::Deserialize>::deserialize(__e)?;
                        _serde::__private229::Ok(EntityEquivalentHashSet(__field0))
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private229::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<HashSet<K,
                                            EntityHash>>(&mut __seq)? {
                                _serde::__private229::Some(__value) => __value,
                                _serde::__private229::None =>
                                    return _serde::__private229::Err(_serde::de::Error::invalid_length(0usize,
                                                &"tuple struct EntityEquivalentHashSet with 1 element")),
                            };
                        _serde::__private229::Ok(EntityEquivalentHashSet(__field0))
                    }
                }
                _serde::Deserializer::deserialize_newtype_struct(__deserializer,
                    "EntityEquivalentHashSet",
                    __Visitor {
                        marker: _serde::__private229::PhantomData::<EntityEquivalentHashSet<K>>,
                        lifetime: _serde::__private229::PhantomData,
                    })
            }
        }
    };serde::Deserialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<K: EntityEquivalent + Hash> _serde::Serialize for
            EntityEquivalentHashSet<K> where K: _serde::Serialize {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private229::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                _serde::Serializer::serialize_newtype_struct(__serializer,
                    "EntityEquivalentHashSet", &self.0)
            }
        }
    };serde::Serialize))]
27#[derive(#[automatically_derived]
impl<K: ::core::fmt::Debug + EntityEquivalent + Hash> ::core::fmt::Debug for
    EntityEquivalentHashSet<K> {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "EntityEquivalentHashSet", &&self.0)
    }
}Debug, #[automatically_derived]
impl<K: ::core::clone::Clone + EntityEquivalent + Hash> ::core::clone::Clone
    for EntityEquivalentHashSet<K> {
    #[inline]
    fn clone(&self) -> Self { Self(::core::clone::Clone::clone(&self.0)) }
}Clone, #[automatically_derived]
impl<K: ::core::cmp::PartialEq + EntityEquivalent + Hash>
    ::core::marker::StructuralPartialEq for EntityEquivalentHashSet<K> {
}
#[automatically_derived]
impl<K: ::core::cmp::PartialEq + EntityEquivalent + Hash>
    ::core::cmp::PartialEq for EntityEquivalentHashSet<K> {
    #[inline]
    fn eq(&self, other: &Self) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl<K: ::core::cmp::Eq + EntityEquivalent + Hash> ::core::cmp::Eq for
    EntityEquivalentHashSet<K> {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {
        let _: ::core::cmp::AssertParamIsEq<HashSet<K, EntityHash>>;
    }
}Eq)]
28pub struct EntityEquivalentHashSet<K: EntityEquivalent + Hash>(HashSet<K, EntityHash>);
29
30/// An [`HashSet`] pre-configured to use [`EntityHash`] hashing with an [`Entity`].
31pub type EntityHashSet = EntityEquivalentHashSet<Entity>;
32
33impl<K: EntityEquivalent + Hash> EntityEquivalentHashSet<K> {
34    /// Creates an empty `EntityEquivalentHashSet`.
35    ///
36    /// Equivalent to [`HashSet::with_hasher(EntityHash)`].
37    ///
38    /// [`HashSet::with_hasher(EntityHash)`]: HashSet::with_hasher
39    pub const fn new() -> Self {
40        Self(HashSet::with_hasher(EntityHash))
41    }
42
43    /// Creates an empty `EntityEquivalentHashSet` with the specified capacity.
44    ///
45    /// Equivalent to [`HashSet::with_capacity_and_hasher(n, EntityHash)`].
46    ///
47    /// [`HashSet::with_capacity_and_hasher(n, EntityHash)`]: HashSet::with_capacity_and_hasher
48    pub fn with_capacity(n: usize) -> Self {
49        Self(HashSet::with_capacity_and_hasher(n, EntityHash))
50    }
51
52    /// Returns `true` if the set contains no elements.
53    pub fn is_empty(&self) -> bool {
54        self.0.is_empty()
55    }
56
57    /// Constructs an `EntityHashSet` from an [`HashSet`].
58    pub const fn from_hash_set(set: HashSet<K, EntityHash>) -> Self {
59        Self(set)
60    }
61
62    /// Returns the inner [`HashSet`].
63    pub fn into_inner(self) -> HashSet<K, EntityHash> {
64        self.0
65    }
66
67    /// Clears the set, returning all elements in an iterator.
68    ///
69    /// Equivalent to [`HashSet::drain`].
70    pub fn drain(&mut self) -> Drain<'_, K> {
71        Drain(self.0.drain(), PhantomData)
72    }
73
74    /// An iterator visiting all elements in arbitrary order.
75    /// The iterator element type is `&'a Entity`.
76    ///
77    /// Equivalent to [`HashSet::iter`].
78    pub fn iter(&self) -> Iter<'_, K> {
79        Iter(self.0.iter(), PhantomData)
80    }
81
82    /// Drains elements which are true under the given predicate,
83    /// and returns an iterator over the removed items.
84    ///
85    /// Equivalent to [`HashSet::extract_if`].
86    pub fn extract_if<F: FnMut(&K) -> bool>(&mut self, f: F) -> ExtractIf<'_, K, F> {
87        ExtractIf(self.0.extract_if(f), PhantomData)
88    }
89}
90
91impl<K: EntityEquivalent + Hash> Deref for EntityEquivalentHashSet<K> {
92    type Target = HashSet<K, EntityHash>;
93
94    fn deref(&self) -> &Self::Target {
95        &self.0
96    }
97}
98
99impl<K: EntityEquivalent + Hash> DerefMut for EntityEquivalentHashSet<K> {
100    fn deref_mut(&mut self) -> &mut Self::Target {
101        &mut self.0
102    }
103}
104
105impl<'a, K: EntityEquivalent + Hash> IntoIterator for &'a EntityEquivalentHashSet<K> {
106    type Item = &'a K;
107
108    type IntoIter = Iter<'a, K>;
109
110    fn into_iter(self) -> Self::IntoIter {
111        Iter((&self.0).into_iter(), PhantomData)
112    }
113}
114
115impl<K: EntityEquivalent + Hash> IntoIterator for EntityEquivalentHashSet<K> {
116    type Item = K;
117
118    type IntoIter = IntoIter<K>;
119
120    fn into_iter(self) -> Self::IntoIter {
121        IntoIter(self.0.into_iter(), PhantomData)
122    }
123}
124
125impl<K: EntityEquivalent + Hash> Default for EntityEquivalentHashSet<K> {
126    fn default() -> Self {
127        Self(Default::default())
128    }
129}
130
131impl<K: EntityEquivalent + Hash + Clone> BitAnd for &EntityEquivalentHashSet<K> {
132    type Output = EntityEquivalentHashSet<K>;
133
134    fn bitand(self, rhs: Self) -> Self::Output {
135        EntityEquivalentHashSet(self.0.bitand(&rhs.0))
136    }
137}
138
139impl<K: EntityEquivalent + Hash + Clone> BitAndAssign<&EntityEquivalentHashSet<K>>
140    for EntityEquivalentHashSet<K>
141{
142    fn bitand_assign(&mut self, rhs: &Self) {
143        self.0.bitand_assign(&rhs.0);
144    }
145}
146
147impl<K: EntityEquivalent + Hash + Clone> BitOr for &EntityEquivalentHashSet<K> {
148    type Output = EntityEquivalentHashSet<K>;
149
150    fn bitor(self, rhs: Self) -> Self::Output {
151        EntityEquivalentHashSet(self.0.bitor(&rhs.0))
152    }
153}
154
155impl<K: EntityEquivalent + Hash + Clone> BitOrAssign<&EntityEquivalentHashSet<K>>
156    for EntityEquivalentHashSet<K>
157{
158    fn bitor_assign(&mut self, rhs: &Self) {
159        self.0.bitor_assign(&rhs.0);
160    }
161}
162
163impl<K: EntityEquivalent + Hash + Clone> BitXor for &EntityEquivalentHashSet<K> {
164    type Output = EntityEquivalentHashSet<K>;
165
166    fn bitxor(self, rhs: Self) -> Self::Output {
167        EntityEquivalentHashSet(self.0.bitxor(&rhs.0))
168    }
169}
170
171impl<K: EntityEquivalent + Hash + Clone> BitXorAssign<&EntityEquivalentHashSet<K>>
172    for EntityEquivalentHashSet<K>
173{
174    fn bitxor_assign(&mut self, rhs: &Self) {
175        self.0.bitxor_assign(&rhs.0);
176    }
177}
178
179impl<K: EntityEquivalent + Hash + Clone> Sub for &EntityEquivalentHashSet<K> {
180    type Output = EntityEquivalentHashSet<K>;
181
182    fn sub(self, rhs: Self) -> Self::Output {
183        EntityEquivalentHashSet(self.0.sub(&rhs.0))
184    }
185}
186
187impl<K: EntityEquivalent + Hash + Clone> SubAssign<&EntityEquivalentHashSet<K>>
188    for EntityEquivalentHashSet<K>
189{
190    fn sub_assign(&mut self, rhs: &Self) {
191        self.0.sub_assign(&rhs.0);
192    }
193}
194
195impl<'a, K: EntityEquivalent + Hash + Copy> Extend<&'a K> for EntityEquivalentHashSet<K> {
196    fn extend<I: IntoIterator<Item = &'a K>>(&mut self, iter: I) {
197        self.0.extend(iter);
198    }
199}
200
201impl<K: EntityEquivalent + Hash> Extend<K> for EntityEquivalentHashSet<K> {
202    fn extend<I: IntoIterator<Item = K>>(&mut self, iter: I) {
203        self.0.extend(iter);
204    }
205}
206
207impl<K: EntityEquivalent + Hash, const N: usize> From<[K; N]> for EntityEquivalentHashSet<K> {
208    fn from(value: [K; N]) -> Self {
209        Self(HashSet::from_iter(value))
210    }
211}
212
213impl<K: EntityEquivalent + Hash> FromIterator<K> for EntityEquivalentHashSet<K> {
214    fn from_iter<I: IntoIterator<Item = K>>(iterable: I) -> Self {
215        Self(HashSet::from_iter(iterable))
216    }
217}
218
219impl<K: EntityEquivalent + Hash> FromEntitySetIterator<K> for EntityEquivalentHashSet<K> {
220    fn from_entity_set_iter<I: EntitySet<Item = K>>(set_iter: I) -> Self {
221        let iter = set_iter.into_iter();
222        let set = EntityEquivalentHashSet::with_capacity(iter.size_hint().0);
223        iter.fold(set, |mut set, e| {
224            // SAFETY: Every element in self is unique.
225            unsafe {
226                set.insert_unique_unchecked(e);
227            }
228            set
229        })
230    }
231}
232
233impl<K: EntityEquivalent + Hash> From<HashSet<K, EntityHash>> for EntityEquivalentHashSet<K> {
234    fn from(value: HashSet<K, EntityHash>) -> Self {
235        Self(value)
236    }
237}
238
239/// An iterator over the items of an [`EntityEquivalentHashSet`].
240///
241/// This struct is created by the [`iter`] method on [`EntityEquivalentHashSet`]. See its documentation for more.
242///
243/// [`iter`]: EntityEquivalentHashSet::iter
244pub struct Iter<'a, K: EntityEquivalent + Hash, S = EntityHash>(
245    hash_set::Iter<'a, K>,
246    PhantomData<S>,
247);
248
249impl<'a, K: EntityEquivalent + Hash> Iter<'a, K> {
250    /// Constructs a [`Iter<'a, K, S>`] from a [`hash_set::Iter<'a, K>`] unsafely.
251    ///
252    /// # Safety
253    ///
254    /// `iter` must either be empty, or have been obtained from a
255    /// [`hash_set::HashSet`] using the `S` hasher.
256    pub const unsafe fn from_iter_unchecked<S>(iter: hash_set::Iter<'a, K>) -> Iter<'a, K, S> {
257        Iter(iter, PhantomData)
258    }
259
260    /// Returns the inner [`Iter`](hash_set::Iter).
261    pub const fn into_inner(self) -> hash_set::Iter<'a, K> {
262        self.0
263    }
264}
265
266impl<'a, K: EntityEquivalent + Hash> Deref for Iter<'a, K> {
267    type Target = hash_set::Iter<'a, K>;
268
269    fn deref(&self) -> &Self::Target {
270        &self.0
271    }
272}
273
274impl<'a, K: EntityEquivalent + Hash> Iterator for Iter<'a, K> {
275    type Item = &'a K;
276
277    fn next(&mut self) -> Option<Self::Item> {
278        self.0.next()
279    }
280
281    fn size_hint(&self) -> (usize, Option<usize>) {
282        self.0.size_hint()
283    }
284
285    fn fold<B, F>(self, init: B, f: F) -> B
286    where
287        Self: Sized,
288        F: FnMut(B, Self::Item) -> B,
289    {
290        self.0.fold(init, f)
291    }
292}
293
294impl<K: EntityEquivalent + Hash> ExactSizeIterator for Iter<'_, K> {}
295
296impl<K: EntityEquivalent + Hash> FusedIterator for Iter<'_, K> {}
297
298impl<K: EntityEquivalent + Hash> Clone for Iter<'_, K> {
299    fn clone(&self) -> Self {
300        // SAFETY: We are cloning an already valid `Iter`.
301        unsafe { Self::from_iter_unchecked(self.0.clone()) }
302    }
303}
304
305impl<K: EntityEquivalent + Hash + Debug> Debug for Iter<'_, K> {
306    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
307        f.debug_tuple("Iter").field(&self.0).field(&self.1).finish()
308    }
309}
310
311impl<K: EntityEquivalent + Hash> Default for Iter<'_, K> {
312    fn default() -> Self {
313        // SAFETY: `Iter` is empty.
314        unsafe { Self::from_iter_unchecked(Default::default()) }
315    }
316}
317
318// SAFETY: Iter stems from a correctly behaving `HashSet<Entity, EntityHash>`.
319unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator for Iter<'_, K> {}
320
321/// Owning iterator over the items of an [`EntityEquivalentHashSet`].
322///
323/// This struct is created by the [`into_iter`] method on [`EntityEquivalentHashSet`] (provided by the [`IntoIterator`] trait). See its documentation for more.
324///
325/// [`into_iter`]: EntityEquivalentHashSet::into_iter
326pub struct IntoIter<K: EntityEquivalent + Hash, S = EntityHash>(
327    hash_set::IntoIter<K>,
328    PhantomData<S>,
329);
330
331impl<K: EntityEquivalent + Hash> IntoIter<K> {
332    /// Constructs a [`IntoIter<K, S>`] from a [`hash_set::IntoIter<K>`] unsafely.
333    ///
334    /// # Safety
335    ///
336    /// `into_iter` must either be empty, or have been obtained from a
337    /// [`hash_set::HashSet`] using the `S` hasher.
338    pub const unsafe fn from_into_iter_unchecked<S>(
339        into_iter: hash_set::IntoIter<K>,
340    ) -> IntoIter<K, S> {
341        IntoIter(into_iter, PhantomData)
342    }
343
344    /// Returns the inner [`IntoIter`](hash_set::IntoIter).
345    pub fn into_inner(self) -> hash_set::IntoIter<K> {
346        self.0
347    }
348}
349
350impl<K: EntityEquivalent + Hash> Deref for IntoIter<K> {
351    type Target = hash_set::IntoIter<K>;
352
353    fn deref(&self) -> &Self::Target {
354        &self.0
355    }
356}
357
358impl<K: EntityEquivalent + Hash> Iterator for IntoIter<K> {
359    type Item = K;
360
361    fn next(&mut self) -> Option<Self::Item> {
362        self.0.next()
363    }
364
365    fn size_hint(&self) -> (usize, Option<usize>) {
366        self.0.size_hint()
367    }
368
369    fn fold<B, F>(self, init: B, f: F) -> B
370    where
371        Self: Sized,
372        F: FnMut(B, Self::Item) -> B,
373    {
374        self.0.fold(init, f)
375    }
376}
377
378impl<K: EntityEquivalent + Hash> ExactSizeIterator for IntoIter<K> {}
379
380impl<K: EntityEquivalent + Hash> FusedIterator for IntoIter<K> {}
381
382impl<K: EntityEquivalent + Hash + Debug> Debug for IntoIter<K> {
383    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
384        f.debug_tuple("IntoIter")
385            .field(&self.0)
386            .field(&self.1)
387            .finish()
388    }
389}
390
391impl<K: EntityEquivalent + Hash> Default for IntoIter<K> {
392    fn default() -> Self {
393        // SAFETY: `IntoIter` is empty.
394        unsafe { Self::from_into_iter_unchecked(Default::default()) }
395    }
396}
397
398// SAFETY: IntoIter stems from a correctly behaving `HashSet<Entity, EntityHash>`.
399unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator for IntoIter<K> {}
400
401/// A draining iterator over the items of an [`EntityEquivalentHashSet`].
402///
403/// This struct is created by the [`drain`] method on [`EntityEquivalentHashSet`]. See its documentation for more.
404///
405/// [`drain`]: EntityEquivalentHashSet::drain
406pub struct Drain<'a, K: EntityEquivalent + Hash, S = EntityHash>(
407    hash_set::Drain<'a, K>,
408    PhantomData<S>,
409);
410
411impl<'a, K: EntityEquivalent + Hash> Drain<'a, K> {
412    /// Constructs a [`Drain<'a, K, S>`] from a [`hash_set::Drain<'a, K>`] unsafely.
413    ///
414    /// # Safety
415    ///
416    /// `drain` must either be empty, or have been obtained from a
417    /// [`hash_set::HashSet`] using the `S` hasher.
418    pub const unsafe fn from_drain_unchecked<S>(drain: hash_set::Drain<'a, K>) -> Drain<'a, K, S> {
419        Drain(drain, PhantomData)
420    }
421
422    /// Returns the inner [`Drain`](hash_set::Drain).
423    pub fn into_inner(self) -> hash_set::Drain<'a, K> {
424        self.0
425    }
426}
427
428impl<'a, K: EntityEquivalent + Hash> Deref for Drain<'a, K> {
429    type Target = hash_set::Drain<'a, K>;
430
431    fn deref(&self) -> &Self::Target {
432        &self.0
433    }
434}
435
436impl<'a, K: EntityEquivalent + Hash> Iterator for Drain<'a, K> {
437    type Item = K;
438
439    fn next(&mut self) -> Option<Self::Item> {
440        self.0.next()
441    }
442
443    fn size_hint(&self) -> (usize, Option<usize>) {
444        self.0.size_hint()
445    }
446
447    fn fold<B, F>(self, init: B, f: F) -> B
448    where
449        Self: Sized,
450        F: FnMut(B, Self::Item) -> B,
451    {
452        self.0.fold(init, f)
453    }
454}
455
456impl<K: EntityEquivalent + Hash> ExactSizeIterator for Drain<'_, K> {}
457
458impl<K: EntityEquivalent + Hash> FusedIterator for Drain<'_, K> {}
459
460impl<K: EntityEquivalent + Hash + Debug> Debug for Drain<'_, K> {
461    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
462        f.debug_tuple("Drain")
463            .field(&self.0)
464            .field(&self.1)
465            .finish()
466    }
467}
468
469// SAFETY: Drain stems from a correctly behaving `HashSet<Entity, EntityHash>`.
470unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator for Drain<'_, K> {}
471
472/// A draining iterator over entries of a [`EntityEquivalentHashSet`] which don't satisfy the predicate `f`.
473///
474/// This struct is created by the [`extract_if`] method on [`EntityEquivalentHashSet`]. See its documentation for more.
475///
476/// [`extract_if`]: EntityEquivalentHashSet::extract_if
477pub struct ExtractIf<'a, K: EntityEquivalent + Hash, F: FnMut(&K) -> bool, S = EntityHash>(
478    hash_set::ExtractIf<'a, K, F>,
479    PhantomData<S>,
480);
481
482impl<'a, K: EntityEquivalent + Hash, F: FnMut(&K) -> bool> ExtractIf<'a, K, F> {
483    /// Constructs a [`ExtractIf<'a, K, F, S>`] from a [`hash_set::ExtractIf<'a, K, F>`] unsafely.
484    ///
485    /// # Safety
486    ///
487    /// `extract_if` must either be empty, or have been obtained from a
488    /// [`hash_set::HashSet`] using the `S` hasher.
489    pub const unsafe fn from_extract_if_unchecked<S>(
490        extract_if: hash_set::ExtractIf<'a, K, F>,
491    ) -> ExtractIf<'a, K, F, S> {
492        ExtractIf(extract_if, PhantomData)
493    }
494
495    /// Returns the inner [`ExtractIf`](hash_set::ExtractIf).
496    pub fn into_inner(self) -> hash_set::ExtractIf<'a, K, F> {
497        self.0
498    }
499}
500
501impl<'a, K: EntityEquivalent + Hash, F: FnMut(&K) -> bool> Deref for ExtractIf<'a, K, F> {
502    type Target = hash_set::ExtractIf<'a, K, F>;
503
504    fn deref(&self) -> &Self::Target {
505        &self.0
506    }
507}
508
509impl<'a, K: EntityEquivalent + Hash, F: FnMut(&K) -> bool> Iterator for ExtractIf<'a, K, F> {
510    type Item = K;
511
512    fn next(&mut self) -> Option<Self::Item> {
513        self.0.next()
514    }
515
516    fn size_hint(&self) -> (usize, Option<usize>) {
517        self.0.size_hint()
518    }
519}
520
521impl<K: EntityEquivalent + Hash, F: FnMut(&K) -> bool> FusedIterator for ExtractIf<'_, K, F> {}
522
523impl<K: EntityEquivalent + Hash, F: FnMut(&K) -> bool> Debug for ExtractIf<'_, K, F> {
524    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
525        f.debug_tuple("ExtractIf").finish()
526    }
527}
528
529// SAFETY: ExtractIf stems from a correctly behaving `HashSet<Entity, EntityHash>`.
530unsafe impl<K: EntityEquivalent + Hash, F: FnMut(&K) -> bool> EntitySetIterator
531    for ExtractIf<'_, K, F>
532{
533}
534
535// SAFETY: Difference stems from two correctly behaving `HashSet<Entity, EntityHash>`s.
536unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator
537    for hash_set::Difference<'_, K, EntityHash>
538{
539}
540
541// SAFETY: Intersection stems from two correctly behaving `HashSet<Entity, EntityHash>`s.
542unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator
543    for hash_set::Intersection<'_, K, EntityHash>
544{
545}
546
547// SAFETY: SymmetricDifference stems from two correctly behaving `HashSet<Entity, EntityHash>`s.
548unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator
549    for hash_set::SymmetricDifference<'_, K, EntityHash>
550{
551}
552
553// SAFETY: Union stems from two correctly behaving `HashSet<Entity, EntityHash>`s.
554unsafe impl<K: EntityEquivalent + Hash> EntitySetIterator for hash_set::Union<'_, K, EntityHash> {}