bevy_ecs/entity/
index_set.rs

1//! Contains the [`EntityIndexSet`] type, a [`IndexSet`] pre-configured to use [`EntityHash`] hashing.
2//!
3//! This module is a lightweight wrapper around `indexmap`'ss [`IndexSet`] that is more performant for [`Entity`] keys.
4
5use core::{
6    cmp::Ordering,
7    fmt::{self, Debug, Formatter},
8    hash::BuildHasher,
9    hash::{Hash, Hasher},
10    iter::FusedIterator,
11    marker::PhantomData,
12    ops::{
13        BitAnd, BitOr, BitXor, Bound, Deref, DerefMut, Index, Range, RangeBounds, RangeFrom,
14        RangeFull, RangeInclusive, RangeTo, RangeToInclusive, Sub,
15    },
16    ptr,
17};
18
19use indexmap::set::{self, IndexSet};
20
21use super::{Entity, EntityHash, EntitySetIterator};
22
23use bevy_platform::prelude::Box;
24
25#[cfg(feature = "bevy_reflect")]
26use bevy_reflect::Reflect;
27
28/// An [`IndexSet`] pre-configured to use [`EntityHash`] hashing.
29#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
30#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
31#[derive(Debug, Clone, Default)]
32pub struct EntityIndexSet(pub(crate) IndexSet<Entity, EntityHash>);
33
34impl EntityIndexSet {
35    /// Creates an empty `EntityIndexSet`.
36    ///
37    /// Equivalent to [`IndexSet::with_hasher(EntityHash)`].
38    ///
39    /// [`IndexSet::with_hasher(EntityHash)`]: IndexSet::with_hasher
40    pub const fn new() -> Self {
41        Self(IndexSet::with_hasher(EntityHash))
42    }
43
44    /// Creates an empty `EntityIndexSet` with the specified capacity.
45    ///
46    /// Equivalent to [`IndexSet::with_capacity_and_hasher(n, EntityHash)`].
47    ///
48    /// [`IndexSet::with_capacity_and_hasher(n, EntityHash)`]: IndexSet::with_capacity_and_hasher
49    pub fn with_capacity(n: usize) -> Self {
50        Self(IndexSet::with_capacity_and_hasher(n, EntityHash))
51    }
52
53    /// Returns the inner [`IndexSet`].
54    pub fn into_inner(self) -> IndexSet<Entity, EntityHash> {
55        self.0
56    }
57
58    /// Returns a slice of all the values in the set.
59    ///
60    /// Equivalent to [`IndexSet::as_slice`].
61    pub fn as_slice(&self) -> &Slice {
62        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
63        unsafe { Slice::from_slice_unchecked(self.0.as_slice()) }
64    }
65
66    /// Clears the `IndexSet` in the given index range, returning those values
67    /// as a drain iterator.
68    ///
69    /// Equivalent to [`IndexSet::drain`].
70    pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> Drain<'_> {
71        Drain(self.0.drain(range), PhantomData)
72    }
73
74    /// Returns a slice of values in the given range of indices.
75    ///
76    /// Equivalent to [`IndexSet::get_range`].
77    pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Slice> {
78        self.0.get_range(range).map(|slice|
79            // SAFETY: The source IndexSet uses EntityHash.
80            unsafe { Slice::from_slice_unchecked(slice) })
81    }
82
83    /// Return an iterator over the values of the set, in their order.
84    ///
85    /// Equivalent to [`IndexSet::iter`].
86    pub fn iter(&self) -> Iter<'_> {
87        Iter(self.0.iter(), PhantomData)
88    }
89
90    /// Converts into a boxed slice of all the values in the set.
91    ///
92    /// Equivalent to [`IndexSet::into_boxed_slice`].
93    pub fn into_boxed_slice(self) -> Box<Slice> {
94        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
95        unsafe { Slice::from_boxed_slice_unchecked(self.0.into_boxed_slice()) }
96    }
97}
98
99impl Deref for EntityIndexSet {
100    type Target = IndexSet<Entity, EntityHash>;
101
102    fn deref(&self) -> &Self::Target {
103        &self.0
104    }
105}
106
107impl DerefMut for EntityIndexSet {
108    fn deref_mut(&mut self) -> &mut Self::Target {
109        &mut self.0
110    }
111}
112
113impl<'a> IntoIterator for &'a EntityIndexSet {
114    type Item = &'a Entity;
115
116    type IntoIter = Iter<'a>;
117
118    fn into_iter(self) -> Self::IntoIter {
119        Iter((&self.0).into_iter(), PhantomData)
120    }
121}
122
123impl IntoIterator for EntityIndexSet {
124    type Item = Entity;
125
126    type IntoIter = IntoIter;
127
128    fn into_iter(self) -> Self::IntoIter {
129        IntoIter(self.0.into_iter(), PhantomData)
130    }
131}
132
133impl BitAnd for &EntityIndexSet {
134    type Output = EntityIndexSet;
135
136    fn bitand(self, rhs: Self) -> Self::Output {
137        EntityIndexSet(self.0.bitand(&rhs.0))
138    }
139}
140
141impl BitOr for &EntityIndexSet {
142    type Output = EntityIndexSet;
143
144    fn bitor(self, rhs: Self) -> Self::Output {
145        EntityIndexSet(self.0.bitor(&rhs.0))
146    }
147}
148
149impl BitXor for &EntityIndexSet {
150    type Output = EntityIndexSet;
151
152    fn bitxor(self, rhs: Self) -> Self::Output {
153        EntityIndexSet(self.0.bitxor(&rhs.0))
154    }
155}
156
157impl Sub for &EntityIndexSet {
158    type Output = EntityIndexSet;
159
160    fn sub(self, rhs: Self) -> Self::Output {
161        EntityIndexSet(self.0.sub(&rhs.0))
162    }
163}
164
165impl<'a> Extend<&'a Entity> for EntityIndexSet {
166    fn extend<T: IntoIterator<Item = &'a Entity>>(&mut self, iter: T) {
167        self.0.extend(iter);
168    }
169}
170
171impl Extend<Entity> for EntityIndexSet {
172    fn extend<T: IntoIterator<Item = Entity>>(&mut self, iter: T) {
173        self.0.extend(iter);
174    }
175}
176
177impl<const N: usize> From<[Entity; N]> for EntityIndexSet {
178    fn from(value: [Entity; N]) -> Self {
179        Self(IndexSet::from_iter(value))
180    }
181}
182
183impl FromIterator<Entity> for EntityIndexSet {
184    fn from_iter<I: IntoIterator<Item = Entity>>(iterable: I) -> Self {
185        Self(IndexSet::from_iter(iterable))
186    }
187}
188
189impl<S2> PartialEq<IndexSet<Entity, S2>> for EntityIndexSet
190where
191    S2: BuildHasher,
192{
193    fn eq(&self, other: &IndexSet<Entity, S2>) -> bool {
194        self.0.eq(other)
195    }
196}
197
198impl PartialEq for EntityIndexSet {
199    fn eq(&self, other: &EntityIndexSet) -> bool {
200        self.0.eq(other)
201    }
202}
203
204impl Eq for EntityIndexSet {}
205
206impl Index<(Bound<usize>, Bound<usize>)> for EntityIndexSet {
207    type Output = Slice;
208    fn index(&self, key: (Bound<usize>, Bound<usize>)) -> &Self::Output {
209        // SAFETY: The source IndexSet uses EntityHash.
210        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
211    }
212}
213
214impl Index<Range<usize>> for EntityIndexSet {
215    type Output = Slice;
216    fn index(&self, key: Range<usize>) -> &Self::Output {
217        // SAFETY: The source IndexSet uses EntityHash.
218        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
219    }
220}
221
222impl Index<RangeFrom<usize>> for EntityIndexSet {
223    type Output = Slice;
224    fn index(&self, key: RangeFrom<usize>) -> &Self::Output {
225        // SAFETY: The source IndexSet uses EntityHash.
226        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
227    }
228}
229
230impl Index<RangeFull> for EntityIndexSet {
231    type Output = Slice;
232    fn index(&self, key: RangeFull) -> &Self::Output {
233        // SAFETY: The source IndexSet uses EntityHash.
234        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
235    }
236}
237
238impl Index<RangeInclusive<usize>> for EntityIndexSet {
239    type Output = Slice;
240    fn index(&self, key: RangeInclusive<usize>) -> &Self::Output {
241        // SAFETY: The source IndexSet uses EntityHash.
242        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
243    }
244}
245
246impl Index<RangeTo<usize>> for EntityIndexSet {
247    type Output = Slice;
248    fn index(&self, key: RangeTo<usize>) -> &Self::Output {
249        // SAFETY: The source IndexSet uses EntityHash.
250        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
251    }
252}
253
254impl Index<RangeToInclusive<usize>> for EntityIndexSet {
255    type Output = Slice;
256    fn index(&self, key: RangeToInclusive<usize>) -> &Self::Output {
257        // SAFETY: The source IndexSet uses EntityHash.
258        unsafe { Slice::from_slice_unchecked(self.0.index(key)) }
259    }
260}
261
262impl Index<usize> for EntityIndexSet {
263    type Output = Entity;
264    fn index(&self, key: usize) -> &Entity {
265        self.0.index(key)
266    }
267}
268
269/// A dynamically-sized slice of values in an [`EntityIndexSet`].
270///
271/// Equivalent to an [`indexmap::set::Slice<V>`] whose source [`IndexSet`]
272/// uses [`EntityHash`].
273#[repr(transparent)]
274pub struct Slice<S = EntityHash>(PhantomData<S>, set::Slice<Entity>);
275
276impl Slice {
277    /// Returns an empty slice.
278    ///
279    /// Equivalent to [`set::Slice::new`].
280    pub const fn new<'a>() -> &'a Self {
281        // SAFETY: The source slice is empty.
282        unsafe { Self::from_slice_unchecked(set::Slice::new()) }
283    }
284
285    /// Constructs a [`entity::index_set::Slice`] from a [`indexmap::set::Slice`] unsafely.
286    ///
287    /// # Safety
288    ///
289    /// `slice` must stem from an [`IndexSet`] using [`EntityHash`].
290    ///
291    /// [`entity::index_set::Slice`]: `crate::entity::index_set::Slice`
292    pub const unsafe fn from_slice_unchecked(slice: &set::Slice<Entity>) -> &Self {
293        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
294        unsafe { &*(ptr::from_ref(slice) as *const Self) }
295    }
296
297    /// Constructs a [`entity::index_set::Slice`] from a [`indexmap::set::Slice`] unsafely.
298    ///
299    /// # Safety
300    ///
301    /// `slice` must stem from an [`IndexSet`] using [`EntityHash`].
302    ///
303    /// [`entity::index_set::Slice`]: `crate::entity::index_set::Slice`
304    pub const unsafe fn from_slice_unchecked_mut(slice: &mut set::Slice<Entity>) -> &mut Self {
305        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
306        unsafe { &mut *(ptr::from_mut(slice) as *mut Self) }
307    }
308
309    /// Casts `self` to the inner slice.
310    pub const fn as_inner(&self) -> &set::Slice<Entity> {
311        &self.1
312    }
313
314    /// Constructs a boxed [`entity::index_set::Slice`] from a boxed [`indexmap::set::Slice`] unsafely.
315    ///
316    /// # Safety
317    ///
318    /// `slice` must stem from an [`IndexSet`] using [`EntityHash`].
319    ///
320    /// [`entity::index_set::Slice`]: `crate::entity::index_set::Slice`
321    pub unsafe fn from_boxed_slice_unchecked(slice: Box<set::Slice<Entity>>) -> Box<Self> {
322        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
323        unsafe { Box::from_raw(Box::into_raw(slice) as *mut Self) }
324    }
325
326    /// Casts a reference to `self` to the inner slice.
327    #[expect(
328        clippy::borrowed_box,
329        reason = "We wish to access the Box API of the inner type, without consuming it."
330    )]
331    pub fn as_boxed_inner(self: &Box<Self>) -> &Box<set::Slice<Entity>> {
332        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
333        unsafe { &*(ptr::from_ref(self).cast::<Box<set::Slice<Entity>>>()) }
334    }
335
336    /// Casts `self` to the inner slice.
337    pub fn into_boxed_inner(self: Box<Self>) -> Box<set::Slice<Entity>> {
338        // SAFETY: Slice is a transparent wrapper around indexmap::set::Slice.
339        unsafe { Box::from_raw(Box::into_raw(self) as *mut set::Slice<Entity>) }
340    }
341
342    /// Returns a slice of values in the given range of indices.
343    ///
344    /// Equivalent to [`set::Slice::get_range`].
345    pub fn get_range<R: RangeBounds<usize>>(&self, range: R) -> Option<&Self> {
346        self.1.get_range(range).map(|slice|
347            // SAFETY: This a subslice of a valid slice.
348            unsafe { Self::from_slice_unchecked(slice) })
349    }
350
351    /// Divides one slice into two at an index.
352    ///
353    /// Equivalent to [`set::Slice::split_at`].
354    pub fn split_at(&self, index: usize) -> (&Self, &Self) {
355        let (slice_1, slice_2) = self.1.split_at(index);
356        // SAFETY: These are subslices of a valid slice.
357        unsafe {
358            (
359                Self::from_slice_unchecked(slice_1),
360                Self::from_slice_unchecked(slice_2),
361            )
362        }
363    }
364
365    /// Returns the first value and the rest of the slice,
366    /// or `None` if it is empty.
367    ///
368    /// Equivalent to [`set::Slice::split_first`].
369    pub fn split_first(&self) -> Option<(&Entity, &Self)> {
370        self.1.split_first().map(|(first, rest)| {
371            (
372                first,
373                // SAFETY: This a subslice of a valid slice.
374                unsafe { Self::from_slice_unchecked(rest) },
375            )
376        })
377    }
378
379    /// Returns the last value and the rest of the slice,
380    /// or `None` if it is empty.
381    ///
382    /// Equivalent to [`set::Slice::split_last`].
383    pub fn split_last(&self) -> Option<(&Entity, &Self)> {
384        self.1.split_last().map(|(last, rest)| {
385            (
386                last,
387                // SAFETY: This a subslice of a valid slice.
388                unsafe { Self::from_slice_unchecked(rest) },
389            )
390        })
391    }
392
393    /// Return an iterator over the values of the set slice.
394    ///
395    /// Equivalent to [`set::Slice::iter`].
396    pub fn iter(&self) -> Iter<'_> {
397        Iter(self.1.iter(), PhantomData)
398    }
399}
400
401impl Deref for Slice {
402    type Target = set::Slice<Entity>;
403
404    fn deref(&self) -> &Self::Target {
405        &self.1
406    }
407}
408
409impl<'a> IntoIterator for &'a Slice {
410    type IntoIter = Iter<'a>;
411    type Item = &'a Entity;
412
413    fn into_iter(self) -> Self::IntoIter {
414        self.iter()
415    }
416}
417
418impl IntoIterator for Box<Slice> {
419    type IntoIter = IntoIter;
420    type Item = Entity;
421
422    fn into_iter(self) -> Self::IntoIter {
423        IntoIter(self.into_boxed_inner().into_iter(), PhantomData)
424    }
425}
426
427impl Clone for Box<Slice> {
428    fn clone(&self) -> Self {
429        // SAFETY: This is a clone of a valid slice.
430        unsafe { Slice::from_boxed_slice_unchecked(self.as_boxed_inner().clone()) }
431    }
432}
433
434impl Default for &Slice {
435    fn default() -> Self {
436        // SAFETY: The source slice is empty.
437        unsafe { Slice::from_slice_unchecked(<&set::Slice<Entity>>::default()) }
438    }
439}
440
441impl Default for Box<Slice> {
442    fn default() -> Self {
443        // SAFETY: The source slice is empty.
444        unsafe { Slice::from_boxed_slice_unchecked(<Box<set::Slice<Entity>>>::default()) }
445    }
446}
447
448impl<V: Debug> Debug for Slice<V> {
449    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
450        f.debug_tuple("Slice")
451            .field(&self.0)
452            .field(&&self.1)
453            .finish()
454    }
455}
456
457impl From<&Slice> for Box<Slice> {
458    fn from(value: &Slice) -> Self {
459        // SAFETY: This slice is a copy of a valid slice.
460        unsafe { Slice::from_boxed_slice_unchecked(value.1.into()) }
461    }
462}
463
464impl Hash for Slice {
465    fn hash<H: Hasher>(&self, state: &mut H) {
466        self.1.hash(state);
467    }
468}
469
470impl PartialOrd for Slice {
471    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
472        Some(self.cmp(other))
473    }
474}
475
476impl Ord for Slice {
477    fn cmp(&self, other: &Self) -> Ordering {
478        self.1.cmp(other)
479    }
480}
481
482impl PartialEq for Slice {
483    fn eq(&self, other: &Self) -> bool {
484        self.1 == other.1
485    }
486}
487
488impl Eq for Slice {}
489
490impl Index<(Bound<usize>, Bound<usize>)> for Slice {
491    type Output = Self;
492    fn index(&self, key: (Bound<usize>, Bound<usize>)) -> &Self {
493        // SAFETY: This a subslice of a valid slice.
494        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
495    }
496}
497
498impl Index<Range<usize>> for Slice {
499    type Output = Self;
500    fn index(&self, key: Range<usize>) -> &Self {
501        // SAFETY: This a subslice of a valid slice.
502        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
503    }
504}
505
506impl Index<RangeFrom<usize>> for Slice {
507    type Output = Slice;
508    fn index(&self, key: RangeFrom<usize>) -> &Self {
509        // SAFETY: This a subslice of a valid slice.
510        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
511    }
512}
513
514impl Index<RangeFull> for Slice {
515    type Output = Self;
516    fn index(&self, key: RangeFull) -> &Self {
517        // SAFETY: This a subslice of a valid slice.
518        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
519    }
520}
521
522impl Index<RangeInclusive<usize>> for Slice {
523    type Output = Self;
524    fn index(&self, key: RangeInclusive<usize>) -> &Self {
525        // SAFETY: This a subslice of a valid slice.
526        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
527    }
528}
529
530impl Index<RangeTo<usize>> for Slice {
531    type Output = Self;
532    fn index(&self, key: RangeTo<usize>) -> &Self {
533        // SAFETY: This a subslice of a valid slice.
534        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
535    }
536}
537
538impl Index<RangeToInclusive<usize>> for Slice {
539    type Output = Self;
540    fn index(&self, key: RangeToInclusive<usize>) -> &Self {
541        // SAFETY: This a subslice of a valid slice.
542        unsafe { Self::from_slice_unchecked(self.1.index(key)) }
543    }
544}
545
546impl Index<usize> for Slice {
547    type Output = Entity;
548    fn index(&self, key: usize) -> &Entity {
549        self.1.index(key)
550    }
551}
552
553/// An iterator over the items of an [`EntityIndexSet`].
554///
555/// This struct is created by the [`iter`] method on [`EntityIndexSet`]. See its documentation for more.
556///
557/// [`iter`]: EntityIndexSet::iter
558pub struct Iter<'a, S = EntityHash>(set::Iter<'a, Entity>, PhantomData<S>);
559
560impl<'a> Iter<'a> {
561    /// Returns the inner [`Iter`](set::Iter).
562    pub fn into_inner(self) -> set::Iter<'a, Entity> {
563        self.0
564    }
565
566    /// Returns a slice of the remaining entries in the iterator.
567    ///
568    /// Equivalent to [`set::Iter::as_slice`].
569    pub fn as_slice(&self) -> &Slice {
570        // SAFETY: The source IndexSet uses EntityHash.
571        unsafe { Slice::from_slice_unchecked(self.0.as_slice()) }
572    }
573}
574
575impl<'a> Deref for Iter<'a> {
576    type Target = set::Iter<'a, Entity>;
577
578    fn deref(&self) -> &Self::Target {
579        &self.0
580    }
581}
582
583impl<'a> Iterator for Iter<'a> {
584    type Item = &'a Entity;
585
586    fn next(&mut self) -> Option<Self::Item> {
587        self.0.next()
588    }
589
590    fn size_hint(&self) -> (usize, Option<usize>) {
591        self.0.size_hint()
592    }
593}
594
595impl DoubleEndedIterator for Iter<'_> {
596    fn next_back(&mut self) -> Option<Self::Item> {
597        self.0.next_back()
598    }
599}
600
601impl ExactSizeIterator for Iter<'_> {}
602
603impl FusedIterator for Iter<'_> {}
604
605impl Clone for Iter<'_> {
606    fn clone(&self) -> Self {
607        Self(self.0.clone(), PhantomData)
608    }
609}
610
611impl Debug for Iter<'_> {
612    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
613        f.debug_tuple("Iter").field(&self.0).field(&self.1).finish()
614    }
615}
616
617impl Default for Iter<'_> {
618    fn default() -> Self {
619        Self(Default::default(), PhantomData)
620    }
621}
622
623// SAFETY: Iter stems from a correctly behaving `IndexSet<Entity, EntityHash>`.
624unsafe impl EntitySetIterator for Iter<'_> {}
625
626/// Owning iterator over the items of an [`EntityIndexSet`].
627///
628/// This struct is created by the [`into_iter`] method on [`EntityIndexSet`] (provided by the [`IntoIterator`] trait). See its documentation for more.
629///
630/// [`into_iter`]: EntityIndexSet::into_iter
631pub struct IntoIter<S = EntityHash>(set::IntoIter<Entity>, PhantomData<S>);
632
633impl IntoIter {
634    /// Returns the inner [`IntoIter`](set::IntoIter).
635    pub fn into_inner(self) -> set::IntoIter<Entity> {
636        self.0
637    }
638
639    /// Returns a slice of the remaining entries in the iterator.
640    ///
641    /// Equivalent to [`set::IntoIter::as_slice`].
642    pub fn as_slice(&self) -> &Slice {
643        // SAFETY: The source IndexSet uses EntityHash.
644        unsafe { Slice::from_slice_unchecked(self.0.as_slice()) }
645    }
646}
647
648impl Deref for IntoIter {
649    type Target = set::IntoIter<Entity>;
650
651    fn deref(&self) -> &Self::Target {
652        &self.0
653    }
654}
655
656impl Iterator for IntoIter {
657    type Item = Entity;
658
659    fn next(&mut self) -> Option<Self::Item> {
660        self.0.next()
661    }
662
663    fn size_hint(&self) -> (usize, Option<usize>) {
664        self.0.size_hint()
665    }
666}
667
668impl DoubleEndedIterator for IntoIter {
669    fn next_back(&mut self) -> Option<Self::Item> {
670        self.0.next_back()
671    }
672}
673
674impl ExactSizeIterator for IntoIter {}
675
676impl FusedIterator for IntoIter {}
677
678impl Clone for IntoIter {
679    fn clone(&self) -> Self {
680        Self(self.0.clone(), PhantomData)
681    }
682}
683
684impl Debug for IntoIter {
685    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
686        f.debug_tuple("IntoIter")
687            .field(&self.0)
688            .field(&self.1)
689            .finish()
690    }
691}
692
693impl Default for IntoIter {
694    fn default() -> Self {
695        Self(Default::default(), PhantomData)
696    }
697}
698
699// SAFETY: IntoIter stems from a correctly behaving `IndexSet<Entity, EntityHash>`.
700unsafe impl EntitySetIterator for IntoIter {}
701
702/// A draining iterator over the items of an [`EntityIndexSet`].
703///
704/// This struct is created by the [`drain`] method on [`EntityIndexSet`]. See its documentation for more.
705///
706/// [`drain`]: EntityIndexSet::drain
707pub struct Drain<'a, S = EntityHash>(set::Drain<'a, Entity>, PhantomData<S>);
708
709impl<'a> Drain<'a> {
710    /// Returns the inner [`Drain`](set::Drain).
711    pub fn into_inner(self) -> set::Drain<'a, Entity> {
712        self.0
713    }
714
715    /// Returns a slice of the remaining entries in the iterator.$
716    ///
717    /// Equivalent to [`set::Drain::as_slice`].
718    pub fn as_slice(&self) -> &Slice {
719        // SAFETY: The source IndexSet uses EntityHash.
720        unsafe { Slice::from_slice_unchecked(self.0.as_slice()) }
721    }
722}
723
724impl<'a> Deref for Drain<'a> {
725    type Target = set::Drain<'a, Entity>;
726
727    fn deref(&self) -> &Self::Target {
728        &self.0
729    }
730}
731
732impl<'a> Iterator for Drain<'a> {
733    type Item = Entity;
734
735    fn next(&mut self) -> Option<Self::Item> {
736        self.0.next()
737    }
738
739    fn size_hint(&self) -> (usize, Option<usize>) {
740        self.0.size_hint()
741    }
742}
743
744impl DoubleEndedIterator for Drain<'_> {
745    fn next_back(&mut self) -> Option<Self::Item> {
746        self.0.next_back()
747    }
748}
749
750impl ExactSizeIterator for Drain<'_> {}
751
752impl FusedIterator for Drain<'_> {}
753
754impl Debug for Drain<'_> {
755    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
756        f.debug_tuple("Drain")
757            .field(&self.0)
758            .field(&self.1)
759            .finish()
760    }
761}
762
763// SAFETY: Drain stems from a correctly behaving `IndexSet<Entity, EntityHash>`.
764unsafe impl EntitySetIterator for Drain<'_> {}
765
766// SAFETY: Difference stems from two correctly behaving `IndexSet<Entity, EntityHash>`s.
767unsafe impl EntitySetIterator for set::Difference<'_, Entity, EntityHash> {}
768
769// SAFETY: Intersection stems from two correctly behaving `IndexSet<Entity, EntityHash>`s.
770unsafe impl EntitySetIterator for set::Intersection<'_, Entity, EntityHash> {}
771
772// SAFETY: SymmetricDifference stems from two correctly behaving `IndexSet<Entity, EntityHash>`s.
773unsafe impl EntitySetIterator for set::SymmetricDifference<'_, Entity, EntityHash, EntityHash> {}
774
775// SAFETY: Union stems from two correctly behaving `IndexSet<Entity, EntityHash>`s.
776unsafe impl EntitySetIterator for set::Union<'_, Entity, EntityHash> {}
777
778// SAFETY: Splice stems from a correctly behaving `IndexSet<Entity, EntityHash>`s.
779unsafe impl<I: Iterator<Item = Entity>> EntitySetIterator
780    for set::Splice<'_, I, Entity, EntityHash>
781{
782}