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