Skip to main content

bevy_ecs/entity/
hash_set.rs

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