Skip to main content

glam/bool/neon/
bvec3a.rs

1// Generated from vec_mask.rs.tera template. Edit the template, not the generated file.
2
3use core::fmt;
4use core::ops::*;
5
6use core::arch::aarch64::*;
7
8#[repr(C)]
9union UnionCast {
10    a: [u32; 4],
11    v: BVec3A,
12}
13
14/// Creates a 3-dimensional `bool` vector mask.
15#[inline(always)]
16#[must_use]
17pub const fn bvec3a(x: bool, y: bool, z: bool) -> BVec3A {
18    BVec3A::new(x, y, z)
19}
20
21/// A 3-dimensional SIMD vector mask.
22///
23/// This type is 16 byte aligned.
24#[derive(Clone, Copy)]
25#[repr(transparent)]
26pub struct BVec3A(pub(crate) uint32x4_t);
27
28const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
29
30impl BVec3A {
31    /// All false.
32    pub const FALSE: Self = Self::splat(false);
33
34    /// All true.
35    pub const TRUE: Self = Self::splat(true);
36
37    /// Creates a new vector mask.
38    #[inline(always)]
39    #[must_use]
40    pub const fn new(x: bool, y: bool, z: bool) -> Self {
41        unsafe {
42            UnionCast {
43                a: [MASK[x as usize], MASK[y as usize], MASK[z as usize], 0],
44            }
45            .v
46        }
47    }
48
49    /// Creates a vector mask with all elements set to `v`.
50    #[inline]
51    #[must_use]
52    pub const fn splat(v: bool) -> Self {
53        Self::new(v, v, v)
54    }
55
56    /// Creates a new vector mask from a bool array.
57    #[inline]
58    #[must_use]
59    pub const fn from_array(a: [bool; 3]) -> Self {
60        Self::new(a[0], a[1], a[2])
61    }
62
63    /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
64    ///
65    /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
66    /// into the first lowest bit, element `y` into the second, etc.
67    #[inline]
68    #[must_use]
69    pub fn bitmask(self) -> u32 {
70        let movemask = unsafe {
71            let mma = vandq_u32(self.0, vld1q_u32([1, 2, 4, 8].as_ptr())); // [0 1 2 3]
72            let mmb = vextq_u32(mma, mma, 2); // [2 3 0 1]
73            let mmc = vorrq_u32(mma, mmb); // [0+2 1+3 0+2 1+3]
74            let mmd = vextq_u32(mmc, mmc, 3); // [1+3 0+2 1+3 0+2]
75            let mme = vorrq_u32(mmc, mmd); // [0+1+2+3 ...]
76            vgetq_lane_u32(mme, 0)
77        };
78
79        movemask & 0x7
80    }
81
82    /// Returns true if any of the elements are true, false otherwise.
83    #[inline]
84    #[must_use]
85    pub fn any(self) -> bool {
86        self.bitmask() != 0
87    }
88
89    /// Returns true if all the elements are true, false otherwise.
90    #[inline]
91    #[must_use]
92    pub fn all(self) -> bool {
93        self.bitmask() == 0x7
94    }
95
96    /// Tests the value at `index`.
97    ///
98    /// Panics if `index` is greater than 2.
99    #[inline]
100    #[must_use]
101    #[track_caller]
102    pub fn test(self, index: usize) -> bool {
103        match index {
104            0 => (self.bitmask() & (1 << 0)) != 0,
105            1 => (self.bitmask() & (1 << 1)) != 0,
106            2 => (self.bitmask() & (1 << 2)) != 0,
107            _ => panic!("index out of bounds"),
108        }
109    }
110
111    /// Sets the element at `index`.
112    ///
113    /// Panics if `index` is greater than 2.
114    #[inline]
115    #[track_caller]
116    pub fn set(&mut self, index: usize, value: bool) {
117        self.0 = match index {
118            0 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 0) },
119            1 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 1) },
120            2 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 2) },
121            _ => panic!("index out of bounds"),
122        }
123    }
124
125    #[inline]
126    #[must_use]
127    fn into_bool_array(self) -> [bool; 3] {
128        let bitmask = self.bitmask();
129        [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0]
130    }
131
132    #[inline]
133    #[must_use]
134    fn into_u32_array(self) -> [u32; 3] {
135        let bitmask = self.bitmask();
136        [
137            MASK[(bitmask & 1) as usize],
138            MASK[((bitmask >> 1) & 1) as usize],
139            MASK[((bitmask >> 2) & 1) as usize],
140        ]
141    }
142}
143
144impl Default for BVec3A {
145    #[inline]
146    fn default() -> Self {
147        Self::FALSE
148    }
149}
150
151impl PartialEq for BVec3A {
152    #[inline]
153    fn eq(&self, rhs: &Self) -> bool {
154        self.bitmask().eq(&rhs.bitmask())
155    }
156}
157
158impl Eq for BVec3A {}
159
160impl core::hash::Hash for BVec3A {
161    #[inline]
162    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
163        self.bitmask().hash(state);
164    }
165}
166
167impl BitAnd for BVec3A {
168    type Output = Self;
169    #[inline]
170    fn bitand(self, rhs: Self) -> Self {
171        Self(unsafe { vandq_u32(self.0, rhs.0) })
172    }
173}
174
175impl BitAnd<&Self> for BVec3A {
176    type Output = Self;
177    #[inline]
178    fn bitand(self, rhs: &Self) -> Self {
179        self.bitand(*rhs)
180    }
181}
182
183impl BitAnd<&BVec3A> for &BVec3A {
184    type Output = BVec3A;
185    #[inline]
186    fn bitand(self, rhs: &BVec3A) -> BVec3A {
187        (*self).bitand(*rhs)
188    }
189}
190
191impl BitAnd<BVec3A> for &BVec3A {
192    type Output = BVec3A;
193    #[inline]
194    fn bitand(self, rhs: BVec3A) -> BVec3A {
195        (*self).bitand(rhs)
196    }
197}
198
199impl BitAndAssign for BVec3A {
200    #[inline]
201    fn bitand_assign(&mut self, rhs: Self) {
202        *self = self.bitand(rhs);
203    }
204}
205
206impl BitAndAssign<&Self> for BVec3A {
207    #[inline]
208    fn bitand_assign(&mut self, rhs: &Self) {
209        self.bitand_assign(*rhs);
210    }
211}
212
213impl BitOr for BVec3A {
214    type Output = Self;
215    #[inline]
216    fn bitor(self, rhs: Self) -> Self {
217        Self(unsafe { vorrq_u32(self.0, rhs.0) })
218    }
219}
220
221impl BitOr<&Self> for BVec3A {
222    type Output = Self;
223    #[inline]
224    fn bitor(self, rhs: &Self) -> Self {
225        self.bitor(*rhs)
226    }
227}
228
229impl BitOr<&BVec3A> for &BVec3A {
230    type Output = BVec3A;
231    #[inline]
232    fn bitor(self, rhs: &BVec3A) -> BVec3A {
233        (*self).bitor(*rhs)
234    }
235}
236
237impl BitOr<BVec3A> for &BVec3A {
238    type Output = BVec3A;
239    #[inline]
240    fn bitor(self, rhs: BVec3A) -> BVec3A {
241        (*self).bitor(rhs)
242    }
243}
244
245impl BitOrAssign for BVec3A {
246    #[inline]
247    fn bitor_assign(&mut self, rhs: Self) {
248        *self = self.bitor(rhs);
249    }
250}
251
252impl BitOrAssign<&Self> for BVec3A {
253    #[inline]
254    fn bitor_assign(&mut self, rhs: &Self) {
255        self.bitor_assign(*rhs);
256    }
257}
258
259impl BitXor for BVec3A {
260    type Output = Self;
261    #[inline]
262    fn bitxor(self, rhs: Self) -> Self {
263        Self(unsafe { veorq_u32(self.0, rhs.0) })
264    }
265}
266
267impl BitXor<&Self> for BVec3A {
268    type Output = Self;
269    #[inline]
270    fn bitxor(self, rhs: &Self) -> Self {
271        self.bitxor(*rhs)
272    }
273}
274
275impl BitXor<&BVec3A> for &BVec3A {
276    type Output = BVec3A;
277    #[inline]
278    fn bitxor(self, rhs: &BVec3A) -> BVec3A {
279        (*self).bitxor(*rhs)
280    }
281}
282
283impl BitXor<BVec3A> for &BVec3A {
284    type Output = BVec3A;
285    #[inline]
286    fn bitxor(self, rhs: BVec3A) -> BVec3A {
287        (*self).bitxor(rhs)
288    }
289}
290
291impl BitXorAssign for BVec3A {
292    #[inline]
293    fn bitxor_assign(&mut self, rhs: Self) {
294        *self = self.bitxor(rhs);
295    }
296}
297
298impl BitXorAssign<&Self> for BVec3A {
299    #[inline]
300    fn bitxor_assign(&mut self, rhs: &Self) {
301        self.bitxor_assign(*rhs);
302    }
303}
304
305impl Not for BVec3A {
306    type Output = Self;
307    #[inline]
308    fn not(self) -> Self {
309        Self(unsafe { vmvnq_u32(self.0) })
310    }
311}
312
313impl Not for &BVec3A {
314    type Output = BVec3A;
315    #[inline]
316    fn not(self) -> BVec3A {
317        (*self).not()
318    }
319}
320
321impl From<BVec3A> for uint32x4_t {
322    #[inline]
323    fn from(t: BVec3A) -> Self {
324        t.0
325    }
326}
327
328impl fmt::Debug for BVec3A {
329    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330        let arr = self.into_u32_array();
331        write!(
332            f,
333            "{}({:#x}, {:#x}, {:#x})",
334            stringify!(BVec3A),
335            arr[0],
336            arr[1],
337            arr[2]
338        )
339    }
340}
341
342impl fmt::Display for BVec3A {
343    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
344        let arr = self.into_bool_array();
345        write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
346    }
347}
348
349impl From<[bool; 3]> for BVec3A {
350    #[inline]
351    fn from(a: [bool; 3]) -> Self {
352        Self::from_array(a)
353    }
354}
355
356impl From<BVec3A> for [bool; 3] {
357    #[inline]
358    fn from(mask: BVec3A) -> Self {
359        mask.into_bool_array()
360    }
361}
362
363impl From<BVec3A> for [u32; 3] {
364    #[inline]
365    fn from(mask: BVec3A) -> Self {
366        mask.into_u32_array()
367    }
368}