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 BitAndAssign for BVec3A {
166    #[inline]
167    fn bitand_assign(&mut self, rhs: Self) {
168        *self = self.bitand(rhs);
169    }
170}
171
172impl BitOr for BVec3A {
173    type Output = Self;
174    #[inline]
175    fn bitor(self, rhs: Self) -> Self {
176        Self(unsafe { _mm_or_ps(self.0, rhs.0) })
177    }
178}
179
180impl BitOrAssign for BVec3A {
181    #[inline]
182    fn bitor_assign(&mut self, rhs: Self) {
183        *self = self.bitor(rhs);
184    }
185}
186
187impl BitXor for BVec3A {
188    type Output = Self;
189    #[inline]
190    fn bitxor(self, rhs: Self) -> Self {
191        Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
192    }
193}
194
195impl BitXorAssign for BVec3A {
196    #[inline]
197    fn bitxor_assign(&mut self, rhs: Self) {
198        *self = self.bitxor(rhs);
199    }
200}
201
202impl Not for BVec3A {
203    type Output = Self;
204    #[inline]
205    fn not(self) -> Self {
206        Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
207    }
208}
209
210impl From<BVec3A> for __m128 {
211    #[inline]
212    fn from(t: BVec3A) -> Self {
213        t.0
214    }
215}
216
217impl fmt::Debug for BVec3A {
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})",
223            stringify!(BVec3A),
224            arr[0],
225            arr[1],
226            arr[2]
227        )
228    }
229}
230
231impl fmt::Display for BVec3A {
232    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233        let arr = self.into_bool_array();
234        write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
235    }
236}
237
238impl From<[bool; 3]> for BVec3A {
239    #[inline]
240    fn from(a: [bool; 3]) -> Self {
241        Self::from_array(a)
242    }
243}
244
245impl From<BVec3A> for [bool; 3] {
246    #[inline]
247    fn from(mask: BVec3A) -> Self {
248        mask.into_bool_array()
249    }
250}
251
252impl From<BVec3A> for [u32; 3] {
253    #[inline]
254    fn from(mask: BVec3A) -> Self {
255        mask.into_u32_array()
256    }
257}