1use 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#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
23#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
24#[derive(Debug, Clone, Default, PartialEq, Eq)]
25pub struct EntityHashSet(pub(crate) HashSet<Entity, EntityHash>);
26
27impl EntityHashSet {
28 pub const fn new() -> Self {
34 Self(HashSet::with_hasher(EntityHash))
35 }
36
37 pub fn with_capacity(n: usize) -> Self {
43 Self(HashSet::with_capacity_and_hasher(n, EntityHash))
44 }
45
46 pub fn len(&self) -> usize {
48 self.0.len()
49 }
50
51 pub fn is_empty(&self) -> bool {
53 self.0.is_empty()
54 }
55
56 pub fn into_inner(self) -> HashSet<Entity, EntityHash> {
58 self.0
59 }
60
61 pub fn drain(&mut self) -> Drain<'_> {
65 Drain(self.0.drain(), PhantomData)
66 }
67
68 pub fn iter(&self) -> Iter<'_> {
73 Iter(self.0.iter(), PhantomData)
74 }
75
76 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 unsafe {
206 set.insert_unique_unchecked(e);
207 }
208 set
209 })
210 }
211}
212
213pub struct Iter<'a, S = EntityHash>(hash_set::Iter<'a, Entity>, PhantomData<S>);
219
220impl<'a> Iter<'a> {
221 pub fn into_inner(self) -> hash_set::Iter<'a, Entity> {
223 self.0
224 }
225}
226
227impl<'a> Deref for Iter<'a> {
228 type Target = hash_set::Iter<'a, Entity>;
229
230 fn deref(&self) -> &Self::Target {
231 &self.0
232 }
233}
234
235impl<'a> Iterator for Iter<'a> {
236 type Item = &'a Entity;
237
238 fn next(&mut self) -> Option<Self::Item> {
239 self.0.next()
240 }
241}
242
243impl ExactSizeIterator for Iter<'_> {}
244
245impl FusedIterator for Iter<'_> {}
246
247impl Clone for Iter<'_> {
248 fn clone(&self) -> Self {
249 Self(self.0.clone(), PhantomData)
250 }
251}
252
253impl Debug for Iter<'_> {
254 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
255 f.debug_tuple("Iter").field(&self.0).field(&self.1).finish()
256 }
257}
258
259impl Default for Iter<'_> {
260 fn default() -> Self {
261 Self(Default::default(), PhantomData)
262 }
263}
264
265unsafe impl EntitySetIterator for Iter<'_> {}
267
268pub struct IntoIter<S = EntityHash>(hash_set::IntoIter<Entity>, PhantomData<S>);
274
275impl IntoIter {
276 pub fn into_inner(self) -> hash_set::IntoIter<Entity> {
278 self.0
279 }
280}
281
282impl Deref for IntoIter {
283 type Target = hash_set::IntoIter<Entity>;
284
285 fn deref(&self) -> &Self::Target {
286 &self.0
287 }
288}
289
290impl Iterator for IntoIter {
291 type Item = Entity;
292
293 fn next(&mut self) -> Option<Self::Item> {
294 self.0.next()
295 }
296}
297
298impl ExactSizeIterator for IntoIter {}
299
300impl FusedIterator for IntoIter {}
301
302impl Debug for IntoIter {
303 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
304 f.debug_tuple("IntoIter")
305 .field(&self.0)
306 .field(&self.1)
307 .finish()
308 }
309}
310
311impl Default for IntoIter {
312 fn default() -> Self {
313 Self(Default::default(), PhantomData)
314 }
315}
316
317unsafe impl EntitySetIterator for IntoIter {}
319
320pub struct Drain<'a, S = EntityHash>(hash_set::Drain<'a, Entity>, PhantomData<S>);
326
327impl<'a> Drain<'a> {
328 pub fn into_inner(self) -> hash_set::Drain<'a, Entity> {
330 self.0
331 }
332}
333
334impl<'a> Deref for Drain<'a> {
335 type Target = hash_set::Drain<'a, Entity>;
336
337 fn deref(&self) -> &Self::Target {
338 &self.0
339 }
340}
341
342impl<'a> Iterator for Drain<'a> {
343 type Item = Entity;
344
345 fn next(&mut self) -> Option<Self::Item> {
346 self.0.next()
347 }
348}
349
350impl ExactSizeIterator for Drain<'_> {}
351
352impl FusedIterator for Drain<'_> {}
353
354impl Debug for Drain<'_> {
355 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
356 f.debug_tuple("Drain")
357 .field(&self.0)
358 .field(&self.1)
359 .finish()
360 }
361}
362
363unsafe impl EntitySetIterator for Drain<'_> {}
365
366pub struct ExtractIf<'a, F: FnMut(&Entity) -> bool, S = EntityHash>(
372 hash_set::ExtractIf<'a, Entity, F>,
373 PhantomData<S>,
374);
375
376impl<'a, F: FnMut(&Entity) -> bool> ExtractIf<'a, F> {
377 pub fn into_inner(self) -> hash_set::ExtractIf<'a, Entity, F> {
379 self.0
380 }
381}
382
383impl<'a, F: FnMut(&Entity) -> bool> Deref for ExtractIf<'a, F> {
384 type Target = hash_set::ExtractIf<'a, Entity, F>;
385
386 fn deref(&self) -> &Self::Target {
387 &self.0
388 }
389}
390
391impl<'a, F: FnMut(&Entity) -> bool> Iterator for ExtractIf<'a, F> {
392 type Item = Entity;
393
394 fn next(&mut self) -> Option<Self::Item> {
395 self.0.next()
396 }
397}
398
399impl<F: FnMut(&Entity) -> bool> FusedIterator for ExtractIf<'_, F> {}
400
401impl<F: FnMut(&Entity) -> bool> Debug for ExtractIf<'_, F> {
402 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
403 f.debug_tuple("ExtractIf").finish()
404 }
405}
406
407unsafe impl<F: FnMut(&Entity) -> bool> EntitySetIterator for ExtractIf<'_, F> {}
409
410unsafe impl EntitySetIterator for hash_set::Difference<'_, Entity, EntityHash> {}
412
413unsafe impl EntitySetIterator for hash_set::Intersection<'_, Entity, EntityHash> {}
415
416unsafe impl EntitySetIterator for hash_set::SymmetricDifference<'_, Entity, EntityHash> {}
418
419unsafe impl EntitySetIterator for hash_set::Union<'_, Entity, EntityHash> {}