glam/bool/sse2/
bvec4a.rs
1#[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#[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 pub const FALSE: Self = Self::splat(false);
30
31 pub const TRUE: Self = Self::splat(true);
33
34 #[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 #[inline]
53 #[must_use]
54 pub const fn splat(v: bool) -> Self {
55 Self::new(v, v, v, v)
56 }
57
58 #[inline]
63 #[must_use]
64 pub fn bitmask(self) -> u32 {
65 unsafe { _mm_movemask_ps(self.0) as u32 }
66 }
67
68 #[inline]
70 #[must_use]
71 pub fn any(self) -> bool {
72 self.bitmask() != 0
73 }
74
75 #[inline]
77 #[must_use]
78 pub fn all(self) -> bool {
79 self.bitmask() == 0xf
80 }
81
82 #[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 #[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}