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