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 BitAndAssign for BVec4A {
185    #[inline]
186    fn bitand_assign(&mut self, rhs: Self) {
187        *self = self.bitand(rhs);
188    }
189}
190
191impl BitOr for BVec4A {
192    type Output = Self;
193    #[inline]
194    fn bitor(self, rhs: Self) -> Self {
195        Self(unsafe { vorrq_u32(self.0, rhs.0) })
196    }
197}
198
199impl BitOrAssign for BVec4A {
200    #[inline]
201    fn bitor_assign(&mut self, rhs: Self) {
202        *self = self.bitor(rhs);
203    }
204}
205
206impl BitXor for BVec4A {
207    type Output = Self;
208    #[inline]
209    fn bitxor(self, rhs: Self) -> Self {
210        Self(unsafe { veorq_u32(self.0, rhs.0) })
211    }
212}
213
214impl BitXorAssign for BVec4A {
215    #[inline]
216    fn bitxor_assign(&mut self, rhs: Self) {
217        *self = self.bitxor(rhs);
218    }
219}
220
221impl Not for BVec4A {
222    type Output = Self;
223    #[inline]
224    fn not(self) -> Self {
225        Self(unsafe { vmvnq_u32(self.0) })
226    }
227}
228
229impl From<BVec4A> for uint32x4_t {
230    #[inline]
231    fn from(t: BVec4A) -> Self {
232        t.0
233    }
234}
235
236impl fmt::Debug for BVec4A {
237    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
238        let arr = self.into_u32_array();
239        write!(
240            f,
241            "{}({:#x}, {:#x}, {:#x}, {:#x})",
242            stringify!(BVec4A),
243            arr[0],
244            arr[1],
245            arr[2],
246            arr[3]
247        )
248    }
249}
250
251impl fmt::Display for BVec4A {
252    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
253        let arr = self.into_bool_array();
254        write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
255    }
256}
257
258impl From<[bool; 4]> for BVec4A {
259    #[inline]
260    fn from(a: [bool; 4]) -> Self {
261        Self::from_array(a)
262    }
263}
264
265impl From<BVec4A> for [bool; 4] {
266    #[inline]
267    fn from(mask: BVec4A) -> Self {
268        mask.into_bool_array()
269    }
270}
271
272impl From<BVec4A> for [u32; 4] {
273    #[inline]
274    fn from(mask: BVec4A) -> Self {
275        mask.into_u32_array()
276    }
277}