1 // Generated from vec_mask.rs.tera template. Edit the template, not the generated file.
2 
3 #[cfg(not(target_arch = "spirv"))]
4 use core::fmt;
5 use core::ops::*;
6 
7 #[cfg(target_arch = "x86")]
8 use core::arch::x86::*;
9 #[cfg(target_arch = "x86_64")]
10 use core::arch::x86_64::*;
11 
12 #[repr(C)]
13 union 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)]
23 pub struct BVec4A(pub(crate) __m128);
24 
25 const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
26 
27 impl 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]
new(x: bool, y: bool, z: bool, w: bool) -> Self37     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]
splat(v: bool) -> Self54     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]
bitmask(self) -> u3264     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]
any(self) -> bool71     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]
all(self) -> bool78     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]
test(&self, index: usize) -> bool87     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]
set(&mut self, index: usize, value: bool)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]
into_bool_array(self) -> [bool; 4]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]
into_u32_array(self) -> [u32; 4]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 
133 impl Default for BVec4A {
134     #[inline]
default() -> Self135     fn default() -> Self {
136         Self::FALSE
137     }
138 }
139 
140 impl PartialEq for BVec4A {
141     #[inline]
eq(&self, rhs: &Self) -> bool142     fn eq(&self, rhs: &Self) -> bool {
143         self.bitmask().eq(&rhs.bitmask())
144     }
145 }
146 
147 impl Eq for BVec4A {}
148 
149 impl core::hash::Hash for BVec4A {
150     #[inline]
hash<H: core::hash::Hasher>(&self, state: &mut H)151     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
152         self.bitmask().hash(state);
153     }
154 }
155 
156 impl BitAnd for BVec4A {
157     type Output = Self;
158     #[inline]
bitand(self, rhs: Self) -> Self159     fn bitand(self, rhs: Self) -> Self {
160         Self(unsafe { _mm_and_ps(self.0, rhs.0) })
161     }
162 }
163 
164 impl BitAndAssign for BVec4A {
165     #[inline]
bitand_assign(&mut self, rhs: Self)166     fn bitand_assign(&mut self, rhs: Self) {
167         *self = self.bitand(rhs);
168     }
169 }
170 
171 impl BitOr for BVec4A {
172     type Output = Self;
173     #[inline]
bitor(self, rhs: Self) -> Self174     fn bitor(self, rhs: Self) -> Self {
175         Self(unsafe { _mm_or_ps(self.0, rhs.0) })
176     }
177 }
178 
179 impl BitOrAssign for BVec4A {
180     #[inline]
bitor_assign(&mut self, rhs: Self)181     fn bitor_assign(&mut self, rhs: Self) {
182         *self = self.bitor(rhs);
183     }
184 }
185 
186 impl BitXor for BVec4A {
187     type Output = Self;
188     #[inline]
bitxor(self, rhs: Self) -> Self189     fn bitxor(self, rhs: Self) -> Self {
190         Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
191     }
192 }
193 
194 impl BitXorAssign for BVec4A {
195     #[inline]
bitxor_assign(&mut self, rhs: Self)196     fn bitxor_assign(&mut self, rhs: Self) {
197         *self = self.bitxor(rhs);
198     }
199 }
200 
201 impl Not for BVec4A {
202     type Output = Self;
203     #[inline]
not(self) -> Self204     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 
209 impl From<BVec4A> for __m128 {
210     #[inline]
from(t: BVec4A) -> Self211     fn from(t: BVec4A) -> Self {
212         t.0
213     }
214 }
215 
216 #[cfg(not(target_arch = "spirv"))]
217 impl fmt::Debug for BVec4A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result218     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"))]
233 impl fmt::Display for BVec4A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result234     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 
240 impl From<BVec4A> for [bool; 4] {
241     #[inline]
from(mask: BVec4A) -> Self242     fn from(mask: BVec4A) -> Self {
243         mask.into_bool_array()
244     }
245 }
246 
247 impl From<BVec4A> for [u32; 4] {
248     #[inline]
from(mask: BVec4A) -> Self249     fn from(mask: BVec4A) -> Self {
250         mask.into_u32_array()
251     }
252 }
253