Skip to main content

bevy_ecs/entity/
index_set.rs

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