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