glam/bool/sse2/
bvec4a.rs

1// Generated from vec_mask.rs.tera template. Edit the template, not the generated file.
2
3#[cfg(not(target_arch = "spirv"))]
4use core::fmt;
5use core::ops::*;
6
7#[cfg(target_arch = "x86")]
8use core::arch::x86::*;
9#[cfg(target_arch = "x86_64")]
10use core::arch::x86_64::*;
11
12#[repr(C)]
13union UnionCast {
14    a: [u32; 4],
15    v: BVec4A,
16}
17
18/// A 4-dimensional SIMD vector mask.
19///
20/// This type is 16 byte aligned.
21#[derive(Clone, Copy)]
22#[repr(transparent)]
23pub struct BVec4A(pub(crate) __m128);
24
25const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
26
27impl BVec4A {
28    /// All false.
29    pub const FALSE: Self = Self::splat(false);
30
31    /// All true.
32    pub const TRUE: Self = Self::splat(true);
33
34    /// Creates a new vector mask.
35    #[inline(always)]
36    #[must_use]
37    pub const fn new(x: bool, y: bool, z: bool, w: bool) -> Self {
38        unsafe {
39            UnionCast {
40                a: [
41                    MASK[x as usize],
42                    MASK[y as usize],
43                    MASK[z as usize],
44                    MASK[w as usize],
45                ],
46            }
47            .v
48        }
49    }
50
51    /// Creates a vector with all elements set to `v`.
52    #[inline]
53    #[must_use]
54    pub const fn splat(v: bool) -> Self {
55        Self::new(v, v, v, v)
56    }
57
58    /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
59    ///
60    /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
61    /// into the first lowest bit, element `y` into the second, etc.
62    #[inline]
63    #[must_use]
64    pub fn bitmask(self) -> u32 {
65        unsafe { _mm_movemask_ps(self.0) as u32 }
66    }
67
68    /// Returns true if any of the elements are true, false otherwise.
69    #[inline]
70    #[must_use]
71    pub fn any(self) -> bool {
72        self.bitmask() != 0
73    }
74
75    /// Returns true if all the elements are true, false otherwise.
76    #[inline]
77    #[must_use]
78    pub fn all(self) -> bool {
79        self.bitmask() == 0xf
80    }
81
82    /// Tests the value at `index`.
83    ///
84    /// Panics if `index` is greater than 3.
85    #[inline]
86    #[must_use]
87    pub fn test(&self, index: usize) -> bool {
88        match index {
89            0 => (self.bitmask() & (1 << 0)) != 0,
90            1 => (self.bitmask() & (1 << 1)) != 0,
91            2 => (self.bitmask() & (1 << 2)) != 0,
92            3 => (self.bitmask() & (1 << 3)) != 0,
93            _ => panic!("index out of bounds"),
94        }
95    }
96
97    /// Sets the element at `index`.
98    ///
99    /// Panics if `index` is greater than 3.
100    #[inline]
101    pub fn set(&mut self, index: usize, value: bool) {
102        use crate::Vec4;
103        let mut v = Vec4(self.0);
104        v[index] = f32::from_bits(MASK[value as usize]);
105        *self = Self(v.0);
106    }
107
108    #[inline]
109    #[must_use]
110    fn into_bool_array(self) -> [bool; 4] {
111        let bitmask = self.bitmask();
112        [
113            (bitmask & 1) != 0,
114            (bitmask & 2) != 0,
115            (bitmask & 4) != 0,
116            (bitmask & 8) != 0,
117        ]
118    }
119
120    #[inline]
121    #[must_use]
122    fn into_u32_array(self) -> [u32; 4] {
123        let bitmask = self.bitmask();
124        [
125            MASK[(bitmask & 1) as usize],
126            MASK[((bitmask >> 1) & 1) as usize],
127            MASK[((bitmask >> 2) & 1) as usize],
128            MASK[((bitmask >> 3) & 1) as usize],
129        ]
130    }
131}
132
133impl Default for BVec4A {
134    #[inline]
135    fn default() -> Self {
136        Self::FALSE
137    }
138}
139
140impl PartialEq for BVec4A {
141    #[inline]
142    fn eq(&self, rhs: &Self) -> bool {
143        self.bitmask().eq(&rhs.bitmask())
144    }
145}
146
147impl Eq for BVec4A {}
148
149impl core::hash::Hash for BVec4A {
150    #[inline]
151    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
152        self.bitmask().hash(state);
153    }
154}
155
156impl BitAnd for BVec4A {
157    type Output = Self;
158    #[inline]
159    fn bitand(self, rhs: Self) -> Self {
160        Self(unsafe { _mm_and_ps(self.0, rhs.0) })
161    }
162}
163
164impl BitAndAssign for BVec4A {
165    #[inline]
166    fn bitand_assign(&mut self, rhs: Self) {
167        *self = self.bitand(rhs);
168    }
169}
170
171impl BitOr for BVec4A {
172    type Output = Self;
173    #[inline]
174    fn bitor(self, rhs: Self) -> Self {
175        Self(unsafe { _mm_or_ps(self.0, rhs.0) })
176    }
177}
178
179impl BitOrAssign for BVec4A {
180    #[inline]
181    fn bitor_assign(&mut self, rhs: Self) {
182        *self = self.bitor(rhs);
183    }
184}
185
186impl BitXor for BVec4A {
187    type Output = Self;
188    #[inline]
189    fn bitxor(self, rhs: Self) -> Self {
190        Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
191    }
192}
193
194impl BitXorAssign for BVec4A {
195    #[inline]
196    fn bitxor_assign(&mut self, rhs: Self) {
197        *self = self.bitxor(rhs);
198    }
199}
200
201impl Not for BVec4A {
202    type Output = Self;
203    #[inline]
204    fn not(self) -> Self {
205        Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
206    }
207}
208
209impl From<BVec4A> for __m128 {
210    #[inline]
211    fn from(t: BVec4A) -> Self {
212        t.0
213    }
214}
215
216#[cfg(not(target_arch = "spirv"))]
217impl fmt::Debug for BVec4A {
218    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
219        let arr = self.into_u32_array();
220        write!(
221            f,
222            "{}({:#x}, {:#x}, {:#x}, {:#x})",
223            stringify!(BVec4A),
224            arr[0],
225            arr[1],
226            arr[2],
227            arr[3]
228        )
229    }
230}
231
232#[cfg(not(target_arch = "spirv"))]
233impl fmt::Display for BVec4A {
234    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
235        let arr = self.into_bool_array();
236        write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
237    }
238}
239
240impl From<BVec4A> for [bool; 4] {
241    #[inline]
242    fn from(mask: BVec4A) -> Self {
243        mask.into_bool_array()
244    }
245}
246
247impl From<BVec4A> for [u32; 4] {
248    #[inline]
249    fn from(mask: BVec4A) -> Self {
250        mask.into_u32_array()
251    }
252}