glam/bool/sse2/
bvec4a.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: BVec4A,
15}
16
17/// Creates a 4-dimensional `bool` vector mask.
18#[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/// A 4-dimensional SIMD vector mask.
25///
26/// This type is 16 byte aligned.
27#[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    /// 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, 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    /// Creates a vector mask with all elements set to `v`.
58    #[inline]
59    #[must_use]
60    pub const fn splat(v: bool) -> Self {
61        Self::new(v, v, v, v)
62    }
63
64    /// Creates a new vector mask from a bool array.
65    #[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    /// Returns a bitmask with the lowest 4 bits set from the elements of `self`.
72    ///
73    /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
74    /// into the first lowest bit, element `y` into the second, etc.
75    #[inline]
76    #[must_use]
77    pub fn bitmask(self) -> u32 {
78        unsafe { _mm_movemask_ps(self.0) as u32 }
79    }
80
81    /// Returns true if any of the elements are true, false otherwise.
82    #[inline]
83    #[must_use]
84    pub fn any(self) -> bool {
85        self.bitmask() != 0
86    }
87
88    /// Returns true if all the elements are true, false otherwise.
89    #[inline]
90    #[must_use]
91    pub fn all(self) -> bool {
92        self.bitmask() == 0xf
93    }
94
95    /// Tests the value at `index`.
96    ///
97    /// Panics if `index` is greater than 3.
98    #[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    /// Sets the element at `index`.
111    ///
112    /// Panics if `index` is greater than 3.
113    #[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 BitAndAssign for BVec4A {
178    #[inline]
179    fn bitand_assign(&mut self, rhs: Self) {
180        *self = self.bitand(rhs);
181    }
182}
183
184impl BitOr for BVec4A {
185    type Output = Self;
186    #[inline]
187    fn bitor(self, rhs: Self) -> Self {
188        Self(unsafe { _mm_or_ps(self.0, rhs.0) })
189    }
190}
191
192impl BitOrAssign for BVec4A {
193    #[inline]
194    fn bitor_assign(&mut self, rhs: Self) {
195        *self = self.bitor(rhs);
196    }
197}
198
199impl BitXor for BVec4A {
200    type Output = Self;
201    #[inline]
202    fn bitxor(self, rhs: Self) -> Self {
203        Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
204    }
205}
206
207impl BitXorAssign for BVec4A {
208    #[inline]
209    fn bitxor_assign(&mut self, rhs: Self) {
210        *self = self.bitxor(rhs);
211    }
212}
213
214impl Not for BVec4A {
215    type Output = Self;
216    #[inline]
217    fn not(self) -> Self {
218        Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
219    }
220}
221
222impl From<BVec4A> for __m128 {
223    #[inline]
224    fn from(t: BVec4A) -> Self {
225        t.0
226    }
227}
228
229impl fmt::Debug for BVec4A {
230    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
231        let arr = self.into_u32_array();
232        write!(
233            f,
234            "{}({:#x}, {:#x}, {:#x}, {:#x})",
235            stringify!(BVec4A),
236            arr[0],
237            arr[1],
238            arr[2],
239            arr[3]
240        )
241    }
242}
243
244impl fmt::Display for BVec4A {
245    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246        let arr = self.into_bool_array();
247        write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
248    }
249}
250
251impl From<[bool; 4]> for BVec4A {
252    #[inline]
253    fn from(a: [bool; 4]) -> Self {
254        Self::from_array(a)
255    }
256}
257
258impl From<BVec4A> for [bool; 4] {
259    #[inline]
260    fn from(mask: BVec4A) -> Self {
261        mask.into_bool_array()
262    }
263}
264
265impl From<BVec4A> for [u32; 4] {
266    #[inline]
267    fn from(mask: BVec4A) -> Self {
268        mask.into_u32_array()
269    }
270}