Skip to main content

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    #[track_caller]
105    pub fn test(self, index: usize) -> bool {
106        match index {
107            0 => (self.bitmask() & (1 << 0)) != 0,
108            1 => (self.bitmask() & (1 << 1)) != 0,
109            2 => (self.bitmask() & (1 << 2)) != 0,
110            3 => (self.bitmask() & (1 << 3)) != 0,
111            _ => panic!("index out of bounds"),
112        }
113    }
114
115    /// Sets the element at `index`.
116    ///
117    /// Panics if `index` is greater than 3.
118    #[inline]
119    #[track_caller]
120    pub fn set(&mut self, index: usize, value: bool) {
121        self.0 = match index {
122            0 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 0) },
123            1 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 1) },
124            2 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 2) },
125            3 => unsafe { vsetq_lane_u32(MASK[value as usize], self.0, 3) },
126            _ => panic!("index out of bounds"),
127        }
128    }
129
130    #[inline]
131    #[must_use]
132    fn into_bool_array(self) -> [bool; 4] {
133        let bitmask = self.bitmask();
134        [
135            (bitmask & 1) != 0,
136            (bitmask & 2) != 0,
137            (bitmask & 4) != 0,
138            (bitmask & 8) != 0,
139        ]
140    }
141
142    #[inline]
143    #[must_use]
144    fn into_u32_array(self) -> [u32; 4] {
145        let bitmask = self.bitmask();
146        [
147            MASK[(bitmask & 1) as usize],
148            MASK[((bitmask >> 1) & 1) as usize],
149            MASK[((bitmask >> 2) & 1) as usize],
150            MASK[((bitmask >> 3) & 1) as usize],
151        ]
152    }
153}
154
155impl Default for BVec4A {
156    #[inline]
157    fn default() -> Self {
158        Self::FALSE
159    }
160}
161
162impl PartialEq for BVec4A {
163    #[inline]
164    fn eq(&self, rhs: &Self) -> bool {
165        self.bitmask().eq(&rhs.bitmask())
166    }
167}
168
169impl Eq for BVec4A {}
170
171impl core::hash::Hash for BVec4A {
172    #[inline]
173    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
174        self.bitmask().hash(state);
175    }
176}
177
178impl BitAnd for BVec4A {
179    type Output = Self;
180    #[inline]
181    fn bitand(self, rhs: Self) -> Self {
182        Self(unsafe { vandq_u32(self.0, rhs.0) })
183    }
184}
185
186impl BitAnd<&Self> for BVec4A {
187    type Output = Self;
188    #[inline]
189    fn bitand(self, rhs: &Self) -> Self {
190        self.bitand(*rhs)
191    }
192}
193
194impl BitAnd<&BVec4A> for &BVec4A {
195    type Output = BVec4A;
196    #[inline]
197    fn bitand(self, rhs: &BVec4A) -> BVec4A {
198        (*self).bitand(*rhs)
199    }
200}
201
202impl BitAnd<BVec4A> for &BVec4A {
203    type Output = BVec4A;
204    #[inline]
205    fn bitand(self, rhs: BVec4A) -> BVec4A {
206        (*self).bitand(rhs)
207    }
208}
209
210impl BitAndAssign for BVec4A {
211    #[inline]
212    fn bitand_assign(&mut self, rhs: Self) {
213        *self = self.bitand(rhs);
214    }
215}
216
217impl BitAndAssign<&Self> for BVec4A {
218    #[inline]
219    fn bitand_assign(&mut self, rhs: &Self) {
220        self.bitand_assign(*rhs);
221    }
222}
223
224impl BitOr for BVec4A {
225    type Output = Self;
226    #[inline]
227    fn bitor(self, rhs: Self) -> Self {
228        Self(unsafe { vorrq_u32(self.0, rhs.0) })
229    }
230}
231
232impl BitOr<&Self> for BVec4A {
233    type Output = Self;
234    #[inline]
235    fn bitor(self, rhs: &Self) -> Self {
236        self.bitor(*rhs)
237    }
238}
239
240impl BitOr<&BVec4A> for &BVec4A {
241    type Output = BVec4A;
242    #[inline]
243    fn bitor(self, rhs: &BVec4A) -> BVec4A {
244        (*self).bitor(*rhs)
245    }
246}
247
248impl BitOr<BVec4A> for &BVec4A {
249    type Output = BVec4A;
250    #[inline]
251    fn bitor(self, rhs: BVec4A) -> BVec4A {
252        (*self).bitor(rhs)
253    }
254}
255
256impl BitOrAssign for BVec4A {
257    #[inline]
258    fn bitor_assign(&mut self, rhs: Self) {
259        *self = self.bitor(rhs);
260    }
261}
262
263impl BitOrAssign<&Self> for BVec4A {
264    #[inline]
265    fn bitor_assign(&mut self, rhs: &Self) {
266        self.bitor_assign(*rhs);
267    }
268}
269
270impl BitXor for BVec4A {
271    type Output = Self;
272    #[inline]
273    fn bitxor(self, rhs: Self) -> Self {
274        Self(unsafe { veorq_u32(self.0, rhs.0) })
275    }
276}
277
278impl BitXor<&Self> for BVec4A {
279    type Output = Self;
280    #[inline]
281    fn bitxor(self, rhs: &Self) -> Self {
282        self.bitxor(*rhs)
283    }
284}
285
286impl BitXor<&BVec4A> for &BVec4A {
287    type Output = BVec4A;
288    #[inline]
289    fn bitxor(self, rhs: &BVec4A) -> BVec4A {
290        (*self).bitxor(*rhs)
291    }
292}
293
294impl BitXor<BVec4A> for &BVec4A {
295    type Output = BVec4A;
296    #[inline]
297    fn bitxor(self, rhs: BVec4A) -> BVec4A {
298        (*self).bitxor(rhs)
299    }
300}
301
302impl BitXorAssign for BVec4A {
303    #[inline]
304    fn bitxor_assign(&mut self, rhs: Self) {
305        *self = self.bitxor(rhs);
306    }
307}
308
309impl BitXorAssign<&Self> for BVec4A {
310    #[inline]
311    fn bitxor_assign(&mut self, rhs: &Self) {
312        self.bitxor_assign(*rhs);
313    }
314}
315
316impl Not for BVec4A {
317    type Output = Self;
318    #[inline]
319    fn not(self) -> Self {
320        Self(unsafe { vmvnq_u32(self.0) })
321    }
322}
323
324impl Not for &BVec4A {
325    type Output = BVec4A;
326    #[inline]
327    fn not(self) -> BVec4A {
328        (*self).not()
329    }
330}
331
332impl From<BVec4A> for uint32x4_t {
333    #[inline]
334    fn from(t: BVec4A) -> Self {
335        t.0
336    }
337}
338
339impl fmt::Debug for BVec4A {
340    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341        let arr = self.into_u32_array();
342        write!(
343            f,
344            "{}({:#x}, {:#x}, {:#x}, {:#x})",
345            stringify!(BVec4A),
346            arr[0],
347            arr[1],
348            arr[2],
349            arr[3]
350        )
351    }
352}
353
354impl fmt::Display for BVec4A {
355    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356        let arr = self.into_bool_array();
357        write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
358    }
359}
360
361impl From<[bool; 4]> for BVec4A {
362    #[inline]
363    fn from(a: [bool; 4]) -> Self {
364        Self::from_array(a)
365    }
366}
367
368impl From<BVec4A> for [bool; 4] {
369    #[inline]
370    fn from(mask: BVec4A) -> Self {
371        mask.into_bool_array()
372    }
373}
374
375impl From<BVec4A> for [u32; 4] {
376    #[inline]
377    fn from(mask: BVec4A) -> Self {
378        mask.into_u32_array()
379    }
380}