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 #[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 #[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}