glam/bool/sse2/
bvec3a.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: BVec3A,
16}
17
18#[derive(Clone, Copy)]
22#[repr(transparent)]
23pub struct BVec3A(pub(crate) __m128);
24
25const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
26
27impl BVec3A {
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) -> Self {
38 unsafe {
39 UnionCast {
40 a: [MASK[x as usize], MASK[y as usize], MASK[z as usize], 0],
41 }
42 .v
43 }
44 }
45
46 #[inline]
48 #[must_use]
49 pub const fn splat(v: bool) -> Self {
50 Self::new(v, v, v)
51 }
52
53 #[inline]
58 #[must_use]
59 pub fn bitmask(self) -> u32 {
60 unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
61 }
62
63 #[inline]
65 #[must_use]
66 pub fn any(self) -> bool {
67 self.bitmask() != 0
68 }
69
70 #[inline]
72 #[must_use]
73 pub fn all(self) -> bool {
74 self.bitmask() == 0x7
75 }
76
77 #[inline]
81 #[must_use]
82 pub fn test(&self, index: usize) -> bool {
83 match index {
84 0 => (self.bitmask() & (1 << 0)) != 0,
85 1 => (self.bitmask() & (1 << 1)) != 0,
86 2 => (self.bitmask() & (1 << 2)) != 0,
87 _ => panic!("index out of bounds"),
88 }
89 }
90
91 #[inline]
95 pub fn set(&mut self, index: usize, value: bool) {
96 use crate::Vec3A;
97 let mut v = Vec3A(self.0);
98 v[index] = f32::from_bits(MASK[value as usize]);
99 *self = Self(v.0);
100 }
101
102 #[inline]
103 #[must_use]
104 fn into_bool_array(self) -> [bool; 3] {
105 let bitmask = self.bitmask();
106 [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0]
107 }
108
109 #[inline]
110 #[must_use]
111 fn into_u32_array(self) -> [u32; 3] {
112 let bitmask = self.bitmask();
113 [
114 MASK[(bitmask & 1) as usize],
115 MASK[((bitmask >> 1) & 1) as usize],
116 MASK[((bitmask >> 2) & 1) as usize],
117 ]
118 }
119}
120
121impl Default for BVec3A {
122 #[inline]
123 fn default() -> Self {
124 Self::FALSE
125 }
126}
127
128impl PartialEq for BVec3A {
129 #[inline]
130 fn eq(&self, rhs: &Self) -> bool {
131 self.bitmask().eq(&rhs.bitmask())
132 }
133}
134
135impl Eq for BVec3A {}
136
137impl core::hash::Hash for BVec3A {
138 #[inline]
139 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
140 self.bitmask().hash(state);
141 }
142}
143
144impl BitAnd for BVec3A {
145 type Output = Self;
146 #[inline]
147 fn bitand(self, rhs: Self) -> Self {
148 Self(unsafe { _mm_and_ps(self.0, rhs.0) })
149 }
150}
151
152impl BitAndAssign for BVec3A {
153 #[inline]
154 fn bitand_assign(&mut self, rhs: Self) {
155 *self = self.bitand(rhs);
156 }
157}
158
159impl BitOr for BVec3A {
160 type Output = Self;
161 #[inline]
162 fn bitor(self, rhs: Self) -> Self {
163 Self(unsafe { _mm_or_ps(self.0, rhs.0) })
164 }
165}
166
167impl BitOrAssign for BVec3A {
168 #[inline]
169 fn bitor_assign(&mut self, rhs: Self) {
170 *self = self.bitor(rhs);
171 }
172}
173
174impl BitXor for BVec3A {
175 type Output = Self;
176 #[inline]
177 fn bitxor(self, rhs: Self) -> Self {
178 Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
179 }
180}
181
182impl BitXorAssign for BVec3A {
183 #[inline]
184 fn bitxor_assign(&mut self, rhs: Self) {
185 *self = self.bitxor(rhs);
186 }
187}
188
189impl Not for BVec3A {
190 type Output = Self;
191 #[inline]
192 fn not(self) -> Self {
193 Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
194 }
195}
196
197impl From<BVec3A> for __m128 {
198 #[inline]
199 fn from(t: BVec3A) -> Self {
200 t.0
201 }
202}
203
204#[cfg(not(target_arch = "spirv"))]
205impl fmt::Debug for BVec3A {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 let arr = self.into_u32_array();
208 write!(
209 f,
210 "{}({:#x}, {:#x}, {:#x})",
211 stringify!(BVec3A),
212 arr[0],
213 arr[1],
214 arr[2]
215 )
216 }
217}
218
219#[cfg(not(target_arch = "spirv"))]
220impl fmt::Display for BVec3A {
221 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 let arr = self.into_bool_array();
223 write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
224 }
225}
226
227impl From<BVec3A> for [bool; 3] {
228 #[inline]
229 fn from(mask: BVec3A) -> Self {
230 mask.into_bool_array()
231 }
232}
233
234impl From<BVec3A> for [u32; 3] {
235 #[inline]
236 fn from(mask: BVec3A) -> Self {
237 mask.into_u32_array()
238 }
239}