specs/
bitset.rs

1//! Implementations and structures related to bitsets.
2//!
3//! Normally used for `Join`s and filtering entities.
4
5#![cfg_attr(rustfmt, rustfmt::skip)]
6
7use hibitset::{AtomicBitSet, BitSet, BitSetAnd, BitSetLike, BitSetNot, BitSetOr, BitSetXor};
8
9#[nougat::gat(Type)]
10use crate::join::LendJoin;
11#[cfg(feature = "parallel")]
12use crate::join::ParJoin;
13use crate::join::{Join, RepeatableLendGet};
14use crate::world::Index;
15
16macro_rules! define_bit_join {
17    ( impl < ( $( $lifetime:tt )* ) ( $( $arg:ident ),* ) > for $bitset:ty ) => {
18        // SAFETY: `get` just returns the provided `id` (`Self::Value` is `()`
19        // and corresponds with any mask instance).
20        #[nougat::gat]
21        unsafe impl<$( $lifetime, )* $( $arg ),*> LendJoin for $bitset
22            where $( $arg: BitSetLike ),*
23        {
24            type Type<'next> = Index;
25            type Value = ();
26            type Mask = $bitset;
27
28            unsafe fn open(self) -> (Self::Mask, Self::Value) {
29                (self, ())
30            }
31
32            unsafe fn get<'next>(_: &'next mut Self::Value, id: Index) -> Self::Type<'next>
33
34            {
35                id
36            }
37        }
38
39        // SAFETY: <$biset as LendJoin>::get does not rely on only being called
40        // once with a particular ID
41        unsafe impl<$( $lifetime, )* $( $arg ),*> RepeatableLendGet for $bitset
42            where $( $arg: BitSetLike ),* {}
43
44        // SAFETY: `get` just returns the provided `id` (`Self::Value` is `()`
45        // and corresponds with any mask instance).
46        unsafe impl<$( $lifetime, )* $( $arg ),*> Join for $bitset
47            where $( $arg: BitSetLike ),*
48        {
49            type Type = Index;
50            type Value = ();
51            type Mask = $bitset;
52
53            unsafe fn open(self) -> (Self::Mask, Self::Value) {
54                (self, ())
55            }
56
57            unsafe fn get(_: &mut Self::Value, id: Index) -> Self::Type {
58                id
59            }
60        }
61
62        // SAFETY: `get` is safe to call concurrently and just returns the
63        // provided `id` (`Self::Value` is `()` and corresponds with any mask
64        // instance).
65        #[cfg(feature = "parallel")]
66        unsafe impl<$( $lifetime, )* $( $arg ),*> ParJoin for $bitset
67            where $( $arg: BitSetLike ),*
68        {
69            type Type = Index;
70            type Value = ();
71            type Mask = $bitset;
72
73            unsafe fn open(self) -> (Self::Mask, Self::Value) {
74                (self, ())
75            }
76
77            unsafe fn get(_: &Self::Value, id: Index) -> Self::Type {
78                id
79            }
80        }
81    }
82}
83
84define_bit_join!(impl<()()> for BitSet);
85define_bit_join!(impl<('a)()> for &'a BitSet);
86define_bit_join!(impl<()()> for AtomicBitSet);
87define_bit_join!(impl<('a)()> for &'a AtomicBitSet);
88define_bit_join!(impl<()(A)> for BitSetNot<A>);
89define_bit_join!(impl<('a)(A)> for &'a BitSetNot<A>);
90define_bit_join!(impl<()(A, B)> for BitSetAnd<A, B>);
91define_bit_join!(impl<('a)(A, B)> for &'a BitSetAnd<A, B>);
92define_bit_join!(impl<()(A, B)> for BitSetOr<A, B>);
93define_bit_join!(impl<('a)(A, B)> for &'a BitSetOr<A, B>);
94define_bit_join!(impl<()(A, B)> for BitSetXor<A, B>);
95define_bit_join!(impl<('a)()> for &'a dyn BitSetLike);