1use core::fmt;
4use core::ops::*;
5
6#[cfg(target_arch = "x86")]
7use core::arch::x86::*;
8#[cfg(target_arch = "x86_64")]
9use core::arch::x86_64::*;
10
11#[repr(C)]
12union UnionCast {
13 a: [u32; 4],
14 v: BVec4A,
15}
16
17#[inline(always)]
19#[must_use]
20pub const fn bvec4a(x: bool, y: bool, z: bool, w: bool) -> BVec4A {
21 BVec4A::new(x, y, z, w)
22}
23
24#[derive(Clone, Copy)]
28#[repr(transparent)]
29pub struct BVec4A(pub(crate) __m128);
30
31const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
32
33impl BVec4A {
34 pub const FALSE: Self = Self::splat(false);
36
37 pub const TRUE: Self = Self::splat(true);
39
40 #[inline(always)]
42 #[must_use]
43 pub const fn new(x: bool, y: bool, z: bool, w: bool) -> Self {
44 unsafe {
45 UnionCast {
46 a: [
47 MASK[x as usize],
48 MASK[y as usize],
49 MASK[z as usize],
50 MASK[w as usize],
51 ],
52 }
53 .v
54 }
55 }
56
57 #[inline]
59 #[must_use]
60 pub const fn splat(v: bool) -> Self {
61 Self::new(v, v, v, v)
62 }
63
64 #[inline]
66 #[must_use]
67 pub const fn from_array(a: [bool; 4]) -> Self {
68 Self::new(a[0], a[1], a[2], a[3])
69 }
70
71 #[inline]
76 #[must_use]
77 pub fn bitmask(self) -> u32 {
78 unsafe { _mm_movemask_ps(self.0) as u32 }
79 }
80
81 #[inline]
83 #[must_use]
84 pub fn any(self) -> bool {
85 self.bitmask() != 0
86 }
87
88 #[inline]
90 #[must_use]
91 pub fn all(self) -> bool {
92 self.bitmask() == 0xf
93 }
94
95 #[inline]
99 #[must_use]
100 #[track_caller]
101 pub fn test(self, index: usize) -> bool {
102 match index {
103 0 => (self.bitmask() & (1 << 0)) != 0,
104 1 => (self.bitmask() & (1 << 1)) != 0,
105 2 => (self.bitmask() & (1 << 2)) != 0,
106 3 => (self.bitmask() & (1 << 3)) != 0,
107 _ => panic!("index out of bounds"),
108 }
109 }
110
111 #[inline]
115 #[track_caller]
116 pub fn set(&mut self, index: usize, value: bool) {
117 use crate::Vec4;
118 let mut v = Vec4(self.0);
119 v[index] = f32::from_bits(MASK[value as usize]);
120 self.0 = v.0;
121 }
122
123 #[inline]
124 #[must_use]
125 fn into_bool_array(self) -> [bool; 4] {
126 let bitmask = self.bitmask();
127 [
128 (bitmask & 1) != 0,
129 (bitmask & 2) != 0,
130 (bitmask & 4) != 0,
131 (bitmask & 8) != 0,
132 ]
133 }
134
135 #[inline]
136 #[must_use]
137 fn into_u32_array(self) -> [u32; 4] {
138 let bitmask = self.bitmask();
139 [
140 MASK[(bitmask & 1) as usize],
141 MASK[((bitmask >> 1) & 1) as usize],
142 MASK[((bitmask >> 2) & 1) as usize],
143 MASK[((bitmask >> 3) & 1) as usize],
144 ]
145 }
146}
147
148impl Default for BVec4A {
149 #[inline]
150 fn default() -> Self {
151 Self::FALSE
152 }
153}
154
155impl PartialEq for BVec4A {
156 #[inline]
157 fn eq(&self, rhs: &Self) -> bool {
158 self.bitmask().eq(&rhs.bitmask())
159 }
160}
161
162impl Eq for BVec4A {}
163
164impl core::hash::Hash for BVec4A {
165 #[inline]
166 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
167 self.bitmask().hash(state);
168 }
169}
170
171impl BitAnd for BVec4A {
172 type Output = Self;
173 #[inline]
174 fn bitand(self, rhs: Self) -> Self {
175 Self(unsafe { _mm_and_ps(self.0, rhs.0) })
176 }
177}
178
179impl BitAnd<&Self> for BVec4A {
180 type Output = Self;
181 #[inline]
182 fn bitand(self, rhs: &Self) -> Self {
183 self.bitand(*rhs)
184 }
185}
186
187impl BitAnd<&BVec4A> for &BVec4A {
188 type Output = BVec4A;
189 #[inline]
190 fn bitand(self, rhs: &BVec4A) -> BVec4A {
191 (*self).bitand(*rhs)
192 }
193}
194
195impl BitAnd<BVec4A> for &BVec4A {
196 type Output = BVec4A;
197 #[inline]
198 fn bitand(self, rhs: BVec4A) -> BVec4A {
199 (*self).bitand(rhs)
200 }
201}
202
203impl BitAndAssign for BVec4A {
204 #[inline]
205 fn bitand_assign(&mut self, rhs: Self) {
206 *self = self.bitand(rhs);
207 }
208}
209
210impl BitAndAssign<&Self> for BVec4A {
211 #[inline]
212 fn bitand_assign(&mut self, rhs: &Self) {
213 self.bitand_assign(*rhs);
214 }
215}
216
217impl BitOr for BVec4A {
218 type Output = Self;
219 #[inline]
220 fn bitor(self, rhs: Self) -> Self {
221 Self(unsafe { _mm_or_ps(self.0, rhs.0) })
222 }
223}
224
225impl BitOr<&Self> for BVec4A {
226 type Output = Self;
227 #[inline]
228 fn bitor(self, rhs: &Self) -> Self {
229 self.bitor(*rhs)
230 }
231}
232
233impl BitOr<&BVec4A> for &BVec4A {
234 type Output = BVec4A;
235 #[inline]
236 fn bitor(self, rhs: &BVec4A) -> BVec4A {
237 (*self).bitor(*rhs)
238 }
239}
240
241impl BitOr<BVec4A> for &BVec4A {
242 type Output = BVec4A;
243 #[inline]
244 fn bitor(self, rhs: BVec4A) -> BVec4A {
245 (*self).bitor(rhs)
246 }
247}
248
249impl BitOrAssign for BVec4A {
250 #[inline]
251 fn bitor_assign(&mut self, rhs: Self) {
252 *self = self.bitor(rhs);
253 }
254}
255
256impl BitOrAssign<&Self> for BVec4A {
257 #[inline]
258 fn bitor_assign(&mut self, rhs: &Self) {
259 self.bitor_assign(*rhs);
260 }
261}
262
263impl BitXor for BVec4A {
264 type Output = Self;
265 #[inline]
266 fn bitxor(self, rhs: Self) -> Self {
267 Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
268 }
269}
270
271impl BitXor<&Self> for BVec4A {
272 type Output = Self;
273 #[inline]
274 fn bitxor(self, rhs: &Self) -> Self {
275 self.bitxor(*rhs)
276 }
277}
278
279impl BitXor<&BVec4A> for &BVec4A {
280 type Output = BVec4A;
281 #[inline]
282 fn bitxor(self, rhs: &BVec4A) -> BVec4A {
283 (*self).bitxor(*rhs)
284 }
285}
286
287impl BitXor<BVec4A> for &BVec4A {
288 type Output = BVec4A;
289 #[inline]
290 fn bitxor(self, rhs: BVec4A) -> BVec4A {
291 (*self).bitxor(rhs)
292 }
293}
294
295impl BitXorAssign for BVec4A {
296 #[inline]
297 fn bitxor_assign(&mut self, rhs: Self) {
298 *self = self.bitxor(rhs);
299 }
300}
301
302impl BitXorAssign<&Self> for BVec4A {
303 #[inline]
304 fn bitxor_assign(&mut self, rhs: &Self) {
305 self.bitxor_assign(*rhs);
306 }
307}
308
309impl Not for BVec4A {
310 type Output = Self;
311 #[inline]
312 fn not(self) -> Self {
313 Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
314 }
315}
316
317impl Not for &BVec4A {
318 type Output = BVec4A;
319 #[inline]
320 fn not(self) -> BVec4A {
321 (*self).not()
322 }
323}
324
325impl From<BVec4A> for __m128 {
326 #[inline]
327 fn from(t: BVec4A) -> Self {
328 t.0
329 }
330}
331
332impl fmt::Debug for BVec4A {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 let arr = self.into_u32_array();
335 write!(
336 f,
337 "{}({:#x}, {:#x}, {:#x}, {:#x})",
338 stringify!(BVec4A),
339 arr[0],
340 arr[1],
341 arr[2],
342 arr[3]
343 )
344 }
345}
346
347impl fmt::Display for BVec4A {
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349 let arr = self.into_bool_array();
350 write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
351 }
352}
353
354impl From<[bool; 4]> for BVec4A {
355 #[inline]
356 fn from(a: [bool; 4]) -> Self {
357 Self::from_array(a)
358 }
359}
360
361impl From<BVec4A> for [bool; 4] {
362 #[inline]
363 fn from(mask: BVec4A) -> Self {
364 mask.into_bool_array()
365 }
366}
367
368impl From<BVec4A> for [u32; 4] {
369 #[inline]
370 fn from(mask: BVec4A) -> Self {
371 mask.into_u32_array()
372 }
373}