Skip to main content

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