1use 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#[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#[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 pub const FALSE: Self = Self::splat(false);
33
34 pub const TRUE: Self = Self::splat(true);
36
37 #[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 #[inline]
56 #[must_use]
57 pub const fn splat(v: bool) -> Self {
58 Self::new(v, v, v, v)
59 }
60
61 #[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 #[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())); let mmb = vextq_u32(mma, mma, 2); let mmc = vorrq_u32(mma, mmb); let mmd = vextq_u32(mmc, mmc, 3); let mme = vorrq_u32(mmc, mmd); vgetq_lane_u32(mme, 0)
82 }
83 }
84
85 #[inline]
87 #[must_use]
88 pub fn any(self) -> bool {
89 self.bitmask() != 0
90 }
91
92 #[inline]
94 #[must_use]
95 pub fn all(self) -> bool {
96 self.bitmask() == 0xf
97 }
98
99 #[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 #[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}