Skip to main content

bevy_ecs/query/
access.rs

1use crate::world::unsafe_world_cell::UnsafeWorldCell;
2use crate::{component::ComponentId, resource::IS_RESOURCE};
3use alloc::{format, string::String, vec, vec::Vec};
4use core::iter::FusedIterator;
5use core::mem;
6use core::{fmt, fmt::Debug};
7use derive_more::From;
8use fixedbitset::{Difference, FixedBitSet, Intersection, IntoOnes, Ones, Union};
9use thiserror::Error;
10
11/// A set of bits that is either a finite set, or the set complement of a finite set.
12#[derive(PartialEq, Eq, Clone, Debug)]
13pub enum InvertibleComponentIdSet {
14    /// A finite [`InvertibleComponentIdSet`] that includes all components in the inner set.
15    Included(ComponentIdSet),
16    /// An unbounded [`InvertibleComponentIdSet`] that includes all components *not* in the inner set.
17    Excluded(ComponentIdSet),
18}
19
20impl Default for InvertibleComponentIdSet {
21    fn default() -> Self {
22        Self::new()
23    }
24}
25
26impl InvertibleComponentIdSet {
27    /// Creates a new empty `InvertibleSet`.
28    #[inline]
29    pub const fn new() -> Self {
30        Self::Included(ComponentIdSet::new())
31    }
32
33    /// Creates a new `InvertibleSet` that includes all components.
34    #[inline]
35    pub const fn new_all() -> Self {
36        Self::Excluded(ComponentIdSet::new())
37    }
38
39    /// Adds a [`ComponentId`] to the set.
40    #[inline]
41    pub fn insert(&mut self, index: ComponentId) {
42        match self {
43            Self::Included(included) => included.insert(index),
44            Self::Excluded(excluded) => excluded.remove(index),
45        }
46    }
47
48    /// Removes a [`ComponentId`] from the set.
49    #[inline]
50    pub fn remove(&mut self, index: ComponentId) {
51        match self {
52            Self::Included(included) => included.remove(index),
53            Self::Excluded(excluded) => excluded.insert(index),
54        }
55    }
56
57    /// Removes all [`ComponentId`]s from the set.
58    #[inline]
59    pub fn clear(&mut self) {
60        *self = Self::new();
61    }
62
63    /// Adds all [`ComponentId`]s to the set.
64    #[inline]
65    pub fn all(&mut self) {
66        *self = Self::new_all();
67    }
68
69    /// Returns `true` if the [`ComponentId`] is in the set.
70    #[inline]
71    pub fn contains(&self, index: ComponentId) -> bool {
72        match self {
73            Self::Included(included) => included.contains(index),
74            Self::Excluded(excluded) => !excluded.contains(index),
75        }
76    }
77
78    /// Returns `true` if the set is empty.
79    /// Note that an unbounded set is never clear.
80    #[inline]
81    pub fn is_clear(&self) -> bool {
82        match self {
83            Self::Included(included) => included.is_clear(),
84            Self::Excluded(_) => false,
85        }
86    }
87
88    /// Returns `true` if the set contains all components.
89    /// Note that a finite set is never fully set.
90    #[inline]
91    pub fn is_all(&self) -> bool {
92        match self {
93            Self::Included(_) => false,
94            Self::Excluded(excluded) => excluded.is_clear(),
95        }
96    }
97
98    /// Returns `true` if this is an unbounded set, or `false` if it is a finite set.
99    #[inline]
100    pub fn is_unbounded(&self) -> bool {
101        match self {
102            Self::Included(_) => false,
103            Self::Excluded(_) => true,
104        }
105    }
106
107    /// If this is a finite set, returns the set.
108    /// If this is an unbounded set, returns `None`.
109    #[inline]
110    pub fn into_finite_set(self) -> Option<ComponentIdSet> {
111        match self {
112            Self::Included(included) => Some(included),
113            Self::Excluded(_) => None,
114        }
115    }
116
117    /// If this is a finite set, returns the set.
118    /// If this is an unbounded set, returns `None`.
119    #[inline]
120    pub fn as_finite_set(&self) -> Option<&ComponentIdSet> {
121        match self {
122            Self::Included(included) => Some(included),
123            Self::Excluded(_) => None,
124        }
125    }
126
127    /// If this is an unbounded set, returns the set of components
128    /// that are excluded from the set.
129    /// If this is a finite set, returns `None`.
130    #[inline]
131    pub fn as_exclusion_set(&self) -> Option<&ComponentIdSet> {
132        match self {
133            Self::Included(_) => None,
134            Self::Excluded(excluded) => Some(excluded),
135        }
136    }
137
138    /// In-place union of two sets.
139    pub fn union_with(&mut self, other: &Self) {
140        match (&mut *self, other) {
141            (Self::Included(this), Self::Included(other)) => this.union_with(other),
142            (Self::Included(this), Self::Excluded(other)) => {
143                this.difference_from(other);
144                *self = Self::Excluded(mem::take(this));
145            }
146            (Self::Excluded(this), Self::Included(other)) => this.difference_with(other),
147            (Self::Excluded(this), Self::Excluded(other)) => this.intersect_with(other),
148        }
149    }
150
151    /// Returns the union of two sets.
152    pub fn union(&self, other: &Self) -> Self {
153        let mut result = self.clone();
154        result.union_with(other);
155        result
156    }
157
158    /// In-place difference of two sets.
159    pub fn difference_with(&mut self, other: &Self) {
160        match (&mut *self, other) {
161            (Self::Included(this), Self::Included(other)) => this.difference_with(other),
162            (Self::Included(this), Self::Excluded(other)) => this.intersect_with(other),
163            (Self::Excluded(this), Self::Included(other)) => this.union_with(other),
164            (Self::Excluded(this), Self::Excluded(other)) => {
165                this.difference_from(other);
166                *self = Self::Included(mem::take(this));
167            }
168        }
169    }
170
171    /// Returns the set difference of two sets.
172    pub fn difference(&self, other: &Self) -> Self {
173        let mut result = self.clone();
174        result.difference_with(other);
175        result
176    }
177
178    /// In-place intersection of two sets.
179    pub fn intersect_with(&mut self, other: &Self) {
180        match (&mut *self, other) {
181            (Self::Included(this), Self::Included(other)) => this.intersect_with(other),
182            (Self::Included(this), Self::Excluded(other)) => this.difference_with(other),
183            (Self::Excluded(this), Self::Included(other)) => {
184                this.difference_from(other);
185                *self = Self::Included(mem::take(this));
186            }
187            (Self::Excluded(this), Self::Excluded(other)) => this.union_with(other),
188        }
189    }
190
191    /// Returns the intersection of two sets.
192    pub fn intersection(&self, other: &Self) -> Self {
193        let mut result = self.clone();
194        result.intersect_with(other);
195        result
196    }
197
198    /// Returns `true` if `self` has no elements in common with `other`.
199    /// This is equivalent to checking for an empty intersection.
200    pub fn is_disjoint(&self, other: &Self) -> bool {
201        match (self, other) {
202            (Self::Included(this), Self::Included(other)) => this.is_disjoint(other),
203            // Two sets are disjoint if one is a subset of the other's complement.
204            (Self::Included(this), Self::Excluded(other)) => this.is_subset(other),
205            (Self::Excluded(this), Self::Included(other)) => other.is_subset(this),
206            (Self::Excluded(_), Self::Excluded(_)) => false,
207        }
208    }
209
210    /// Returns `true` if the set is a subset of another, i.e. `other` contains at least all the values in `self`.
211    pub fn is_subset(&self, other: &Self) -> bool {
212        match (self, other) {
213            (Self::Included(this), Self::Included(other)) => this.is_subset(other),
214            // Two sets are disjoint if one is a subset of the other's complement.
215            (Self::Included(this), Self::Excluded(other)) => this.is_disjoint(other),
216            (Self::Excluded(_), Self::Included(_)) => false,
217            (Self::Excluded(this), Self::Excluded(other)) => other.is_subset(this),
218        }
219    }
220}
221
222/// Tracks read and write access to specific elements in a collection.
223///
224/// Used internally to ensure soundness during system initialization and execution.
225/// See the [`is_compatible`](Access::is_compatible) and [`get_conflicts`](Access::get_conflicts) functions.
226#[derive(Eq, PartialEq, Default, Debug)]
227pub struct Access {
228    /// All accessed components.
229    ///
230    /// Note: this includes those in [`Self::writes`], since a mutable access also allows read-only
231    /// access.
232    reads: InvertibleComponentIdSet,
233    /// All exclusively-accessed components.
234    writes: InvertibleComponentIdSet,
235    // Components that are not accessed, but whose presence in an archetype affect query results.
236    archetypal: ComponentIdSet,
237}
238
239// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
240impl Clone for Access {
241    fn clone(&self) -> Self {
242        Self {
243            reads: self.reads.clone(),
244            writes: self.writes.clone(),
245            archetypal: self.archetypal.clone(),
246        }
247    }
248
249    fn clone_from(&mut self, source: &Self) {
250        self.reads.clone_from(&source.reads);
251        self.writes.clone_from(&source.writes);
252        self.archetypal.clone_from(&source.archetypal);
253    }
254}
255
256impl Access {
257    /// Creates an empty [`Access`] collection.
258    pub const fn new() -> Self {
259        Self {
260            reads: InvertibleComponentIdSet::new(),
261            writes: InvertibleComponentIdSet::new(),
262            archetypal: ComponentIdSet::new(),
263        }
264    }
265
266    /// Creates an [`Access`] with read access to all components.
267    /// This is equivalent to calling `read_all()` on `Access::new()`,
268    /// but is available in a `const` context.
269    pub(crate) const fn new_read_all() -> Self {
270        Self {
271            reads: InvertibleComponentIdSet::new_all(),
272            writes: InvertibleComponentIdSet::new(),
273            archetypal: ComponentIdSet::new(),
274        }
275    }
276
277    /// Creates an [`Access`] with read and write access to all components.
278    /// This is equivalent to calling `write_all()` on `Access::new()`,
279    /// but is available in a `const` context.
280    pub(crate) const fn new_write_all() -> Self {
281        Self {
282            reads: InvertibleComponentIdSet::new_all(),
283            writes: InvertibleComponentIdSet::new_all(),
284            archetypal: ComponentIdSet::new(),
285        }
286    }
287
288    /// Adds access to the component given by `index`.
289    pub fn add_read(&mut self, index: ComponentId) {
290        self.reads.insert(index);
291    }
292
293    /// Adds exclusive access to the component given by `index`.
294    pub fn add_write(&mut self, index: ComponentId) {
295        self.reads.insert(index);
296        self.writes.insert(index);
297    }
298
299    /// Removes read access to the component given by `index`.
300    ///
301    /// This also removes write access, since if you can't even read a component, you also can't
302    /// write to it.
303    ///
304    /// Because this method corresponds to the set difference operator ∖, it can
305    /// create complicated logical formulas that you should verify correctness
306    /// of. For example, A ∪ (B ∖ A) isn't equivalent to (A ∪ B) ∖ A, so you
307    /// can't replace a call to [`Self::remove_read`] followed by a call to
308    /// [`Self::extend`] with a call to [`Self::extend`] followed by a call to
309    /// [`Self::remove_read`].
310    pub fn remove_read(&mut self, index: ComponentId) {
311        self.writes.remove(index);
312        self.reads.remove(index);
313    }
314
315    /// Removes write access to the component given by `index`.
316    ///
317    /// Unlike [`Self::remove_read`], this method only removes write access, since it's reasonable
318    /// to "downgrade" write access to only read access.
319    ///
320    /// Because this method corresponds to the set difference operator ∖, it can
321    /// create complicated logical formulas that you should verify correctness
322    /// of. For example, A ∪ (B ∖ A) isn't equivalent to (A ∪ B) ∖ A, so you
323    /// can't replace a call to `remove_write` followed by a call to
324    /// `extend` with a call to `extend` followed by a call to
325    /// `remove_write`.
326    pub fn remove_write(&mut self, index: ComponentId) {
327        self.writes.remove(index);
328    }
329
330    /// Adds an archetypal (indirect) access to the component given by `index`.
331    ///
332    /// This is for components whose values are not accessed (and thus will never cause conflicts),
333    /// but whose presence in an archetype may affect query results.
334    ///
335    /// Currently, this is only used for [`Has<T>`] and [`Allow<T>`].
336    ///
337    /// [`Has<T>`]: crate::query::Has
338    /// [`Allow<T>`]: crate::query::filter::Allow
339    pub fn add_archetypal(&mut self, index: ComponentId) {
340        self.archetypal.insert(index);
341    }
342
343    /// Returns `true` if this can access the component given by `index`.
344    pub fn has_read(&self, index: ComponentId) -> bool {
345        self.reads.contains(index)
346    }
347
348    /// Returns `true` if this can access any component.
349    pub fn has_any_read(&self) -> bool {
350        !self.reads.is_clear()
351    }
352
353    /// Returns `true` if this can exclusively access the component given by `index`.
354    pub fn has_write(&self, index: ComponentId) -> bool {
355        self.writes.contains(index)
356    }
357
358    /// Returns `true` if this accesses any component mutably.
359    pub fn has_any_write(&self) -> bool {
360        !self.writes.is_clear()
361    }
362
363    /// Returns true if this has an archetypal (indirect) access to the component given by `index`.
364    ///
365    /// This is a component whose value is not accessed (and thus will never cause conflicts),
366    /// but whose presence in an archetype may affect query results.
367    ///
368    /// Currently, this is only used for [`Has<T>`].
369    ///
370    /// [`Has<T>`]: crate::query::Has
371    pub fn has_archetypal(&self, index: ComponentId) -> bool {
372        self.archetypal.contains(index)
373    }
374
375    /// Sets this as having access to all components (i.e. `EntityRef` and `&World`).
376    #[inline]
377    pub fn read_all(&mut self) {
378        self.reads.all();
379    }
380
381    /// Sets this as having mutable access to all components (i.e. `EntityMut` and `&mut World`).
382    #[inline]
383    pub fn write_all(&mut self) {
384        self.reads.all();
385        self.writes.all();
386    }
387
388    /// Returns `true` if this has access to all components (i.e. `EntityRef` and `&World`).
389    #[inline]
390    pub fn has_read_all(&self) -> bool {
391        self.reads.is_all()
392    }
393
394    /// Returns `true` if this has write access to all components (i.e. `EntityMut` and `&mut World`).
395    #[inline]
396    pub fn has_write_all(&self) -> bool {
397        self.writes.is_all()
398    }
399
400    /// Removes all writes.
401    pub fn clear_writes(&mut self) {
402        self.writes.clear();
403    }
404
405    /// Removes all accesses.
406    pub fn clear(&mut self) {
407        self.reads.clear();
408        self.writes.clear();
409    }
410
411    /// Adds all access from `other`.
412    pub fn extend(&mut self, other: &Access) {
413        self.reads.union_with(&other.reads);
414        self.writes.union_with(&other.writes);
415        self.archetypal.union_with(&other.archetypal);
416    }
417
418    /// Removes any access from `self` that would conflict with `other`.
419    /// This removes any reads and writes for any component written by `other`,
420    /// and removes any writes for any component read by `other`.
421    pub fn remove_conflicting_access(&mut self, other: &Access) {
422        self.reads.difference_with(&other.writes);
423        self.writes.difference_with(&other.reads);
424    }
425
426    /// Returns `true` if the access and `other` can be active at the same time.
427    ///
428    /// [`Access`] instances are incompatible if one can write
429    /// an element that the other can read or write.
430    pub fn is_compatible(&self, other: &Access) -> bool {
431        // We have a conflict if we write and they read or write, or if they
432        // write and we read or write.
433        self.writes.is_disjoint(&other.reads) && other.writes.is_disjoint(&self.reads)
434    }
435
436    /// Returns `true` if the set is a subset of another, i.e. `other` contains
437    /// at least all the values in `self`.
438    pub fn is_subset(&self, other: &Access) -> bool {
439        self.reads.is_subset(&other.reads) && self.writes.is_subset(&other.writes)
440    }
441
442    /// Returns a vector of elements that the access and `other` cannot access at the same time.
443    #[inline]
444    pub fn get_conflicts(&self, other: &Access) -> AccessConflicts {
445        // We have a conflict if we write and they read or write, or if they
446        // write and we read or write.
447        let mut conflicts = self.writes.intersection(&other.reads);
448        conflicts.union_with(&other.writes.intersection(&self.reads));
449        conflicts
450            .into_finite_set()
451            .map_or(AccessConflicts::All, AccessConflicts::Individual)
452    }
453
454    /// Returns the indices of the components that this has an archetypal access to.
455    ///
456    /// These are components whose values are not accessed (and thus will never cause conflicts),
457    /// but whose presence in an archetype may affect query results.
458    ///
459    /// Currently, this is only used for [`Has<T>`].
460    ///
461    /// [`Has<T>`]: crate::query::Has
462    pub fn archetypal(&self) -> &ComponentIdSet {
463        &self.archetypal
464    }
465
466    /// Returns the set of components with read access,
467    /// or an error if the access is unbounded.
468    ///
469    /// This includes components with write access, since write access also allows you to read the
470    /// component.
471    #[deprecated(since = "0.20.0", note = "use `reads_and_writes().as_finite_set()")]
472    pub fn try_reads_and_writes(&self) -> Result<&ComponentIdSet, UnboundedAccessError> {
473        self.reads.as_finite_set().ok_or(UnboundedAccessError {
474            writes_inverted: self.writes.is_unbounded(),
475            reads_inverted: self.reads.is_unbounded(),
476        })
477    }
478
479    /// Returns the set of components with read or write access.
480    ///
481    /// This includes components with write access, since write access also allows you to read the
482    /// component.
483    pub fn reads(&self) -> &InvertibleComponentIdSet {
484        &self.reads
485    }
486
487    /// Returns the set of components with write access,
488    /// or an error if the access is unbounded.
489    #[deprecated(since = "0.20.0", note = "use `writes().as_finite_set()")]
490    pub fn try_writes(&self) -> Result<&ComponentIdSet, UnboundedAccessError> {
491        self.writes.as_finite_set().ok_or(UnboundedAccessError {
492            writes_inverted: self.writes.is_unbounded(),
493            reads_inverted: self.reads.is_unbounded(),
494        })
495    }
496
497    /// Returns the set of components with write access.
498    pub fn writes(&self) -> &InvertibleComponentIdSet {
499        &self.writes
500    }
501
502    /// Returns an iterator over the component IDs and their [`ComponentAccessKind`].
503    ///
504    /// Returns `Err(UnboundedAccess)` if the access is unbounded.
505    /// This typically occurs when an [`Access`] is marked as accessing all
506    /// components, and then adding exceptions.
507    ///
508    /// # Examples
509    ///
510    /// ```rust
511    /// # use bevy_ecs::query::{Access, ComponentAccessKind};
512    /// # use bevy_ecs::component::ComponentId;
513    /// let mut access = Access::default();
514    ///
515    /// access.add_read(ComponentId::new(1));
516    /// access.add_write(ComponentId::new(2));
517    /// access.add_archetypal(ComponentId::new(3));
518    ///
519    /// let result = access
520    ///     .try_iter_access()
521    ///     .map(Iterator::collect::<Vec<_>>);
522    ///
523    /// assert_eq!(
524    ///     result,
525    ///     Ok(vec![
526    ///         ComponentAccessKind::Shared(ComponentId::new(1)),
527    ///         ComponentAccessKind::Exclusive(ComponentId::new(2)),
528    ///         ComponentAccessKind::Archetypal(ComponentId::new(3)),
529    ///     ]),
530    /// );
531    /// ```
532    pub fn try_iter_access(
533        &self,
534    ) -> Result<impl Iterator<Item = ComponentAccessKind> + '_, UnboundedAccessError> {
535        let reads = self.reads.as_finite_set().ok_or(UnboundedAccessError {
536            writes_inverted: self.writes.is_unbounded(),
537            reads_inverted: self.reads.is_unbounded(),
538        })?;
539        let accesses = reads.iter().map(|index| {
540            if self.writes.contains(index) {
541                ComponentAccessKind::Exclusive(index)
542            } else {
543                ComponentAccessKind::Shared(index)
544            }
545        });
546
547        let archetypal = self
548            .archetypal
549            .difference(reads)
550            .map(ComponentAccessKind::Archetypal);
551
552        Ok(accesses.chain(archetypal))
553    }
554}
555
556/// Error returned when attempting to iterate over items included in an [`Access`]
557/// if the access excludes items rather than including them.
558#[derive(Clone, Copy, PartialEq, Eq, Debug, Error)]
559#[error("Access is unbounded")]
560pub struct UnboundedAccessError {
561    /// [`Access`] is defined in terms of _excluding_ [exclusive](ComponentAccessKind::Exclusive)
562    /// access.
563    pub writes_inverted: bool,
564    /// [`Access`] is defined in terms of _excluding_ [shared](ComponentAccessKind::Shared) and
565    /// [exclusive](ComponentAccessKind::Exclusive) access.
566    pub reads_inverted: bool,
567}
568
569/// Describes the level of access for a particular component as defined in an [`Access`].
570#[derive(PartialEq, Eq, Hash, Debug, Clone, Copy)]
571pub enum ComponentAccessKind {
572    /// Archetypical access, such as `Has<Foo>`.
573    Archetypal(ComponentId),
574    /// Shared access, such as `&Foo`.
575    Shared(ComponentId),
576    /// Exclusive access, such as `&mut Foo`.
577    Exclusive(ComponentId),
578}
579
580impl ComponentAccessKind {
581    /// Gets the index of this `ComponentAccessKind`.
582    pub fn index(&self) -> &ComponentId {
583        let (Self::Archetypal(value) | Self::Shared(value) | Self::Exclusive(value)) = self;
584        value
585    }
586}
587
588/// An [`Access`] that has been filtered to include and exclude certain combinations of elements.
589///
590/// Used internally to statically check if queries are disjoint.
591///
592/// Subtle: a `read` or `write` in `access` should not be considered to imply a
593/// `with` access.
594///
595/// For example consider `Query<Option<&T>>` this only has a `read` of `T` as doing
596/// otherwise would allow for queries to be considered disjoint when they shouldn't:
597/// - `Query<(&mut T, Option<&U>)>` read/write `T`, read `U`, with `U`
598/// - `Query<&mut T, Without<U>>` read/write `T`, without `U`
599///   from this we could reasonably conclude that the queries are disjoint but they aren't.
600///
601/// In order to solve this the actual access that `Query<(&mut T, Option<&U>)>` has
602/// is read/write `T`, read `U`. It must still have a read `U` access otherwise the following
603/// queries would be incorrectly considered disjoint:
604/// - `Query<&mut T>`  read/write `T`
605/// - `Query<Option<&T>>` accesses nothing
606///
607/// See comments the [`WorldQuery`](super::WorldQuery) impls of [`AnyOf`](super::AnyOf)/`Option`/[`Or`](super::Or) for more information.
608#[derive(Debug, Eq, PartialEq)]
609pub struct FilteredAccess {
610    pub(crate) access: Access,
611    pub(crate) required: ComponentIdSet,
612    // An array of filter sets to express `With` or `Without` clauses in disjunctive normal form, for example: `Or<(With<A>, With<B>)>`.
613    // Filters like `(With<A>, Or<(With<B>, Without<C>)>` are expanded into `Or<((With<A>, With<B>), (With<A>, Without<C>))>`.
614    pub(crate) filter_sets: Vec<AccessFilters>,
615}
616
617// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
618impl Clone for FilteredAccess {
619    fn clone(&self) -> Self {
620        Self {
621            access: self.access.clone(),
622            required: self.required.clone(),
623            filter_sets: self.filter_sets.clone(),
624        }
625    }
626
627    fn clone_from(&mut self, source: &Self) {
628        self.access.clone_from(&source.access);
629        self.required.clone_from(&source.required);
630        self.filter_sets.clone_from(&source.filter_sets);
631    }
632}
633
634impl Default for FilteredAccess {
635    fn default() -> Self {
636        Self::matches_everything()
637    }
638}
639
640impl From<FilteredAccess> for FilteredAccessSet {
641    fn from(filtered_access: FilteredAccess) -> Self {
642        let mut base = FilteredAccessSet::default();
643        base.add(filtered_access);
644        base
645    }
646}
647
648/// Records how two accesses conflict with each other
649#[derive(Debug, PartialEq, Eq, From)]
650pub enum AccessConflicts {
651    /// Conflict is for all indices
652    All,
653    /// There is a conflict for a subset of indices
654    Individual(ComponentIdSet),
655}
656
657impl AccessConflicts {
658    fn add(&mut self, other: &Self) {
659        match (self, other) {
660            (s, AccessConflicts::All) => {
661                *s = AccessConflicts::All;
662            }
663            (AccessConflicts::Individual(this), AccessConflicts::Individual(other)) => {
664                this.extend(other);
665            }
666            _ => {}
667        }
668    }
669
670    /// Returns true if there are no conflicts present
671    pub fn is_empty(&self) -> bool {
672        match self {
673            Self::All => false,
674            Self::Individual(set) => set.is_clear(),
675        }
676    }
677
678    pub(crate) fn format_conflict_list(&self, world: UnsafeWorldCell) -> String {
679        match self {
680            AccessConflicts::All => String::new(),
681            AccessConflicts::Individual(indices) => indices
682                .iter()
683                .map(|index| {
684                    format!(
685                        "{}",
686                        world.components().get_name(index).unwrap().shortname()
687                    )
688                })
689                .collect::<Vec<_>>()
690                .join(", "),
691        }
692    }
693
694    /// An [`AccessConflicts`] which represents the absence of any conflict
695    pub(crate) fn empty() -> Self {
696        Self::Individual(ComponentIdSet::new())
697    }
698}
699
700impl From<Vec<ComponentId>> for AccessConflicts {
701    fn from(value: Vec<ComponentId>) -> Self {
702        Self::Individual(value.into_iter().collect())
703    }
704}
705
706impl FilteredAccess {
707    /// Returns a `FilteredAccess` which has no access and matches everything.
708    /// This is the equivalent of a `TRUE` logic atom.
709    pub fn matches_everything() -> Self {
710        Self {
711            access: Access::default(),
712            required: ComponentIdSet::default(),
713            filter_sets: vec![AccessFilters::default()],
714        }
715    }
716
717    /// Returns a `FilteredAccess` which has no access and matches nothing.
718    /// This is the equivalent of a `FALSE` logic atom.
719    pub fn matches_nothing() -> Self {
720        Self {
721            access: Access::default(),
722            required: ComponentIdSet::default(),
723            filter_sets: Vec::new(),
724        }
725    }
726
727    /// Returns a reference to the underlying unfiltered access.
728    #[inline]
729    pub fn access(&self) -> &Access {
730        &self.access
731    }
732
733    /// Returns a mutable reference to the underlying unfiltered access.
734    #[inline]
735    pub fn access_mut(&mut self) -> &mut Access {
736        &mut self.access
737    }
738
739    /// Adds access to the component given by `index`.
740    pub fn add_read(&mut self, index: ComponentId) {
741        self.access.add_read(index);
742        self.add_required(index);
743        self.and_with(index);
744    }
745
746    /// Adds exclusive access to the component given by `index`.
747    pub fn add_write(&mut self, index: ComponentId) {
748        self.access.add_write(index);
749        self.add_required(index);
750        self.and_with(index);
751    }
752
753    fn add_required(&mut self, index: ComponentId) {
754        self.required.insert(index);
755    }
756
757    /// Adds a `With` filter: corresponds to a conjunction (AND) operation.
758    ///
759    /// Suppose we begin with `Or<(With<A>, With<B>)>`, which is represented by an array of two `AccessFilter` instances.
760    /// Adding `AND With<C>` via this method transforms it into the equivalent of  `Or<((With<A>, With<C>), (With<B>, With<C>))>`.
761    pub fn and_with(&mut self, index: ComponentId) {
762        for filter in &mut self.filter_sets {
763            filter.with.insert(index);
764        }
765    }
766
767    /// Adds a `Without` filter: corresponds to a conjunction (AND) operation.
768    ///
769    /// Suppose we begin with `Or<(With<A>, With<B>)>`, which is represented by an array of two `AccessFilter` instances.
770    /// Adding `AND Without<C>` via this method transforms it into the equivalent of  `Or<((With<A>, Without<C>), (With<B>, Without<C>))>`.
771    pub fn and_without(&mut self, index: ComponentId) {
772        for filter in &mut self.filter_sets {
773            filter.without.insert(index);
774        }
775    }
776
777    /// Appends an array of filters: corresponds to a disjunction (OR) operation.
778    ///
779    /// As the underlying array of filters represents a disjunction,
780    /// where each element (`AccessFilters`) represents a conjunction,
781    /// we can simply append to the array.
782    pub fn append_or(&mut self, other: &FilteredAccess) {
783        self.filter_sets.append(&mut other.filter_sets.clone());
784    }
785
786    /// Adds all of the accesses from `other` to `self`.
787    pub fn extend_access(&mut self, other: &FilteredAccess) {
788        self.access.extend(&other.access);
789    }
790
791    /// Returns `true` if this and `other` can be active at the same time.
792    pub fn is_compatible(&self, other: &FilteredAccess) -> bool {
793        if self.access.is_compatible(&other.access) {
794            return true;
795        }
796
797        // If the access instances are incompatible, we want to check that whether filters can
798        // guarantee that queries are disjoint.
799        // Since the `filter_sets` array represents a Disjunctive Normal Form formula ("ORs of ANDs"),
800        // we need to make sure that each filter set (ANDs) rule out every filter set from the `other` instance.
801        //
802        // For example, `Query<&mut C, Or<(With<A>, Without<B>)>>` is compatible `Query<&mut C, (With<B>, Without<A>)>`,
803        // but `Query<&mut C, Or<(Without<A>, Without<B>)>>` isn't compatible with `Query<&mut C, Or<(With<A>, With<B>)>>`.
804        self.filter_sets.iter().all(|filter| {
805            other
806                .filter_sets
807                .iter()
808                .all(|other_filter| filter.is_ruled_out_by(other_filter))
809        })
810    }
811
812    /// Returns a vector of elements that this and `other` cannot access at the same time.
813    pub fn get_conflicts(&self, other: &FilteredAccess) -> AccessConflicts {
814        if !self.is_compatible(other) {
815            // filters are disjoint, so we can just look at the unfiltered intersection
816            return self.access.get_conflicts(&other.access);
817        }
818        AccessConflicts::empty()
819    }
820
821    /// Adds all access and filters from `other`.
822    ///
823    /// Corresponds to a conjunction operation (AND) for filters.
824    ///
825    /// Extending `Or<(With<A>, Without<B>)>` with `Or<(With<C>, Without<D>)>` will result in
826    /// `Or<((With<A>, With<C>), (With<A>, Without<D>), (Without<B>, With<C>), (Without<B>, Without<D>))>`.
827    pub fn extend(&mut self, other: &FilteredAccess) {
828        self.access.extend(&other.access);
829        self.required.union_with(&other.required);
830
831        // We can avoid allocating a new array of bitsets if `other` contains just a single set of filters:
832        // in this case we can short-circuit by performing an in-place union for each bitset.
833        if other.filter_sets.len() == 1 {
834            for filter in &mut self.filter_sets {
835                filter.with.union_with(&other.filter_sets[0].with);
836                filter.without.union_with(&other.filter_sets[0].without);
837            }
838            return;
839        }
840
841        let mut new_filters = Vec::with_capacity(self.filter_sets.len() * other.filter_sets.len());
842        for filter in &self.filter_sets {
843            for other_filter in &other.filter_sets {
844                let mut new_filter = filter.clone();
845                new_filter.with.union_with(&other_filter.with);
846                new_filter.without.union_with(&other_filter.without);
847                new_filters.push(new_filter);
848            }
849        }
850        self.filter_sets = new_filters;
851    }
852
853    /// Sets the underlying unfiltered access as having access to all components.
854    pub fn read_all(&mut self) {
855        self.access.read_all();
856    }
857
858    /// Sets the underlying unfiltered access as having mutable access to all components.
859    pub fn write_all(&mut self) {
860        self.access.write_all();
861    }
862
863    /// Returns `true` if the set is a subset of another, i.e. `other` contains
864    /// at least all the values in `self`.
865    pub fn is_subset(&self, other: &FilteredAccess) -> bool {
866        self.required.is_subset(&other.required) && self.access().is_subset(other.access())
867    }
868
869    /// Returns the set of components that must be present for this access to match.
870    /// These components will also be included in the [`AccessFilters::with`] collection
871    /// for every filter in [`Self::filter_sets`].
872    ///
873    /// This is used by [query transmutes](crate::system::Query::transmute_lens) to ensure that
874    /// components read by the query are present.
875    /// This will include components from query types like `&C`,
876    /// but not from filters like [`With<C>`](super::With),
877    /// and not from optional data like `Option<&C>`.
878    pub fn required(&self) -> &ComponentIdSet {
879        &self.required
880    }
881
882    /// The list of filters, expressed in disjunctive normal form.
883    ///
884    /// This [`FilteredAccess`] will match an entity if
885    /// *any* of the [`AccessFilters`] matches the entity.
886    pub fn filter_sets(&self) -> &[AccessFilters] {
887        &self.filter_sets
888    }
889
890    /// Returns the indices of the elements that this access filters for.
891    pub fn with_filters(&self) -> impl Iterator<Item = ComponentId> + '_ {
892        self.filter_sets.iter().flat_map(|f| f.with.iter())
893    }
894
895    /// Returns the indices of the elements that this access filters out.
896    pub fn without_filters(&self) -> impl Iterator<Item = ComponentId> + '_ {
897        self.filter_sets.iter().flat_map(|f| f.without.iter())
898    }
899
900    /// Returns true if the index is used by this `FilteredAccess` in filters or archetypal access.
901    /// This includes most ways to access a component, but notably excludes `EntityRef` and `EntityMut`
902    /// along with anything inside `Option<T>`.
903    pub fn contains(&self, index: ComponentId) -> bool {
904        self.access().has_archetypal(index)
905            || self
906                .filter_sets
907                .iter()
908                .any(|f| f.with.contains(index) || f.without.contains(index))
909    }
910}
911
912/// A clause in disjunctive normal form that filters entities by their components.
913/// An [`AccessFilters`] matches entities that have *all* the components in the
914/// `with` filters and *none* of the components in the `without` filters.
915#[derive(Eq, PartialEq, Default, Debug)]
916pub struct AccessFilters {
917    pub(crate) with: ComponentIdSet,
918    pub(crate) without: ComponentIdSet,
919}
920
921// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
922impl Clone for AccessFilters {
923    fn clone(&self) -> Self {
924        Self {
925            with: self.with.clone(),
926            without: self.without.clone(),
927        }
928    }
929
930    fn clone_from(&mut self, source: &Self) {
931        self.with.clone_from(&source.with);
932        self.without.clone_from(&source.without);
933    }
934}
935
936impl AccessFilters {
937    /// The set of components that must all be present for this [`AccessFilters`] to match.
938    pub fn with(&self) -> &ComponentIdSet {
939        &self.with
940    }
941
942    /// The set of components that must all be absent for this [`AccessFilters`] to match.
943    pub fn without(&self) -> &ComponentIdSet {
944        &self.without
945    }
946
947    fn is_ruled_out_by(&self, other: &Self) -> bool {
948        // Although not technically complete, we don't consider the case when `AccessFilters`'s
949        // `without` bitset contradicts its own `with` bitset (e.g. `(With<A>, Without<A>)`).
950        // Such query would be considered compatible with any other query, but as it's almost
951        // always an error, we ignore this case instead of treating such query as compatible
952        // with others.
953        !self.with.is_disjoint(&other.without) || !self.without.is_disjoint(&other.with)
954    }
955}
956
957/// A collection of [`FilteredAccess`] instances.
958///
959/// Used internally to statically check if systems have conflicting access.
960///
961/// It stores multiple sets of accesses.
962/// - A "combined" set, which is the access of all filters in this set combined.
963/// - The set of access of each individual filters in this set.
964#[derive(Debug, PartialEq, Eq, Default)]
965pub struct FilteredAccessSet {
966    combined_access: Access,
967    filtered_accesses: Vec<FilteredAccess>,
968}
969
970// This is needed since `#[derive(Clone)]` does not generate optimized `clone_from`.
971impl Clone for FilteredAccessSet {
972    fn clone(&self) -> Self {
973        Self {
974            combined_access: self.combined_access.clone(),
975            filtered_accesses: self.filtered_accesses.clone(),
976        }
977    }
978
979    fn clone_from(&mut self, source: &Self) {
980        self.combined_access.clone_from(&source.combined_access);
981        self.filtered_accesses.clone_from(&source.filtered_accesses);
982    }
983}
984
985impl FilteredAccessSet {
986    /// Creates an empty [`FilteredAccessSet`].
987    pub const fn new() -> Self {
988        Self {
989            combined_access: Access::new(),
990            filtered_accesses: Vec::new(),
991        }
992    }
993
994    /// Returns a reference to the unfiltered access of the entire set.
995    #[inline]
996    pub fn combined_access(&self) -> &Access {
997        &self.combined_access
998    }
999
1000    /// Returns a reference to the filtered accesses of the set.
1001    #[inline]
1002    pub fn filtered_accesses(&self) -> &[FilteredAccess] {
1003        &self.filtered_accesses
1004    }
1005
1006    /// Returns `true` if this and `other` can be active at the same time.
1007    ///
1008    /// Access conflict resolution happen in two steps:
1009    /// 1. A "coarse" check, if there is no mutual unfiltered conflict between
1010    ///    `self` and `other`, we already know that the two access sets are
1011    ///    compatible.
1012    /// 2. A "fine grained" check, it kicks in when the "coarse" check fails.
1013    ///    the two access sets might still be compatible if some of the accesses
1014    ///    are restricted with the [`With`](super::With) or [`Without`](super::Without) filters so that access is
1015    ///    mutually exclusive. The fine grained phase iterates over all filters in
1016    ///    the `self` set and compares it to all the filters in the `other` set,
1017    ///    making sure they are all mutually compatible.
1018    pub fn is_compatible(&self, other: &FilteredAccessSet) -> bool {
1019        if self.combined_access.is_compatible(other.combined_access()) {
1020            return true;
1021        }
1022        for filtered in &self.filtered_accesses {
1023            for other_filtered in &other.filtered_accesses {
1024                if !filtered.is_compatible(other_filtered) {
1025                    return false;
1026                }
1027            }
1028        }
1029        true
1030    }
1031
1032    /// Returns a vector of elements that this set and `other` cannot access at the same time.
1033    pub fn get_conflicts(&self, other: &FilteredAccessSet) -> AccessConflicts {
1034        // if the unfiltered access is incompatible, must check each pair
1035        let mut conflicts = AccessConflicts::empty();
1036        if !self.combined_access.is_compatible(other.combined_access()) {
1037            for filtered in &self.filtered_accesses {
1038                for other_filtered in &other.filtered_accesses {
1039                    conflicts.add(&filtered.get_conflicts(other_filtered));
1040                }
1041            }
1042        }
1043        conflicts
1044    }
1045
1046    /// Returns a vector of elements that this set and `other` cannot access at the same time.
1047    pub fn get_conflicts_single(&self, filtered_access: &FilteredAccess) -> AccessConflicts {
1048        // if the unfiltered access is incompatible, must check each pair
1049        let mut conflicts = AccessConflicts::empty();
1050        if !self.combined_access.is_compatible(filtered_access.access()) {
1051            for filtered in &self.filtered_accesses {
1052                conflicts.add(&filtered.get_conflicts(filtered_access));
1053            }
1054        }
1055        conflicts
1056    }
1057
1058    /// Adds the filtered access to the set.
1059    pub fn add(&mut self, filtered_access: FilteredAccess) {
1060        self.combined_access.extend(&filtered_access.access);
1061        self.filtered_accesses.push(filtered_access);
1062    }
1063
1064    /// Adds a read access to a resource to the set.
1065    pub fn add_resource_read(&mut self, index: ComponentId) {
1066        let mut filter = FilteredAccess::default();
1067        filter.add_read(index);
1068        filter.and_with(IS_RESOURCE);
1069        self.add(filter);
1070    }
1071
1072    /// Adds a read access to a component to the set.
1073    pub fn add_unfiltered_component_read(&mut self, index: ComponentId) {
1074        let mut filter = FilteredAccess::default();
1075        filter.add_read(index);
1076        self.add(filter);
1077    }
1078
1079    /// Adds read access to all components to the set.
1080    pub fn add_unfiltered_read_all_components(&mut self) {
1081        let mut filter = FilteredAccess::default();
1082        filter.access.read_all();
1083        self.add(filter);
1084    }
1085
1086    /// Adds a write access to a resource to the set.
1087    pub fn add_resource_write(&mut self, index: ComponentId) {
1088        let mut filter = FilteredAccess::default();
1089        filter.add_write(index);
1090        filter.and_with(IS_RESOURCE);
1091        self.add(filter);
1092    }
1093
1094    /// Adds a write access to a resource to the set.
1095    pub fn add_unfiltered_component_write(&mut self, index: ComponentId) {
1096        let mut filter = FilteredAccess::default();
1097        filter.add_write(index);
1098        self.add(filter);
1099    }
1100
1101    /// Adds write access to all components to the set.
1102    pub fn add_unfiltered_write_all_components(&mut self) {
1103        let mut filter = FilteredAccess::default();
1104        filter.write_all();
1105        self.add(filter);
1106    }
1107
1108    /// Adds all of the accesses from the passed set to `self`.
1109    pub fn extend(&mut self, filtered_access_set: FilteredAccessSet) {
1110        self.combined_access
1111            .extend(&filtered_access_set.combined_access);
1112        self.filtered_accesses
1113            .extend(filtered_access_set.filtered_accesses);
1114    }
1115
1116    /// Marks the set as reading all possible indices of type T.
1117    pub fn read_all(&mut self) {
1118        let mut filter = FilteredAccess::matches_everything();
1119        filter.read_all();
1120        self.add(filter);
1121    }
1122
1123    /// Marks the set as writing all T.
1124    pub fn write_all(&mut self) {
1125        let mut filter = FilteredAccess::matches_everything();
1126        filter.write_all();
1127        self.add(filter);
1128    }
1129
1130    /// Removes all accesses stored in this set.
1131    pub fn clear(&mut self) {
1132        self.combined_access.clear();
1133        self.filtered_accesses.clear();
1134    }
1135}
1136
1137/// A set of [`ComponentId`]s.
1138#[derive(Default, Eq)]
1139#[repr(transparent)]
1140pub struct ComponentIdSet(FixedBitSet);
1141
1142impl PartialEq for ComponentIdSet {
1143    fn eq(&self, other: &Self) -> bool {
1144        // `FixedBitSet` requires equal lengths for equality,
1145        // but we consider two sets equal if they have the same bits set
1146        self.0.symmetric_difference(&other.0).next().is_none()
1147    }
1148}
1149
1150impl ComponentIdSet {
1151    /// Create a new empty `ComponentIdSet`.
1152    #[inline]
1153    pub const fn new() -> Self {
1154        Self(FixedBitSet::new())
1155    }
1156
1157    #[cfg(test)]
1158    pub(crate) fn from_bits(bits: FixedBitSet) -> Self {
1159        Self(bits)
1160    }
1161
1162    /// Adds a [`ComponentId`] to the set.
1163    #[inline]
1164    pub fn insert(&mut self, index: ComponentId) {
1165        self.0.grow_and_insert(index.index());
1166    }
1167
1168    /// Removes a [`ComponentId`] from the set.
1169    #[inline]
1170    pub fn remove(&mut self, index: ComponentId) {
1171        if index.index() < self.0.len() {
1172            self.0.remove(index.index());
1173        }
1174    }
1175
1176    /// Removes all [`ComponentId`]s from the set.
1177    #[inline]
1178    pub fn clear(&mut self) {
1179        self.0.clear();
1180    }
1181
1182    /// Returns `true` if the [`ComponentId`] is in the set.
1183    #[inline]
1184    pub fn contains(&self, index: ComponentId) -> bool {
1185        self.0.contains(index.index())
1186    }
1187
1188    /// Returns `true` if `self` has no elements in common with `other`. This
1189    /// is equivalent to checking for an empty intersection.
1190    #[inline]
1191    pub fn is_disjoint(&self, other: &ComponentIdSet) -> bool {
1192        self.0.is_disjoint(&other.0)
1193    }
1194
1195    /// Returns `true` if the set is a subset of another, i.e. `other` contains
1196    /// at least all the values in `self`.
1197    #[inline]
1198    pub fn is_subset(&self, other: &ComponentIdSet) -> bool {
1199        self.0.is_subset(&other.0)
1200    }
1201
1202    /// Returns `true` if the set is empty.
1203    #[inline]
1204    pub fn is_clear(&self) -> bool {
1205        self.0.is_clear()
1206    }
1207
1208    /// Iterates the [`ComponentId`]s in the set.
1209    #[inline]
1210    pub fn iter(&self) -> ComponentIdIter<Ones<'_>> {
1211        ComponentIdIter(self.0.ones())
1212    }
1213
1214    /// Returns a lazy iterator over the union of two [`ComponentIdSet`]s.
1215    #[inline]
1216    pub fn union<'a>(&'a self, other: &'a ComponentIdSet) -> ComponentIdIter<Union<'a>> {
1217        ComponentIdIter(self.0.union(&other.0))
1218    }
1219
1220    /// Returns a lazy iterator over the intersection of two [`ComponentIdSet`]s.
1221    #[inline]
1222    pub fn intersection<'a>(
1223        &'a self,
1224        other: &'a ComponentIdSet,
1225    ) -> ComponentIdIter<Intersection<'a>> {
1226        ComponentIdIter(self.0.intersection(&other.0))
1227    }
1228
1229    /// Returns a lazy iterator over the difference of two [`ComponentIdSet`]s.
1230    #[inline]
1231    pub fn difference<'a>(&'a self, other: &'a ComponentIdSet) -> ComponentIdIter<Difference<'a>> {
1232        ComponentIdIter(self.0.difference(&other.0))
1233    }
1234
1235    /// In-place union of two [`ComponentIdSet`]s.
1236    #[inline]
1237    pub fn union_with(&mut self, other: &ComponentIdSet) {
1238        self.0.union_with(&other.0);
1239    }
1240
1241    /// In-place intersection of two [`ComponentIdSet`]s.
1242    #[inline]
1243    pub fn intersect_with(&mut self, other: &ComponentIdSet) {
1244        self.0.intersect_with(&other.0);
1245    }
1246
1247    /// In-place difference of two [`ComponentIdSet`]s.
1248    #[inline]
1249    pub fn difference_with(&mut self, other: &ComponentIdSet) {
1250        self.0.difference_with(&other.0);
1251    }
1252
1253    /// In-place reversed difference of two [`ComponentIdSet`]s.
1254    /// This sets `self` to be `other.difference(self)`.
1255    #[inline]
1256    pub fn difference_from(&mut self, other: &ComponentIdSet) {
1257        // Calculate `other - self` as `!self & other`
1258        // We have to grow here because the new bits are going to get flipped to 1.
1259        self.0.grow(other.0.len());
1260        self.0.toggle_range(..);
1261        self.0.intersect_with(&other.0);
1262    }
1263}
1264
1265impl Debug for ComponentIdSet {
1266    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1267        // `FixedBitSet` normally has a `Debug` output like:
1268        // FixedBitSet { data: [ 160 ], length: 8 }
1269        // Instead, print the list of set values, like:
1270        // [ 5, 7 ]
1271        // Don't wrap in `ComponentId`, since that would just output:
1272        // [ ComponentId(5), ComponentId(7) ]
1273        f.debug_list().entries(self.0.ones()).finish()
1274    }
1275}
1276
1277impl Clone for ComponentIdSet {
1278    #[inline]
1279    fn clone(&self) -> Self {
1280        Self(self.0.clone())
1281    }
1282
1283    #[inline]
1284    fn clone_from(&mut self, source: &Self) {
1285        self.0.clone_from(&source.0);
1286    }
1287}
1288
1289impl IntoIterator for ComponentIdSet {
1290    type Item = ComponentId;
1291
1292    type IntoIter = ComponentIdIter<IntoOnes>;
1293
1294    #[inline]
1295    fn into_iter(self) -> Self::IntoIter {
1296        ComponentIdIter(self.0.into_ones())
1297    }
1298}
1299
1300impl<'a> IntoIterator for &'a ComponentIdSet {
1301    type Item = ComponentId;
1302
1303    type IntoIter = ComponentIdIter<Ones<'a>>;
1304
1305    #[inline]
1306    fn into_iter(self) -> Self::IntoIter {
1307        self.iter()
1308    }
1309}
1310
1311impl FromIterator<ComponentId> for ComponentIdSet {
1312    #[inline]
1313    fn from_iter<T: IntoIterator<Item = ComponentId>>(iter: T) -> Self {
1314        Self(FixedBitSet::from_iter(
1315            iter.into_iter().map(ComponentId::index),
1316        ))
1317    }
1318}
1319
1320impl Extend<ComponentId> for ComponentIdSet {
1321    #[inline]
1322    fn extend<T: IntoIterator<Item = ComponentId>>(&mut self, iter: T) {
1323        self.0.extend(iter.into_iter().map(ComponentId::index));
1324    }
1325}
1326
1327/// An iterator of [`ComponentId`]s.
1328///
1329/// This is equivalent to `map(ComponentId::new)`,
1330/// but is a named type to allow it to be used in associated types.
1331#[repr(transparent)]
1332pub struct ComponentIdIter<I>(I);
1333
1334impl<I: Iterator<Item = usize>> Iterator for ComponentIdIter<I> {
1335    type Item = ComponentId;
1336
1337    #[inline]
1338    fn next(&mut self) -> Option<Self::Item> {
1339        self.0.next().map(ComponentId::new)
1340    }
1341
1342    #[inline]
1343    fn size_hint(&self) -> (usize, Option<usize>) {
1344        self.0.size_hint()
1345    }
1346}
1347
1348impl<I: DoubleEndedIterator<Item = usize>> DoubleEndedIterator for ComponentIdIter<I> {
1349    #[inline]
1350    fn next_back(&mut self) -> Option<Self::Item> {
1351        self.0.next_back().map(ComponentId::new)
1352    }
1353}
1354
1355impl<I: FusedIterator<Item = usize>> FusedIterator for ComponentIdIter<I> {}
1356
1357#[cfg(test)]
1358mod tests {
1359    use crate::{
1360        component::ComponentIds,
1361        query::{
1362            access::{AccessFilters, InvertibleComponentIdSet},
1363            Access, AccessConflicts, ComponentAccessKind, ComponentIdSet, FilteredAccess,
1364            FilteredAccessSet, UnboundedAccessError,
1365        },
1366    };
1367    use alloc::{vec, vec::Vec};
1368    use fixedbitset::FixedBitSet;
1369
1370    #[test]
1371    fn test_access_clone() {
1372        let mut ids = ComponentIds::default();
1373        let id_1 = ids.next_mut();
1374        let id_2 = ids.next_mut();
1375        let id_3 = ids.next_mut();
1376        let id_5 = ids.next_mut();
1377
1378        let mut original = Access::default();
1379        original.add_read(id_1);
1380        original.add_read(id_2);
1381        original.add_write(id_3);
1382        original.add_archetypal(id_5);
1383        original.read_all();
1384
1385        let cloned = original.clone();
1386
1387        assert_eq!(original, cloned);
1388    }
1389
1390    #[test]
1391    fn test_access_clone_from() {
1392        let mut ids = ComponentIds::default();
1393        let id_1 = ids.next_mut();
1394        let id_2 = ids.next_mut();
1395        let id_3 = ids.next_mut();
1396        let id_4 = ids.next_mut();
1397        let id_5 = ids.next_mut();
1398        let id_7 = ids.next_mut();
1399        let id_8 = ids.next_mut();
1400
1401        let mut original = Access::default();
1402        original.add_read(id_1);
1403        original.add_read(id_2);
1404        original.add_write(id_3);
1405        original.add_archetypal(id_5);
1406        original.read_all();
1407
1408        let mut cloned = Access::default();
1409
1410        cloned.add_write(id_7);
1411        cloned.add_read(id_4);
1412        cloned.add_archetypal(id_8);
1413        cloned.write_all();
1414
1415        cloned.clone_from(&original);
1416
1417        assert_eq!(original, cloned);
1418    }
1419
1420    #[test]
1421    fn test_filtered_access_clone() {
1422        let mut ids = ComponentIds::default();
1423        let id_1 = ids.next_mut();
1424        let id_2 = ids.next_mut();
1425        let id_3 = ids.next_mut();
1426        let id_4 = ids.next_mut();
1427
1428        let mut original = FilteredAccess::default();
1429        original.add_write(id_1);
1430        original.add_read(id_2);
1431        original.add_required(id_3);
1432        original.and_with(id_4);
1433
1434        let cloned = original.clone();
1435
1436        assert_eq!(original, cloned);
1437    }
1438
1439    #[test]
1440    fn test_filtered_access_clone_from() {
1441        let mut ids = ComponentIds::default();
1442        let id_1 = ids.next_mut();
1443        let id_2 = ids.next_mut();
1444        let id_3 = ids.next_mut();
1445        let id_4 = ids.next_mut();
1446        let id_7 = ids.next_mut();
1447
1448        let mut original = FilteredAccess::default();
1449        original.add_write(id_1);
1450        original.add_read(id_2);
1451        original.add_required(id_3);
1452        original.and_with(id_4);
1453
1454        let mut cloned = FilteredAccess::default();
1455
1456        cloned.add_write(id_7);
1457        cloned.add_read(id_4);
1458        cloned.append_or(&FilteredAccess::default());
1459
1460        cloned.clone_from(&original);
1461
1462        assert_eq!(original, cloned);
1463    }
1464
1465    #[test]
1466    fn test_access_filters_clone() {
1467        let mut ids = ComponentIds::default();
1468        let id_3 = ids.next_mut();
1469        let id_5 = ids.next_mut();
1470
1471        let mut original = AccessFilters::default();
1472        original.with.insert(id_3);
1473        original.without.insert(id_5);
1474
1475        let cloned = original.clone();
1476
1477        assert_eq!(original, cloned);
1478    }
1479
1480    #[test]
1481    fn test_access_filters_clone_from() {
1482        let mut ids = ComponentIds::default();
1483        let id_1 = ids.next_mut();
1484        let id_2 = ids.next_mut();
1485        let id_3 = ids.next_mut();
1486        let id_5 = ids.next_mut();
1487
1488        let mut original = AccessFilters::default();
1489        original.with.insert(id_3);
1490        original.without.insert(id_5);
1491
1492        let mut cloned = AccessFilters::default();
1493
1494        cloned.with.insert(id_1);
1495        cloned.without.insert(id_2);
1496
1497        cloned.clone_from(&original);
1498
1499        assert_eq!(original, cloned);
1500    }
1501
1502    #[test]
1503    fn test_filtered_access_set_clone() {
1504        let mut ids = ComponentIds::default();
1505        let id_2 = ids.next_mut();
1506        let id_4 = ids.next_mut();
1507
1508        let mut original = FilteredAccessSet::default();
1509        original.add_unfiltered_component_read(id_2);
1510        original.add_unfiltered_component_write(id_4);
1511        original.read_all();
1512
1513        let cloned = original.clone();
1514
1515        assert_eq!(original, cloned);
1516    }
1517
1518    #[test]
1519    fn test_filtered_access_set_from() {
1520        let mut ids = ComponentIds::default();
1521        let id_2 = ids.next_mut();
1522        let id_4 = ids.next_mut();
1523        let id_7 = ids.next_mut();
1524        let id_9 = ids.next_mut();
1525
1526        let mut original = FilteredAccessSet::default();
1527        original.add_unfiltered_component_read(id_2);
1528        original.add_unfiltered_component_write(id_4);
1529        original.read_all();
1530
1531        let mut cloned = FilteredAccessSet::default();
1532
1533        cloned.add_unfiltered_component_read(id_7);
1534        cloned.add_unfiltered_component_write(id_9);
1535        cloned.write_all();
1536
1537        cloned.clone_from(&original);
1538
1539        assert_eq!(original, cloned);
1540    }
1541
1542    #[test]
1543    fn read_all_access_conflicts() {
1544        let mut ids = ComponentIds::default();
1545        let id_0 = ids.next_mut();
1546
1547        // read_all / single write
1548        let mut access_a = Access::default();
1549        access_a.add_write(id_0);
1550
1551        let mut access_b = Access::default();
1552        access_b.read_all();
1553
1554        assert!(!access_b.is_compatible(&access_a));
1555
1556        // read_all / read_all
1557        let mut access_a = Access::default();
1558        access_a.read_all();
1559
1560        let mut access_b = Access::default();
1561        access_b.read_all();
1562
1563        assert!(access_b.is_compatible(&access_a));
1564    }
1565
1566    #[test]
1567    fn access_get_conflicts() {
1568        let mut ids = ComponentIds::default();
1569        let id_0 = ids.next_mut();
1570        let id_1 = ids.next_mut();
1571
1572        let mut access_a = Access::default();
1573        access_a.add_read(id_0);
1574        access_a.add_read(id_1);
1575
1576        let mut access_b = Access::default();
1577        access_b.add_read(id_0);
1578        access_b.add_write(id_1);
1579
1580        assert_eq!(access_a.get_conflicts(&access_b), vec![id_1].into());
1581
1582        let mut access_c = Access::default();
1583        access_c.add_write(id_0);
1584        access_c.add_write(id_1);
1585
1586        assert_eq!(access_a.get_conflicts(&access_c), vec![id_0, id_1].into());
1587        assert_eq!(access_b.get_conflicts(&access_c), vec![id_0, id_1].into());
1588
1589        let mut access_d = Access::default();
1590        access_d.add_read(id_0);
1591
1592        assert_eq!(access_d.get_conflicts(&access_a), AccessConflicts::empty());
1593        assert_eq!(access_d.get_conflicts(&access_b), AccessConflicts::empty());
1594        assert_eq!(access_d.get_conflicts(&access_c), vec![id_0].into());
1595    }
1596
1597    #[test]
1598    fn filtered_combined_access() {
1599        let mut ids = ComponentIds::default();
1600        let id_1 = ids.next_mut();
1601
1602        let mut access_a = FilteredAccessSet::default();
1603        access_a.add_unfiltered_component_read(id_1);
1604
1605        let mut filter_b = FilteredAccess::default();
1606        filter_b.add_write(id_1);
1607
1608        let conflicts = access_a.get_conflicts_single(&filter_b);
1609        assert_eq!(
1610            &conflicts,
1611            &AccessConflicts::from(vec![id_1]),
1612            "access_a: {access_a:?}, filter_b: {filter_b:?}"
1613        );
1614    }
1615
1616    #[test]
1617    fn filtered_access_extend() {
1618        let mut ids = ComponentIds::default();
1619        let id_0 = ids.next_mut();
1620        let id_1 = ids.next_mut();
1621        let id_2 = ids.next_mut();
1622        let id_3 = ids.next_mut();
1623        let id_4 = ids.next_mut();
1624
1625        let mut access_a = FilteredAccess::default();
1626        access_a.add_read(id_0);
1627        access_a.add_read(id_1);
1628        access_a.and_with(id_2);
1629
1630        let mut access_b = FilteredAccess::default();
1631        access_b.add_read(id_0);
1632        access_b.add_write(id_3);
1633        access_b.and_without(id_4);
1634
1635        access_a.extend(&access_b);
1636
1637        let mut expected = FilteredAccess::default();
1638        expected.add_read(id_0);
1639        expected.add_read(id_1);
1640        expected.and_with(id_2);
1641        expected.add_write(id_3);
1642        expected.and_without(id_4);
1643
1644        assert!(access_a.eq(&expected));
1645    }
1646
1647    #[test]
1648    fn filtered_access_extend_or() {
1649        let mut ids = ComponentIds::default();
1650        let id_0 = ids.next_mut();
1651        let id_1 = ids.next_mut();
1652        let id_2 = ids.next_mut();
1653        let id_3 = ids.next_mut();
1654        let id_4 = ids.next_mut();
1655
1656        let mut access_a = FilteredAccess::default();
1657        // Exclusive access to `(&mut A, &mut B)`.
1658        access_a.add_write(id_0);
1659        access_a.add_write(id_1);
1660
1661        // Filter by `With<C>`.
1662        let mut access_b = FilteredAccess::default();
1663        access_b.and_with(id_2);
1664
1665        // Filter by `(With<D>, Without<E>)`.
1666        let mut access_c = FilteredAccess::default();
1667        access_c.and_with(id_3);
1668        access_c.and_without(id_4);
1669
1670        // Turns `access_b` into `Or<(With<C>, (With<D>, Without<D>))>`.
1671        access_b.append_or(&access_c);
1672        // Applies the filters to the initial query, which corresponds to the FilteredAccess'
1673        // representation of `Query<(&mut A, &mut B), Or<(With<C>, (With<D>, Without<E>))>>`.
1674        access_a.extend(&access_b);
1675
1676        // Construct the expected `FilteredAccess` struct.
1677        // The intention here is to test that exclusive access implied by `add_write`
1678        // forms correct normalized access structs when extended with `Or` filters.
1679        let mut expected = FilteredAccess::default();
1680        expected.add_write(id_0);
1681        expected.add_write(id_1);
1682        // The resulted access is expected to represent `Or<((With<A>, With<B>, With<C>), (With<A>, With<B>, With<D>, Without<E>))>`.
1683        expected.filter_sets = vec![
1684            AccessFilters {
1685                with: ComponentIdSet::from_bits(FixedBitSet::with_capacity_and_blocks(3, [0b111])),
1686                without: ComponentIdSet::default(),
1687            },
1688            AccessFilters {
1689                with: ComponentIdSet::from_bits(FixedBitSet::with_capacity_and_blocks(4, [0b1011])),
1690                without: ComponentIdSet::from_bits(FixedBitSet::with_capacity_and_blocks(
1691                    5,
1692                    [0b10000],
1693                )),
1694            },
1695        ];
1696
1697        assert_eq!(access_a, expected);
1698    }
1699
1700    #[test]
1701    fn try_iter_component_access_simple() {
1702        let mut ids = ComponentIds::default();
1703        let id_1 = ids.next_mut();
1704        let id_2 = ids.next_mut();
1705        let id_3 = ids.next_mut();
1706        let id_5 = ids.next_mut();
1707
1708        let mut access = Access::default();
1709
1710        access.add_read(id_1);
1711        access.add_read(id_2);
1712        access.add_write(id_3);
1713        access.add_archetypal(id_5);
1714
1715        let result = access.try_iter_access().map(Iterator::collect::<Vec<_>>);
1716
1717        assert_eq!(
1718            result,
1719            Ok(vec![
1720                ComponentAccessKind::Shared(id_1),
1721                ComponentAccessKind::Shared(id_2),
1722                ComponentAccessKind::Exclusive(id_3),
1723                ComponentAccessKind::Archetypal(id_5),
1724            ]),
1725        );
1726    }
1727
1728    #[test]
1729    fn try_iter_component_access_unbounded_write_all() {
1730        let mut ids = ComponentIds::default();
1731        let id_1 = ids.next_mut();
1732        let id_2 = ids.next_mut();
1733
1734        let mut access = Access::default();
1735
1736        access.add_read(id_1);
1737        access.add_read(id_2);
1738        access.write_all();
1739
1740        let result = access.try_iter_access().map(Iterator::collect::<Vec<_>>);
1741
1742        assert_eq!(
1743            result,
1744            Err(UnboundedAccessError {
1745                writes_inverted: true,
1746                reads_inverted: true
1747            }),
1748        );
1749    }
1750
1751    #[test]
1752    fn try_iter_component_access_unbounded_read_all() {
1753        let mut ids = ComponentIds::default();
1754        let id_1 = ids.next_mut();
1755        let id_2 = ids.next_mut();
1756
1757        let mut access = Access::default();
1758
1759        access.add_read(id_1);
1760        access.add_read(id_2);
1761        access.read_all();
1762
1763        let result = access.try_iter_access().map(Iterator::collect::<Vec<_>>);
1764
1765        assert_eq!(
1766            result,
1767            Err(UnboundedAccessError {
1768                writes_inverted: false,
1769                reads_inverted: true
1770            }),
1771        );
1772    }
1773
1774    /// Create a `ComponentIdSet` with a given number of total bits and a given list of bits to set.
1775    /// Setting the number of bits is important in tests since the `PartialEq` impl checks that the length matches.
1776    fn bit_set(bits: usize, iter: impl IntoIterator<Item = usize>) -> ComponentIdSet {
1777        let mut result = FixedBitSet::with_capacity(bits);
1778        result.extend(iter);
1779        ComponentIdSet::from_bits(result)
1780    }
1781
1782    #[test]
1783    fn invertible_union_tests() {
1784        let mut ids = ComponentIds::default();
1785        let id_0 = ids.next_mut();
1786        let id_1 = ids.next_mut();
1787        let id_2 = ids.next_mut();
1788
1789        let set0 = ComponentIdSet::from_iter([id_0]);
1790        let set1 = ComponentIdSet::from_iter([id_1]);
1791        let set2 = ComponentIdSet::from_iter([id_2]);
1792        let set01 = ComponentIdSet::from_iter([id_0, id_1]);
1793        let set02 = ComponentIdSet::from_iter([id_0, id_2]);
1794        let set012 = ComponentIdSet::from_iter([id_0, id_1, id_2]);
1795
1796        // Check each combination of `Included` and `Excluded`
1797        // [0, 1] | [0, 2] = [0, 1, 2]
1798        assert_eq!(
1799            InvertibleComponentIdSet::Included(set01.clone())
1800                .union(&InvertibleComponentIdSet::Included(set02.clone())),
1801            InvertibleComponentIdSet::Included(set012.clone())
1802        );
1803        // [0, 1] | [1, 3, ...] = [0, 1, 3, ...]
1804        assert_eq!(
1805            InvertibleComponentIdSet::Included(set01.clone())
1806                .union(&InvertibleComponentIdSet::Excluded(set02.clone())),
1807            InvertibleComponentIdSet::Excluded(set2.clone())
1808        );
1809
1810        // [2, 3, ...] | [0, 2] = [0, 2, 3, ...]
1811        assert_eq!(
1812            InvertibleComponentIdSet::Excluded(set01.clone())
1813                .union(&InvertibleComponentIdSet::Included(set02.clone())),
1814            InvertibleComponentIdSet::Excluded(set1.clone())
1815        );
1816
1817        // [2, 3, ...] | [1, 3, ...] = [1, 2, 3, ...]
1818        assert_eq!(
1819            InvertibleComponentIdSet::Excluded(set01.clone())
1820                .union(&InvertibleComponentIdSet::Excluded(set02.clone())),
1821            InvertibleComponentIdSet::Excluded(set0.clone())
1822        );
1823    }
1824
1825    #[test]
1826    fn invertible_union_with_different_lengths() {
1827        // When adding a large inverted set to a small normal set,
1828        // make sure we invert the bits beyond the original length.
1829        // Failing to call `grow` before `toggle_range` would cause bit 1 to be zero,
1830        // which would incorrectly treat it as included in the output set.
1831        let mut self_set = InvertibleComponentIdSet::Included(bit_set(1, [0]));
1832        let other_set = InvertibleComponentIdSet::Excluded(bit_set(3, [0, 1]));
1833        self_set.union_with(&other_set);
1834
1835        // [0] | [2, ...] = [0, 2, ...]
1836        assert_eq!(
1837            self_set,
1838            InvertibleComponentIdSet::Excluded(bit_set(3, [1]))
1839        );
1840    }
1841
1842    #[test]
1843    fn invertible_difference_tests() {
1844        let mut ids = ComponentIds::default();
1845        let id_0 = ids.next_mut();
1846        let id_1 = ids.next_mut();
1847        let id_2 = ids.next_mut();
1848
1849        let set0 = ComponentIdSet::from_iter([id_0]);
1850        let set1 = ComponentIdSet::from_iter([id_1]);
1851        let set2 = ComponentIdSet::from_iter([id_2]);
1852        let set01 = ComponentIdSet::from_iter([id_0, id_1]);
1853        let set02 = ComponentIdSet::from_iter([id_0, id_2]);
1854        let set012 = ComponentIdSet::from_iter([id_0, id_1, id_2]);
1855
1856        // Check each combination of `Included` and `Excluded`
1857        // [0, 1] - [0, 2] = [1]
1858        assert_eq!(
1859            InvertibleComponentIdSet::Included(set01.clone())
1860                .difference(&InvertibleComponentIdSet::Included(set02.clone())),
1861            InvertibleComponentIdSet::Included(set1.clone())
1862        );
1863        // [0, 1] - [1, 3, ...] = [0]
1864        assert_eq!(
1865            InvertibleComponentIdSet::Included(set01.clone())
1866                .difference(&InvertibleComponentIdSet::Excluded(set02.clone())),
1867            InvertibleComponentIdSet::Included(set0.clone())
1868        );
1869
1870        // [2, 3, ...] - [0, 2] = [3, ...]
1871        assert_eq!(
1872            InvertibleComponentIdSet::Excluded(set01.clone())
1873                .difference(&InvertibleComponentIdSet::Included(set02.clone())),
1874            InvertibleComponentIdSet::Excluded(set012.clone())
1875        );
1876
1877        // [2, 3, ...] - [1, 3, ...] = [2]
1878        assert_eq!(
1879            InvertibleComponentIdSet::Excluded(set01.clone())
1880                .difference(&InvertibleComponentIdSet::Excluded(set02.clone())),
1881            InvertibleComponentIdSet::Included(set2.clone())
1882        );
1883    }
1884
1885    #[test]
1886    fn invertible_intersection_tests() {
1887        let mut ids = ComponentIds::default();
1888        let id_0 = ids.next_mut();
1889        let id_1 = ids.next_mut();
1890        let id_2 = ids.next_mut();
1891
1892        let set0 = ComponentIdSet::from_iter([id_0]);
1893        let set1 = ComponentIdSet::from_iter([id_1]);
1894        let set2 = ComponentIdSet::from_iter([id_2]);
1895        let set01 = ComponentIdSet::from_iter([id_0, id_1]);
1896        let set02 = ComponentIdSet::from_iter([id_0, id_2]);
1897        let set012 = ComponentIdSet::from_iter([id_0, id_1, id_2]);
1898
1899        // Check each combination of `Included` and `Excluded`
1900        // [0, 1] & [0, 2] = [0]
1901        assert_eq!(
1902            InvertibleComponentIdSet::Included(set01.clone())
1903                .intersection(&InvertibleComponentIdSet::Included(set02.clone())),
1904            InvertibleComponentIdSet::Included(set0.clone())
1905        );
1906        // [0, 1] & [1, 3, ...] = [1]
1907        assert_eq!(
1908            InvertibleComponentIdSet::Included(set01.clone())
1909                .intersection(&InvertibleComponentIdSet::Excluded(set02.clone())),
1910            InvertibleComponentIdSet::Included(set1.clone())
1911        );
1912
1913        // [2, 3, ...] & [0, 2] = [2]
1914        assert_eq!(
1915            InvertibleComponentIdSet::Excluded(set01.clone())
1916                .intersection(&InvertibleComponentIdSet::Included(set02.clone())),
1917            InvertibleComponentIdSet::Included(set2.clone())
1918        );
1919
1920        // [2, 3, ...] & [1, 3, ...] = [3, ...]
1921        assert_eq!(
1922            InvertibleComponentIdSet::Excluded(set01.clone())
1923                .intersection(&InvertibleComponentIdSet::Excluded(set02.clone())),
1924            InvertibleComponentIdSet::Excluded(set012.clone())
1925        );
1926    }
1927
1928    #[test]
1929    fn component_id_set_insert_remove_clear() {
1930        let mut ids = ComponentIds::default();
1931        let id_0 = ids.next_mut();
1932        let id_1 = ids.next_mut();
1933        let id_2 = ids.next_mut();
1934
1935        let mut set = ComponentIdSet::new();
1936        assert!(!set.contains(id_0));
1937        assert!(!set.contains(id_1));
1938        assert!(!set.contains(id_2));
1939        assert!(set.is_clear());
1940        set.insert(id_2);
1941        set.insert(id_1);
1942        assert!(!set.contains(id_0));
1943        assert!(set.contains(id_1));
1944        assert!(set.contains(id_2));
1945        assert!(!set.is_clear());
1946        set.remove(id_1);
1947        assert!(!set.contains(id_0));
1948        assert!(!set.contains(id_1));
1949        assert!(set.contains(id_2));
1950        assert!(!set.is_clear());
1951        set.insert(id_2);
1952        set.insert(id_1);
1953        assert!(!set.contains(id_0));
1954        assert!(set.contains(id_1));
1955        assert!(set.contains(id_2));
1956        assert!(!set.is_clear());
1957        set.clear();
1958        assert!(!set.contains(id_0));
1959        assert!(!set.contains(id_1));
1960        assert!(!set.contains(id_2));
1961        assert!(set.is_clear());
1962    }
1963
1964    #[test]
1965    fn component_id_set_remove_out_of_range() {
1966        let mut ids = ComponentIds::default();
1967        let id_1 = ids.next_mut();
1968        let id_3 = ids.next_mut();
1969        let id_4 = ids.next_mut();
1970
1971        let mut set = ComponentIdSet::new();
1972        set.remove(id_3);
1973        set.insert(id_1);
1974        set.remove(id_4);
1975        assert!(set.iter().eq([id_1]));
1976    }
1977
1978    #[test]
1979    fn component_id_set_is_subset_is_disjoint() {
1980        let mut ids = ComponentIds::default();
1981        let id_1 = ids.next_mut();
1982        let id_2 = ids.next_mut();
1983        let id_3 = ids.next_mut();
1984        let id_4 = ids.next_mut();
1985        let id_5 = ids.next_mut();
1986
1987        let set_1234 = ComponentIdSet::from_iter([id_1, id_2, id_3, id_4]);
1988        let set_23 = ComponentIdSet::from_iter([id_2, id_3]);
1989        let set_45 = ComponentIdSet::from_iter([id_4, id_5]);
1990        assert!(set_23.is_subset(&set_1234));
1991        assert!(!set_1234.is_subset(&set_23));
1992        assert!(set_23.is_disjoint(&set_45));
1993        assert!(set_45.is_disjoint(&set_23));
1994        assert!(!set_1234.is_disjoint(&set_23));
1995        assert!(!set_23.is_disjoint(&set_1234));
1996    }
1997
1998    #[test]
1999    fn component_id_set_union_intersection_difference() {
2000        let mut ids = ComponentIds::default();
2001        let id_1 = ids.next_mut();
2002        let id_2 = ids.next_mut();
2003        let id_3 = ids.next_mut();
2004
2005        let set_13 = ComponentIdSet::from_iter([id_1, id_3]);
2006        let set_23 = ComponentIdSet::from_iter([id_2, id_3]);
2007
2008        assert!(set_13.union(&set_23).eq([id_1, id_3, id_2]));
2009        assert!(set_23.union(&set_13).eq([id_2, id_3, id_1]));
2010        assert!(set_13.intersection(&set_23).eq([id_3]));
2011        assert!(set_23.intersection(&set_13).eq([id_3]));
2012        assert!(set_13.difference(&set_23).eq([id_1]));
2013        assert!(set_23.difference(&set_13).eq([id_2]));
2014    }
2015
2016    #[test]
2017    fn component_id_set_union_intersection_difference_with() {
2018        let mut ids = ComponentIds::default();
2019        let id_1 = ids.next_mut();
2020        let id_2 = ids.next_mut();
2021        let id_3 = ids.next_mut();
2022
2023        let set_13 = ComponentIdSet::from_iter([id_1, id_3]);
2024        let set_23 = ComponentIdSet::from_iter([id_2, id_3]);
2025
2026        let mut s = set_13.clone();
2027        s.union_with(&set_23);
2028        assert!(s.iter().eq([id_1, id_2, id_3]));
2029
2030        let mut s = set_23.clone();
2031        s.union_with(&set_13);
2032        assert!(s.iter().eq([id_1, id_2, id_3]));
2033
2034        let mut s = set_13.clone();
2035        s.intersect_with(&set_23);
2036        assert!(s.iter().eq([id_3]));
2037
2038        let mut s = set_23.clone();
2039        s.intersect_with(&set_13);
2040        assert!(s.iter().eq([id_3]));
2041
2042        let mut s = set_13.clone();
2043        s.difference_with(&set_23);
2044        assert!(s.iter().eq([id_1]));
2045
2046        let mut s = set_23.clone();
2047        s.difference_with(&set_13);
2048        assert!(s.iter().eq([id_2]));
2049
2050        let mut s = set_13.clone();
2051        s.difference_from(&set_23);
2052        assert!(s.iter().eq([id_2]));
2053
2054        let mut s = set_23.clone();
2055        s.difference_from(&set_13);
2056        assert!(s.iter().eq([id_1]));
2057    }
2058}