Skip to main content

bevy_ecs/entity/
entity_set.rs

1use alloc::{
2    boxed::Box,
3    collections::{btree_map, btree_set},
4    rc::Rc,
5};
6use bevy_platform::collections::HashSet;
7
8use core::{
9    array,
10    cmp::Ordering,
11    fmt::{Debug, Formatter},
12    hash::{BuildHasher, Hash},
13    iter::{self, FusedIterator, Product, Sum},
14    option, ptr, result,
15};
16
17use super::{Entity, UniqueEntityEquivalentSlice};
18
19use bevy_platform::sync::Arc;
20
21/// A trait for types that contain an [`Entity`].
22///
23/// This trait behaves similarly to `Borrow<Entity>`, but yielding `Entity` directly.
24///
25/// It should only be implemented when:
26/// - Retrieving the [`Entity`] is a simple operation.
27/// - The [`Entity`] contained by the type is unambiguous.
28pub trait ContainsEntity {
29    /// Returns the contained entity.
30    fn entity(&self) -> Entity;
31}
32
33/// A trait for types that represent an [`Entity`].
34///
35/// Comparison trait behavior between an [`EntityEquivalent`] type and its underlying entity will match.
36/// This property includes [`PartialEq`], [`Eq`], [`PartialOrd`], [`Ord`] and [`Hash`],
37/// and remains even after [`Clone`] and/or [`Borrow`] calls.
38///
39/// # Safety
40/// Any [`PartialEq`], [`Eq`], [`PartialOrd`], and [`Ord`] impls must evaluate the same for `Self` and
41/// its underlying entity.
42/// `x.entity() == y.entity()` must be equivalent to `x == y`.
43///
44/// The above equivalence must also hold through and between calls to any [`Clone`] and
45/// [`Borrow`]/[`BorrowMut`] impls in place of [`entity()`].
46///
47/// The result of [`entity()`] must be unaffected by any interior mutability.
48///
49/// The aforementioned properties imply determinism in both [`entity()`] calls
50/// and comparison trait behavior.
51///
52/// All [`Hash`] impls except that for [`Entity`] must delegate to the [`Hash`] impl of
53/// another [`EntityEquivalent`] type. All conversions to the delegatee within the [`Hash`] impl must
54/// follow [`entity()`] equivalence.
55///
56/// It should be noted that [`Hash`] is *not* a comparison trait, and with [`Hash::hash`] being forcibly
57/// generic over all [`Hasher`]s, **cannot** guarantee determinism or uniqueness of any final hash values
58/// on its own.
59/// To obtain hash values forming the same total order as [`Entity`], any [`Hasher`] used must be
60/// deterministic and concerning [`Entity`], collisionless.
61/// Standard library hash collections handle collisions with an [`Eq`] fallback, but do not account for
62/// determinism when [`BuildHasher`] is unspecified.
63///
64/// [`Hash`]: core::hash::Hash
65/// [`Hasher`]: core::hash::Hasher
66/// [`Borrow`]: core::borrow::Borrow
67/// [`BorrowMut`]: core::borrow::BorrowMut
68/// [`entity()`]: ContainsEntity::entity
69pub unsafe trait EntityEquivalent: ContainsEntity + Eq {}
70
71impl ContainsEntity for Entity {
72    fn entity(&self) -> Entity {
73        *self
74    }
75}
76
77// SAFETY:
78// The trait implementations of Entity are correct and deterministic.
79unsafe impl EntityEquivalent for Entity {}
80
81impl<T: ContainsEntity> ContainsEntity for &T {
82    fn entity(&self) -> Entity {
83        (**self).entity()
84    }
85}
86
87// SAFETY:
88// `&T` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
89// `Clone` and `Borrow` maintain equality.
90// `&T` is `Freeze`.
91unsafe impl<T: EntityEquivalent> EntityEquivalent for &T {}
92
93impl<T: ContainsEntity> ContainsEntity for &mut T {
94    fn entity(&self) -> Entity {
95        (**self).entity()
96    }
97}
98
99// SAFETY:
100// `&mut T` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
101// `Borrow` and `BorrowMut` maintain equality.
102//  `&mut T` is `Freeze`.
103unsafe impl<T: EntityEquivalent> EntityEquivalent for &mut T {}
104
105impl<T: ContainsEntity> ContainsEntity for Box<T> {
106    fn entity(&self) -> Entity {
107        (**self).entity()
108    }
109}
110
111// SAFETY:
112// `Box<T>` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
113// `Clone`, `Borrow` and `BorrowMut` maintain equality.
114// `Box<T>` is `Freeze`.
115unsafe impl<T: EntityEquivalent> EntityEquivalent for Box<T> {}
116
117impl<T: ContainsEntity> ContainsEntity for Rc<T> {
118    fn entity(&self) -> Entity {
119        (**self).entity()
120    }
121}
122
123// SAFETY:
124// `Rc<T>` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
125// `Clone`, `Borrow` and `BorrowMut` maintain equality.
126// `Rc<T>` is `Freeze`.
127unsafe impl<T: EntityEquivalent> EntityEquivalent for Rc<T> {}
128
129impl<T: ContainsEntity> ContainsEntity for Arc<T> {
130    fn entity(&self) -> Entity {
131        (**self).entity()
132    }
133}
134
135// SAFETY:
136// `Arc<T>` delegates `PartialEq`, `Eq`, `PartialOrd`, `Ord`, and `Hash` to T.
137// `Clone`, `Borrow` and `BorrowMut` maintain equality.
138// `Arc<T>` is `Freeze`.
139unsafe impl<T: EntityEquivalent> EntityEquivalent for Arc<T> {}
140
141/// A set of unique entities.
142///
143/// Any element returned by [`Self::IntoIter`] will compare non-equal to every other element in the iterator.
144/// As a consequence, [`into_iter()`] on `EntitySet` will always produce another `EntitySet`.
145///
146/// Implementing this trait allows for unique query iteration over a list of entities.
147/// See [`iter_many_unique`] and [`iter_many_unique_mut`].
148///
149/// Note that there is no guarantee of the [`IntoIterator`] impl being deterministic,
150/// it might return different iterators when called multiple times.
151/// Neither is there a guarantee that the comparison trait impls of `EntitySet` match that
152/// of the respective [`EntitySetIterator`] (or of a [`Vec`] collected from its elements).
153///
154/// [`Self::IntoIter`]: IntoIterator::IntoIter
155/// [`into_iter()`]: IntoIterator::into_iter
156/// [`iter_many_unique`]: crate::system::Query::iter_many_unique
157/// [`iter_many_unique_mut`]: crate::system::Query::iter_many_unique_mut
158/// [`Vec`]: alloc::vec::Vec
159pub trait EntitySet: IntoIterator<IntoIter: EntitySetIterator> {}
160
161impl<T: IntoIterator<IntoIter: EntitySetIterator>> EntitySet for T {}
162
163/// An iterator over a set of unique entities.
164///
165/// Every `EntitySetIterator` is also [`EntitySet`].
166///
167/// # Safety
168///
169/// `x != y` must hold for any 2 elements returned by the iterator.
170/// This is always true for iterators that cannot return more than one element.
171pub unsafe trait EntitySetIterator: Iterator<Item: EntityEquivalent> {
172    /// Transforms an `EntitySetIterator` into a collection.
173    ///
174    /// This is a specialized form of [`collect`], for collections which benefit from the uniqueness guarantee.
175    /// When present, this should always be preferred over [`collect`].
176    ///
177    /// [`collect`]: Iterator::collect
178    //  FIXME: When subtrait item shadowing stabilizes, this should be renamed and shadow `Iterator::collect`
179    fn collect_set<B: FromEntitySetIterator<Self::Item>>(self) -> B
180    where
181        Self: Sized,
182    {
183        FromEntitySetIterator::from_entity_set_iter(self)
184    }
185}
186
187// SAFETY:
188// A correct `BTreeMap` contains only unique keys.
189// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeMap`.
190unsafe impl<K: EntityEquivalent, V> EntitySetIterator for btree_map::Keys<'_, K, V> {}
191
192// SAFETY:
193// A correct `BTreeMap` contains only unique keys.
194// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeMap`.
195unsafe impl<K: EntityEquivalent, V> EntitySetIterator for btree_map::IntoKeys<K, V> {}
196
197// SAFETY:
198// A correct `BTreeSet` contains only unique elements.
199// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
200// The sub-range maintains uniqueness.
201unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::Range<'_, T> {}
202
203// SAFETY:
204// A correct `BTreeSet` contains only unique elements.
205// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
206// The "intersection" operation maintains uniqueness.
207unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Intersection<'_, T> {}
208
209// SAFETY:
210// A correct `BTreeSet` contains only unique elements.
211// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
212// The "union" operation maintains uniqueness.
213unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Union<'_, T> {}
214
215// SAFETY:
216// A correct `BTreeSet` contains only unique elements.
217// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
218// The "difference" operation maintains uniqueness.
219unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::Difference<'_, T> {}
220
221// SAFETY:
222// A correct `BTreeSet` contains only unique elements.
223// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
224// The "symmetric difference" operation maintains uniqueness.
225unsafe impl<T: EntityEquivalent + Ord> EntitySetIterator for btree_set::SymmetricDifference<'_, T> {}
226
227// SAFETY:
228// A correct `BTreeSet` contains only unique elements.
229// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
230unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::Iter<'_, T> {}
231
232// SAFETY:
233// A correct `BTreeSet` contains only unique elements.
234// EntityEquivalent guarantees a trustworthy Ord impl for T, and thus a correct `BTreeSet`.
235unsafe impl<T: EntityEquivalent> EntitySetIterator for btree_set::IntoIter<T> {}
236
237// SAFETY: This iterator only returns one element.
238unsafe impl<T: EntityEquivalent> EntitySetIterator for option::Iter<'_, T> {}
239
240// SAFETY: This iterator only returns one element.
241// unsafe impl<T: EntityEquivalent> EntitySetIterator for option::IterMut<'_, T> {}
242
243// SAFETY: This iterator only returns one element.
244unsafe impl<T: EntityEquivalent> EntitySetIterator for option::IntoIter<T> {}
245
246// SAFETY: This iterator only returns one element.
247unsafe impl<T: EntityEquivalent> EntitySetIterator for result::Iter<'_, T> {}
248
249// SAFETY: This iterator only returns one element.
250// unsafe impl<T: EntityEquivalent> EntitySetIterator for result::IterMut<'_, T> {}
251
252// SAFETY: This iterator only returns one element.
253unsafe impl<T: EntityEquivalent> EntitySetIterator for result::IntoIter<T> {}
254
255// SAFETY: This iterator only returns one element.
256unsafe impl<T: EntityEquivalent> EntitySetIterator for array::IntoIter<T, 1> {}
257
258// SAFETY: This iterator does not return any elements.
259unsafe impl<T: EntityEquivalent> EntitySetIterator for array::IntoIter<T, 0> {}
260
261// SAFETY: This iterator only returns one element.
262unsafe impl<T: EntityEquivalent, F: FnOnce() -> T> EntitySetIterator for iter::OnceWith<F> {}
263
264// SAFETY: This iterator only returns one element.
265unsafe impl<T: EntityEquivalent> EntitySetIterator for iter::Once<T> {}
266
267// SAFETY: This iterator does not return any elements.
268unsafe impl<T: EntityEquivalent> EntitySetIterator for iter::Empty<T> {}
269
270// SAFETY: Taking a mutable reference of an iterator has no effect on its elements.
271unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for &mut I {}
272
273// SAFETY: Boxing an iterator has no effect on its elements.
274unsafe impl<I: EntitySetIterator + ?Sized> EntitySetIterator for Box<I> {}
275
276// SAFETY: EntityEquivalent ensures that Copy does not affect equality, via its restrictions on Clone.
277unsafe impl<'a, T: 'a + EntityEquivalent + Copy, I: EntitySetIterator<Item = &'a T>>
278    EntitySetIterator for iter::Copied<I>
279{
280}
281
282// SAFETY: EntityEquivalent ensures that Clone does not affect equality.
283unsafe impl<'a, T: 'a + EntityEquivalent + Clone, I: EntitySetIterator<Item = &'a T>>
284    EntitySetIterator for iter::Cloned<I>
285{
286}
287
288// SAFETY: Discarding elements maintains uniqueness.
289unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
290    for iter::Filter<I, P>
291{
292}
293
294// SAFETY: Yielding only `None` after yielding it once can only remove elements, which maintains uniqueness.
295unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Fuse<I> {}
296
297// SAFETY:
298// Obtaining immutable references the elements of an iterator does not affect uniqueness.
299// EntityEquivalent ensures the lack of interior mutability.
300unsafe impl<I: EntitySetIterator, F: FnMut(&<I as Iterator>::Item)> EntitySetIterator
301    for iter::Inspect<I, F>
302{
303}
304
305// SAFETY: Reversing an iterator does not affect uniqueness.
306unsafe impl<I: DoubleEndedIterator + EntitySetIterator> EntitySetIterator for iter::Rev<I> {}
307
308// SAFETY: Discarding elements maintains uniqueness.
309unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Skip<I> {}
310
311// SAFETY: Discarding elements maintains uniqueness.
312unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
313    for iter::SkipWhile<I, P>
314{
315}
316
317// SAFETY: Discarding elements maintains uniqueness.
318unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::Take<I> {}
319
320// SAFETY: Discarding elements maintains uniqueness.
321unsafe impl<I: EntitySetIterator, P: FnMut(&<I as Iterator>::Item) -> bool> EntitySetIterator
322    for iter::TakeWhile<I, P>
323{
324}
325
326// SAFETY: Discarding elements maintains uniqueness.
327unsafe impl<I: EntitySetIterator> EntitySetIterator for iter::StepBy<I> {}
328
329/// Conversion from an `EntitySetIterator`.
330///
331/// Some collections, while they can be constructed from plain iterators,
332/// benefit strongly from the additional uniqueness guarantee [`EntitySetIterator`] offers.
333/// Mirroring [`Iterator::collect`]/[`FromIterator::from_iter`], [`EntitySetIterator::collect_set`] and
334/// `FromEntitySetIterator::from_entity_set_iter` can be used for construction.
335///
336/// See also: [`EntitySet`].
337// FIXME: When subtrait item shadowing stabilizes, this should be renamed and shadow `FromIterator::from_iter`
338pub trait FromEntitySetIterator<A: EntityEquivalent>: FromIterator<A> {
339    /// Creates a value from an [`EntitySetIterator`].
340    fn from_entity_set_iter<T: EntitySet<Item = A>>(set_iter: T) -> Self;
341}
342
343impl<T: EntityEquivalent + Hash, S: BuildHasher + Default> FromEntitySetIterator<T>
344    for HashSet<T, S>
345{
346    #[inline]
347    fn from_entity_set_iter<I: EntitySet<Item = T>>(set_iter: I) -> Self {
348        let iter = set_iter.into_iter();
349        let set = HashSet::with_capacity_and_hasher(iter.size_hint().0, S::default());
350        iter.fold(set, |mut set, e| {
351            // SAFETY: Every element in self is unique.
352            unsafe {
353                set.insert_unique_unchecked(e);
354            }
355            set
356        })
357    }
358}
359
360/// An iterator that yields unique entities.
361///
362/// This wrapper can provide an [`EntitySetIterator`] implementation when an instance of `I` is known to uphold uniqueness.
363#[repr(transparent)]
364pub struct UniqueEntityIter<I: Iterator<Item: EntityEquivalent>> {
365    iter: I,
366}
367
368impl<I: EntitySetIterator> UniqueEntityIter<I> {
369    /// Constructs a `UniqueEntityIter` from an [`EntitySetIterator`].
370    #[inline]
371    pub const fn from_entity_set_iter(iter: I) -> Self {
372        // SAFETY: iter implements `EntitySetIterator`.
373        unsafe { Self::from_iter_unchecked(iter) }
374    }
375}
376
377impl<I: Iterator<Item: EntityEquivalent>> UniqueEntityIter<I> {
378    /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
379    ///
380    /// # Safety
381    /// `iter` must only yield unique elements.
382    /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
383    #[inline]
384    pub const unsafe fn from_iter_unchecked(iter: I) -> Self {
385        Self { iter }
386    }
387
388    /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
389    ///
390    /// # Safety
391    /// `iter` must only yield unique elements.
392    /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
393    #[inline]
394    pub const unsafe fn from_iter_ref_unchecked(iter: &I) -> &Self {
395        // SAFETY: UniqueEntityIter is a transparent wrapper around I.
396        unsafe { &*ptr::from_ref(iter).cast() }
397    }
398
399    /// Constructs a [`UniqueEntityIter`] from an iterator unsafely.
400    ///
401    /// # Safety
402    /// `iter` must only yield unique elements.
403    /// As in, the resulting iterator must adhere to the safety contract of [`EntitySetIterator`].
404    #[inline]
405    pub const unsafe fn from_iter_mut_unchecked(iter: &mut I) -> &mut Self {
406        // SAFETY: UniqueEntityIter is a transparent wrapper around I.
407        unsafe { &mut *ptr::from_mut(iter).cast() }
408    }
409
410    /// Returns the inner `I`.
411    pub fn into_inner(self) -> I {
412        self.iter
413    }
414
415    /// Returns a reference to the inner `I`.
416    pub const fn as_inner(&self) -> &I {
417        &self.iter
418    }
419
420    /// Returns a mutable reference to the inner `I`.
421    ///
422    /// # Safety
423    ///
424    /// `self` must always contain an iterator that yields unique elements,
425    /// even while this reference is live.
426    pub const unsafe fn as_mut_inner(&mut self) -> &mut I {
427        &mut self.iter
428    }
429}
430
431// The following methods are not forwarded:
432// `try_fold` and `try_for_each` are dependent on the nightly `Try` trait.
433//
434// `chain`, `zip`, `map`, `filter`, `filter_map`, `enumerate`, `peekable`,
435// `skip_while`, `take_while`, `map_while`, `skip`, take, `scan`, `flat_map`,
436// `flatten`, `inspect`, `rev`, `copied`, `cloned` and `cycle`
437// return combinator iterator types with no public construction methods.
438//
439// `unzip` because no tuples implement `EntityEquivalent`.
440// `rposition`, given that the compiler cannot infer the implied bounds for I.
441impl<I: Iterator<Item: EntityEquivalent>> Iterator for UniqueEntityIter<I> {
442    type Item = I::Item;
443
444    fn next(&mut self) -> Option<Self::Item> {
445        self.iter.next()
446    }
447
448    fn size_hint(&self) -> (usize, Option<usize>) {
449        self.iter.size_hint()
450    }
451
452    fn count(self) -> usize {
453        self.iter.count()
454    }
455
456    fn last(self) -> Option<Self::Item> {
457        self.iter.last()
458    }
459
460    fn nth(&mut self, n: usize) -> Option<Self::Item> {
461        self.iter.nth(n)
462    }
463
464    fn for_each<F>(self, f: F)
465    where
466        Self: Sized,
467        F: FnMut(Self::Item),
468    {
469        self.iter.for_each(f);
470    }
471
472    fn collect<B: FromIterator<Self::Item>>(self) -> B
473    where
474        Self: Sized,
475    {
476        self.iter.collect()
477    }
478
479    fn partition<B, F>(self, f: F) -> (B, B)
480    where
481        Self: Sized,
482        B: Default + Extend<Self::Item>,
483        F: FnMut(&Self::Item) -> bool,
484    {
485        self.iter.partition(f)
486    }
487
488    fn fold<B, F>(self, init: B, f: F) -> B
489    where
490        Self: Sized,
491        F: FnMut(B, Self::Item) -> B,
492    {
493        self.iter.fold(init, f)
494    }
495
496    fn reduce<F>(self, f: F) -> Option<Self::Item>
497    where
498        Self: Sized,
499        F: FnMut(Self::Item, Self::Item) -> Self::Item,
500    {
501        self.iter.reduce(f)
502    }
503
504    fn all<F>(&mut self, f: F) -> bool
505    where
506        Self: Sized,
507        F: FnMut(Self::Item) -> bool,
508    {
509        self.iter.all(f)
510    }
511
512    fn any<F>(&mut self, f: F) -> bool
513    where
514        Self: Sized,
515        F: FnMut(Self::Item) -> bool,
516    {
517        self.iter.any(f)
518    }
519
520    fn find<P>(&mut self, predicate: P) -> Option<Self::Item>
521    where
522        Self: Sized,
523        P: FnMut(&Self::Item) -> bool,
524    {
525        self.iter.find(predicate)
526    }
527
528    fn find_map<B, F>(&mut self, f: F) -> Option<B>
529    where
530        Self: Sized,
531        F: FnMut(Self::Item) -> Option<B>,
532    {
533        self.iter.find_map(f)
534    }
535
536    fn position<P>(&mut self, predicate: P) -> Option<usize>
537    where
538        Self: Sized,
539        P: FnMut(Self::Item) -> bool,
540    {
541        self.iter.position(predicate)
542    }
543
544    fn max(self) -> Option<Self::Item>
545    where
546        Self: Sized,
547        Self::Item: Ord,
548    {
549        self.iter.max()
550    }
551
552    fn min(self) -> Option<Self::Item>
553    where
554        Self: Sized,
555        Self::Item: Ord,
556    {
557        self.iter.min()
558    }
559
560    fn max_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
561    where
562        Self: Sized,
563        F: FnMut(&Self::Item) -> B,
564    {
565        self.iter.max_by_key(f)
566    }
567
568    fn max_by<F>(self, compare: F) -> Option<Self::Item>
569    where
570        Self: Sized,
571        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
572    {
573        self.iter.max_by(compare)
574    }
575
576    fn min_by_key<B: Ord, F>(self, f: F) -> Option<Self::Item>
577    where
578        Self: Sized,
579        F: FnMut(&Self::Item) -> B,
580    {
581        self.iter.min_by_key(f)
582    }
583
584    fn min_by<F>(self, compare: F) -> Option<Self::Item>
585    where
586        Self: Sized,
587        F: FnMut(&Self::Item, &Self::Item) -> Ordering,
588    {
589        self.iter.min_by(compare)
590    }
591
592    fn sum<S>(self) -> S
593    where
594        Self: Sized,
595        S: Sum<Self::Item>,
596    {
597        self.iter.sum()
598    }
599
600    fn product<P>(self) -> P
601    where
602        Self: Sized,
603        P: Product<Self::Item>,
604    {
605        self.iter.product()
606    }
607
608    fn cmp<O>(self, other: O) -> Ordering
609    where
610        O: IntoIterator<Item = Self::Item>,
611        Self::Item: Ord,
612        Self: Sized,
613    {
614        self.iter.cmp(other)
615    }
616
617    fn partial_cmp<O>(self, other: O) -> Option<Ordering>
618    where
619        O: IntoIterator,
620        Self::Item: PartialOrd<O::Item>,
621        Self: Sized,
622    {
623        self.iter.partial_cmp(other)
624    }
625
626    fn eq<O>(self, other: O) -> bool
627    where
628        O: IntoIterator,
629        Self::Item: PartialEq<O::Item>,
630        Self: Sized,
631    {
632        self.iter.eq(other)
633    }
634
635    fn lt<O>(self, other: O) -> bool
636    where
637        O: IntoIterator,
638        Self::Item: PartialOrd<O::Item>,
639        Self: Sized,
640    {
641        self.iter.lt(other)
642    }
643
644    fn le<O>(self, other: O) -> bool
645    where
646        O: IntoIterator,
647        Self::Item: PartialOrd<O::Item>,
648        Self: Sized,
649    {
650        self.iter.le(other)
651    }
652
653    fn gt<O>(self, other: O) -> bool
654    where
655        O: IntoIterator,
656        Self::Item: PartialOrd<O::Item>,
657        Self: Sized,
658    {
659        self.iter.gt(other)
660    }
661
662    fn ge<O>(self, other: O) -> bool
663    where
664        O: IntoIterator,
665        Self::Item: PartialOrd<O::Item>,
666        Self: Sized,
667    {
668        self.iter.ge(other)
669    }
670
671    fn is_sorted(self) -> bool
672    where
673        Self: Sized,
674        Self::Item: PartialOrd,
675    {
676        self.iter.is_sorted()
677    }
678
679    fn is_sorted_by<F>(self, compare: F) -> bool
680    where
681        Self: Sized,
682        F: FnMut(&Self::Item, &Self::Item) -> bool,
683    {
684        self.iter.is_sorted_by(compare)
685    }
686
687    fn is_sorted_by_key<F, K>(self, f: F) -> bool
688    where
689        Self: Sized,
690        F: FnMut(Self::Item) -> K,
691        K: PartialOrd,
692    {
693        self.iter.is_sorted_by_key(f)
694    }
695}
696
697impl<I: ExactSizeIterator<Item: EntityEquivalent>> ExactSizeIterator for UniqueEntityIter<I> {}
698
699// `try_rfold` is dependent on the nightly `Try` trait, and can thus not be forwarded here.
700impl<I: DoubleEndedIterator<Item: EntityEquivalent>> DoubleEndedIterator for UniqueEntityIter<I> {
701    #[inline]
702    fn next_back(&mut self) -> Option<Self::Item> {
703        self.iter.next_back()
704    }
705
706    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
707        self.iter.nth_back(n)
708    }
709
710    fn rfold<B, F>(self, init: B, f: F) -> B
711    where
712        Self: Sized,
713        F: FnMut(B, Self::Item) -> B,
714    {
715        self.iter.rfold(init, f)
716    }
717
718    fn rfind<P>(&mut self, predicate: P) -> Option<Self::Item>
719    where
720        Self: Sized,
721        P: FnMut(&Self::Item) -> bool,
722    {
723        self.iter.rfind(predicate)
724    }
725}
726
727impl<I: FusedIterator<Item: EntityEquivalent>> FusedIterator for UniqueEntityIter<I> {}
728
729// SAFETY: The underlying iterator is ensured to only return unique elements by its construction.
730unsafe impl<I: Iterator<Item: EntityEquivalent>> EntitySetIterator for UniqueEntityIter<I> {}
731
732impl<T, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>> AsRef<[T]> for UniqueEntityIter<I> {
733    fn as_ref(&self) -> &[T] {
734        self.iter.as_ref()
735    }
736}
737
738impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsRef<[T]>>
739    AsRef<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
740{
741    fn as_ref(&self) -> &UniqueEntityEquivalentSlice<T> {
742        // SAFETY: All elements in the original slice are unique.
743        unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked(self.iter.as_ref()) }
744    }
745}
746
747impl<T: EntityEquivalent, I: Iterator<Item: EntityEquivalent> + AsMut<[T]>>
748    AsMut<UniqueEntityEquivalentSlice<T>> for UniqueEntityIter<I>
749{
750    fn as_mut(&mut self) -> &mut UniqueEntityEquivalentSlice<T> {
751        // SAFETY: All elements in the original slice are unique.
752        unsafe { UniqueEntityEquivalentSlice::from_slice_unchecked_mut(self.iter.as_mut()) }
753    }
754}
755
756// Default does not guarantee uniqueness, meaning `I` needs to be EntitySetIterator.
757impl<I: EntitySetIterator + Default> Default for UniqueEntityIter<I> {
758    fn default() -> Self {
759        Self {
760            iter: Default::default(),
761        }
762    }
763}
764
765// Clone does not guarantee to maintain uniqueness, meaning `I` needs to be EntitySetIterator.
766impl<I: EntitySetIterator + Clone> Clone for UniqueEntityIter<I> {
767    fn clone(&self) -> Self {
768        Self {
769            iter: self.iter.clone(),
770        }
771    }
772
773    fn clone_from(&mut self, source: &Self) {
774        self.iter.clone_from(&source.iter);
775    }
776}
777
778impl<I: Iterator<Item: EntityEquivalent> + Debug> Debug for UniqueEntityIter<I> {
779    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
780        f.debug_struct("UniqueEntityIter")
781            .field("iter", &self.iter)
782            .finish()
783    }
784}
785
786#[cfg(test)]
787mod tests {
788    use alloc::{vec, vec::Vec};
789
790    use crate::{
791        component::Component,
792        entity::{Entity, EntityEquivalentHashMap, EntityEquivalentHashSet},
793        prelude::{Schedule, World},
794        query::{QueryState, With},
795        system::Query,
796        world::Mut,
797    };
798
799    use super::{ContainsEntity, EntityEquivalent, UniqueEntityIter};
800
801    #[derive(Component, Clone)]
802    pub struct Thing;
803
804    #[expect(
805        clippy::iter_skip_zero,
806        reason = "The `skip(0)` is used to ensure that the `Skip` iterator implements `EntitySet`, which is needed to pass the iterator as the `entities` parameter."
807    )]
808    #[test]
809    fn preserving_uniqueness() {
810        let mut world = World::new();
811
812        let mut query = QueryState::<&mut Thing>::new(&mut world);
813
814        let spawn_batch: Vec<Entity> = world.spawn_batch(vec![Thing; 1000]).collect();
815
816        // SAFETY: SpawnBatchIter is `EntitySetIterator`,
817        let mut unique_entity_iter =
818            unsafe { UniqueEntityIter::from_iter_unchecked(spawn_batch.iter()) };
819
820        let entity_set = unique_entity_iter
821            .by_ref()
822            .filter(|_| true)
823            .fuse()
824            .inspect(|_| ())
825            .rev()
826            .skip(0)
827            .skip_while(|_| false)
828            .take(1000)
829            .take_while(|_| true)
830            .step_by(2)
831            .cloned();
832
833        // With `iter_many_mut` collecting is not possible, because you need to drop each `Mut`/`&mut` before the next is retrieved.
834        let _results: Vec<Mut<Thing>> = query
835            .iter_many_unique_mut(&mut world, entity_set)
836            .unwrapped()
837            .collect();
838    }
839
840    #[test]
841    fn nesting_queries() {
842        let mut world = World::new();
843
844        world.spawn_batch(vec![Thing; 1000]);
845
846        pub fn system(
847            mut thing_entities: Query<Entity, With<Thing>>,
848            mut things: Query<&mut Thing>,
849        ) {
850            things.iter_many_unique(thing_entities.iter());
851            things.iter_many_unique_mut(thing_entities.iter_mut());
852        }
853
854        let mut schedule = Schedule::default();
855        schedule.add_systems(system);
856        schedule.run(&mut world);
857    }
858
859    #[derive(Copy, Clone, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
860    struct EntityWrapper(Entity);
861
862    impl ContainsEntity for EntityWrapper {
863        fn entity(&self) -> Entity {
864            self.0
865        }
866    }
867
868    impl EntityWrapper {
869        fn new(index: u32) -> EntityWrapper {
870            EntityWrapper(Entity::from_raw_u32(index).unwrap())
871        }
872    }
873
874    // SAFETY: EntityWrapper is a newtype around Entity that derives its comparison traits.
875    unsafe impl EntityEquivalent for EntityWrapper {}
876
877    #[test]
878    fn entity_equivalent_map_test() {
879        type EntityWrapperMap = EntityEquivalentHashMap<EntityWrapper, i32>;
880
881        let mut map = EntityWrapperMap::default();
882        map.insert(EntityWrapper::new(0), 10);
883        map.insert(EntityWrapper::new(1), 11);
884        map.insert(EntityWrapper::new(0), 12);
885        assert_eq!(map.len(), 2);
886        assert!(map
887            .get(&EntityWrapper::new(0))
888            .is_some_and(|val| *val == 12));
889        map.remove(&EntityWrapper::new(1));
890        assert_eq!(map.len(), 1);
891        map.clear();
892        assert!(map.is_empty());
893    }
894
895    #[test]
896    fn entity_equivalent_set_test() {
897        type EntityWrapperSet = EntityEquivalentHashSet<EntityWrapper>;
898
899        let mut set = EntityWrapperSet::default();
900        set.insert(EntityWrapper::new(0));
901        set.insert(EntityWrapper::new(1));
902        set.insert(EntityWrapper::new(0));
903        assert_eq!(set.len(), 2);
904        assert!(set.get(&EntityWrapper::new(0)).is_some());
905        set.remove(&EntityWrapper::new(1));
906        assert_eq!(set.len(), 1);
907        set.clear();
908        assert!(set.is_empty());
909    }
910}