glam/bool/sse2/
bvec3a.rs

1// Generated from vec_mask.rs.tera template. Edit the template, not the generated file.
2
3use 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: BVec3A,
15}
16
17/// Creates a 3-dimensional `bool` vector mask.
18#[inline(always)]
19#[must_use]
20pub const fn bvec3a(x: bool, y: bool, z: bool) -> BVec3A {
21    BVec3A::new(x, y, z)
22}
23
24/// A 3-dimensional SIMD vector mask.
25///
26/// This type is 16 byte aligned.
27#[derive(Clone, Copy)]
28#[repr(transparent)]
29pub struct BVec3A(pub(crate) __m128);
30
31const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
32
33impl BVec3A {
34    /// All false.
35    pub const FALSE: Self = Self::splat(false);
36
37    /// All true.
38    pub const TRUE: Self = Self::splat(true);
39
40    /// Creates a new vector mask.
41    #[inline(always)]
42    #[must_use]
43    pub const fn new(x: bool, y: bool, z: bool) -> Self {
44        unsafe {
45            UnionCast {
46                a: [MASK[x as usize], MASK[y as usize], MASK[z as usize], 0],
47            }
48            .v
49        }
50    }
51
52    /// Creates a vector mask with all elements set to `v`.
53    #[inline]
54    #[must_use]
55    pub const fn splat(v: bool) -> Self {
56        Self::new(v, v, v)
57    }
58
59    /// Creates a new vector mask from a bool array.
60    #[inline]
61    #[must_use]
62    pub const fn from_array(a: [bool; 3]) -> Self {
63        Self::new(a[0], a[1], a[2])
64    }
65
66    /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
67    ///
68    /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
69    /// into the first lowest bit, element `y` into the second, etc.
70    #[inline]
71    #[must_use]
72    pub fn bitmask(self) -> u32 {
73        unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
74    }
75
76    /// Returns true if any of the elements are true, false otherwise.
77    #[inline]
78    #[must_use]
79    pub fn any(self) -> bool {
80        self.bitmask() != 0
81    }
82
83    /// Returns true if all the elements are true, false otherwise.
84    #[inline]
85    #[must_use]
86    pub fn all(self) -> bool {
87        self.bitmask() == 0x7
88    }
89
90    /// Tests the value at `index`.
91    ///
92    /// Panics if `index` is greater than 2.
93    #[inline]
94    #[must_use]
95    pub fn test(&self, index: usize) -> bool {
96        match index {
97            0 => (self.bitmask() & (1 << 0)) != 0,
98            1 => (self.bitmask() & (1 << 1)) != 0,
99            2 => (self.bitmask() & (1 << 2)) != 0,
100            _ => panic!("index out of bounds"),
101        }
102    }
103
104    /// Sets the element at `index`.
105    ///
106    /// Panics if `index` is greater than 2.
107    #[inline]
108    pub fn set(&mut self, index: usize, value: bool) {
109        use crate::Vec3A;
110        let mut v = Vec3A(self.0);
111        v[index] = f32::from_bits(MASK[value as usize]);
112        self.0 = v.0;
113    }
114
115    #[inline]
116    #[must_use]
117    fn into_bool_array(self) -> [bool; 3] {
118        let bitmask = self.bitmask();
119        [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0]
120    }
121
122    #[inline]
123    #[must_use]
124    fn into_u32_array(self) -> [u32; 3] {
125        let bitmask = self.bitmask();
126        [
127            MASK[(bitmask & 1) as usize],
128            MASK[((bitmask >> 1) & 1) as usize],
129            MASK[((bitmask >> 2) & 1) as usize],
130        ]
131    }
132}
133
134impl Default for BVec3A {
135    #[inline]
136    fn default() -> Self {
137        Self::FALSE
138    }
139}
140
141impl PartialEq for BVec3A {
142    #[inline]
143    fn eq(&self, rhs: &Self) -> bool {
144        self.bitmask().eq(&rhs.bitmask())
145    }
146}
147
148impl Eq for BVec3A {}
149
150impl core::hash::Hash for BVec3A {
151    #[inline]
152    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
153        self.bitmask().hash(state);
154    }
155}
156
157impl BitAnd for BVec3A {
158    type Output = Self;
159    #[inline]
160    fn bitand(self, rhs: Self) -> Self {
161        Self(unsafe { _mm_and_ps(self.0, rhs.0) })
162    }
163}
164
165impl BitAnd<&Self> for BVec3A {
166    type Output = Self;
167    #[inline]
168    fn bitand(self, rhs: &Self) -> Self {
169        self.bitand(*rhs)
170    }
171}
172
173impl BitAnd<&BVec3A> for &BVec3A {
174    type Output = BVec3A;
175    #[inline]
176    fn bitand(self, rhs: &BVec3A) -> BVec3A {
177        (*self).bitand(*rhs)
178    }
179}
180
181impl BitAnd<BVec3A> for &BVec3A {
182    type Output = BVec3A;
183    #[inline]
184    fn bitand(self, rhs: BVec3A) -> BVec3A {
185        (*self).bitand(rhs)
186    }
187}
188
189impl BitAndAssign for BVec3A {
190    #[inline]
191    fn bitand_assign(&mut self, rhs: Self) {
192        *self = self.bitand(rhs);
193    }
194}
195
196impl BitAndAssign<&Self> for BVec3A {
197    #[inline]
198    fn bitand_assign(&mut self, rhs: &Self) {
199        self.bitand_assign(*rhs);
200    }
201}
202
203impl BitOr for BVec3A {
204    type Output = Self;
205    #[inline]
206    fn bitor(self, rhs: Self) -> Self {
207        Self(unsafe { _mm_or_ps(self.0, rhs.0) })
208    }
209}
210
211impl BitOr<&Self> for BVec3A {
212    type Output = Self;
213    #[inline]
214    fn bitor(self, rhs: &Self) -> Self {
215        self.bitor(*rhs)
216    }
217}
218
219impl BitOr<&BVec3A> for &BVec3A {
220    type Output = BVec3A;
221    #[inline]
222    fn bitor(self, rhs: &BVec3A) -> BVec3A {
223        (*self).bitor(*rhs)
224    }
225}
226
227impl BitOr<BVec3A> for &BVec3A {
228    type Output = BVec3A;
229    #[inline]
230    fn bitor(self, rhs: BVec3A) -> BVec3A {
231        (*self).bitor(rhs)
232    }
233}
234
235impl BitOrAssign for BVec3A {
236    #[inline]
237    fn bitor_assign(&mut self, rhs: Self) {
238        *self = self.bitor(rhs);
239    }
240}
241
242impl BitOrAssign<&Self> for BVec3A {
243    #[inline]
244    fn bitor_assign(&mut self, rhs: &Self) {
245        self.bitor_assign(*rhs);
246    }
247}
248
249impl BitXor for BVec3A {
250    type Output = Self;
251    #[inline]
252    fn bitxor(self, rhs: Self) -> Self {
253        Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
254    }
255}
256
257impl BitXor<&Self> for BVec3A {
258    type Output = Self;
259    #[inline]
260    fn bitxor(self, rhs: &Self) -> Self {
261        self.bitxor(*rhs)
262    }
263}
264
265impl BitXor<&BVec3A> for &BVec3A {
266    type Output = BVec3A;
267    #[inline]
268    fn bitxor(self, rhs: &BVec3A) -> BVec3A {
269        (*self).bitxor(*rhs)
270    }
271}
272
273impl BitXor<BVec3A> for &BVec3A {
274    type Output = BVec3A;
275    #[inline]
276    fn bitxor(self, rhs: BVec3A) -> BVec3A {
277        (*self).bitxor(rhs)
278    }
279}
280
281impl BitXorAssign for BVec3A {
282    #[inline]
283    fn bitxor_assign(&mut self, rhs: Self) {
284        *self = self.bitxor(rhs);
285    }
286}
287
288impl BitXorAssign<&Self> for BVec3A {
289    #[inline]
290    fn bitxor_assign(&mut self, rhs: &Self) {
291        self.bitxor_assign(*rhs);
292    }
293}
294
295impl Not for BVec3A {
296    type Output = Self;
297    #[inline]
298    fn not(self) -> Self {
299        Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
300    }
301}
302
303impl Not for &BVec3A {
304    type Output = BVec3A;
305    #[inline]
306    fn not(self) -> BVec3A {
307        (*self).not()
308    }
309}
310
311impl From<BVec3A> for __m128 {
312    #[inline]
313    fn from(t: BVec3A) -> Self {
314        t.0
315    }
316}
317
318impl fmt::Debug for BVec3A {
319    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320        let arr = self.into_u32_array();
321        write!(
322            f,
323            "{}({:#x}, {:#x}, {:#x})",
324            stringify!(BVec3A),
325            arr[0],
326            arr[1],
327            arr[2]
328        )
329    }
330}
331
332impl fmt::Display for BVec3A {
333    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334        let arr = self.into_bool_array();
335        write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
336    }
337}
338
339impl From<[bool; 3]> for BVec3A {
340    #[inline]
341    fn from(a: [bool; 3]) -> Self {
342        Self::from_array(a)
343    }
344}
345
346impl From<BVec3A> for [bool; 3] {
347    #[inline]
348    fn from(mask: BVec3A) -> Self {
349        mask.into_bool_array()
350    }
351}
352
353impl From<BVec3A> for [u32; 3] {
354    #[inline]
355    fn from(mask: BVec3A) -> Self {
356        mask.into_u32_array()
357    }
358}