1use core::fmt;
4use core::ops::*;
5
6#[inline(always)]
8#[must_use]
9pub const fn bvec4(x: bool, y: bool, z: bool, w: bool) -> BVec4 {
10 BVec4::new(x, y, z, w)
11}
12
13#[derive(Clone, Copy, PartialEq, Eq, Hash)]
15#[repr(C, align(1))]
16#[cfg_attr(target_arch = "spirv", rust_gpu::vector::v1)]
17pub struct BVec4 {
18 pub x: bool,
19 pub y: bool,
20 pub z: bool,
21 pub w: bool,
22}
23
24const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
25
26impl BVec4 {
27 pub const FALSE: Self = Self::splat(false);
29
30 pub const TRUE: Self = Self::splat(true);
32
33 #[inline(always)]
35 #[must_use]
36 pub const fn new(x: bool, y: bool, z: bool, w: bool) -> Self {
37 Self { x, y, z, w }
38 }
39
40 #[inline]
42 #[must_use]
43 pub const fn splat(v: bool) -> Self {
44 Self::new(v, v, v, v)
45 }
46
47 #[inline]
49 #[must_use]
50 pub const fn from_array(a: [bool; 4]) -> Self {
51 Self::new(a[0], a[1], a[2], a[3])
52 }
53
54 #[inline]
59 #[must_use]
60 pub fn bitmask(self) -> u32 {
61 (self.x as u32) | ((self.y as u32) << 1) | ((self.z as u32) << 2) | ((self.w as u32) << 3)
62 }
63
64 #[inline]
66 #[must_use]
67 pub fn any(self) -> bool {
68 self.x || self.y || self.z || self.w
69 }
70
71 #[inline]
73 #[must_use]
74 pub fn all(self) -> bool {
75 self.x && self.y && self.z && self.w
76 }
77
78 #[inline]
82 #[must_use]
83 pub fn test(&self, index: usize) -> bool {
84 match index {
85 0 => self.x,
86 1 => self.y,
87 2 => self.z,
88 3 => self.w,
89 _ => panic!("index out of bounds"),
90 }
91 }
92
93 #[inline]
97 pub fn set(&mut self, index: usize, value: bool) {
98 match index {
99 0 => self.x = value,
100 1 => self.y = value,
101 2 => self.z = value,
102 3 => self.w = value,
103 _ => panic!("index out of bounds"),
104 }
105 }
106
107 #[inline]
108 #[must_use]
109 fn into_bool_array(self) -> [bool; 4] {
110 [self.x, self.y, self.z, self.w]
111 }
112
113 #[inline]
114 #[must_use]
115 fn into_u32_array(self) -> [u32; 4] {
116 [
117 MASK[self.x as usize],
118 MASK[self.y as usize],
119 MASK[self.z as usize],
120 MASK[self.w as usize],
121 ]
122 }
123}
124
125impl Default for BVec4 {
126 #[inline]
127 fn default() -> Self {
128 Self::FALSE
129 }
130}
131
132impl BitAnd for BVec4 {
133 type Output = Self;
134 #[inline]
135 fn bitand(self, rhs: Self) -> Self {
136 Self {
137 x: self.x & rhs.x,
138 y: self.y & rhs.y,
139 z: self.z & rhs.z,
140 w: self.w & rhs.w,
141 }
142 }
143}
144
145impl BitAnd<&Self> for BVec4 {
146 type Output = Self;
147 #[inline]
148 fn bitand(self, rhs: &Self) -> Self {
149 self.bitand(*rhs)
150 }
151}
152
153impl BitAnd<&BVec4> for &BVec4 {
154 type Output = BVec4;
155 #[inline]
156 fn bitand(self, rhs: &BVec4) -> BVec4 {
157 (*self).bitand(*rhs)
158 }
159}
160
161impl BitAnd<BVec4> for &BVec4 {
162 type Output = BVec4;
163 #[inline]
164 fn bitand(self, rhs: BVec4) -> BVec4 {
165 (*self).bitand(rhs)
166 }
167}
168
169impl BitAndAssign for BVec4 {
170 #[inline]
171 fn bitand_assign(&mut self, rhs: Self) {
172 *self = self.bitand(rhs);
173 }
174}
175
176impl BitAndAssign<&Self> for BVec4 {
177 #[inline]
178 fn bitand_assign(&mut self, rhs: &Self) {
179 self.bitand_assign(*rhs);
180 }
181}
182
183impl BitOr for BVec4 {
184 type Output = Self;
185 #[inline]
186 fn bitor(self, rhs: Self) -> Self {
187 Self {
188 x: self.x | rhs.x,
189 y: self.y | rhs.y,
190 z: self.z | rhs.z,
191 w: self.w | rhs.w,
192 }
193 }
194}
195
196impl BitOr<&Self> for BVec4 {
197 type Output = Self;
198 #[inline]
199 fn bitor(self, rhs: &Self) -> Self {
200 self.bitor(*rhs)
201 }
202}
203
204impl BitOr<&BVec4> for &BVec4 {
205 type Output = BVec4;
206 #[inline]
207 fn bitor(self, rhs: &BVec4) -> BVec4 {
208 (*self).bitor(*rhs)
209 }
210}
211
212impl BitOr<BVec4> for &BVec4 {
213 type Output = BVec4;
214 #[inline]
215 fn bitor(self, rhs: BVec4) -> BVec4 {
216 (*self).bitor(rhs)
217 }
218}
219
220impl BitOrAssign for BVec4 {
221 #[inline]
222 fn bitor_assign(&mut self, rhs: Self) {
223 *self = self.bitor(rhs);
224 }
225}
226
227impl BitOrAssign<&Self> for BVec4 {
228 #[inline]
229 fn bitor_assign(&mut self, rhs: &Self) {
230 self.bitor_assign(*rhs);
231 }
232}
233
234impl BitXor for BVec4 {
235 type Output = Self;
236 #[inline]
237 fn bitxor(self, rhs: Self) -> Self {
238 Self {
239 x: self.x ^ rhs.x,
240 y: self.y ^ rhs.y,
241 z: self.z ^ rhs.z,
242 w: self.w ^ rhs.w,
243 }
244 }
245}
246
247impl BitXor<&Self> for BVec4 {
248 type Output = Self;
249 #[inline]
250 fn bitxor(self, rhs: &Self) -> Self {
251 self.bitxor(*rhs)
252 }
253}
254
255impl BitXor<&BVec4> for &BVec4 {
256 type Output = BVec4;
257 #[inline]
258 fn bitxor(self, rhs: &BVec4) -> BVec4 {
259 (*self).bitxor(*rhs)
260 }
261}
262
263impl BitXor<BVec4> for &BVec4 {
264 type Output = BVec4;
265 #[inline]
266 fn bitxor(self, rhs: BVec4) -> BVec4 {
267 (*self).bitxor(rhs)
268 }
269}
270
271impl BitXorAssign for BVec4 {
272 #[inline]
273 fn bitxor_assign(&mut self, rhs: Self) {
274 *self = self.bitxor(rhs);
275 }
276}
277
278impl BitXorAssign<&Self> for BVec4 {
279 #[inline]
280 fn bitxor_assign(&mut self, rhs: &Self) {
281 self.bitxor_assign(*rhs);
282 }
283}
284
285impl Not for BVec4 {
286 type Output = Self;
287 #[inline]
288 fn not(self) -> Self {
289 Self {
290 x: !self.x,
291 y: !self.y,
292 z: !self.z,
293 w: !self.w,
294 }
295 }
296}
297
298impl Not for &BVec4 {
299 type Output = BVec4;
300 #[inline]
301 fn not(self) -> BVec4 {
302 (*self).not()
303 }
304}
305
306impl fmt::Debug for BVec4 {
307 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
308 let arr = self.into_u32_array();
309 write!(
310 f,
311 "{}({:#x}, {:#x}, {:#x}, {:#x})",
312 stringify!(BVec4),
313 arr[0],
314 arr[1],
315 arr[2],
316 arr[3]
317 )
318 }
319}
320
321impl fmt::Display for BVec4 {
322 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
323 let arr = self.into_bool_array();
324 write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
325 }
326}
327
328impl From<[bool; 4]> for BVec4 {
329 #[inline]
330 fn from(a: [bool; 4]) -> Self {
331 Self::from_array(a)
332 }
333}
334
335impl From<BVec4> for [bool; 4] {
336 #[inline]
337 fn from(mask: BVec4) -> Self {
338 mask.into_bool_array()
339 }
340}
341
342impl From<BVec4> for [u32; 4] {
343 #[inline]
344 fn from(mask: BVec4) -> Self {
345 mask.into_u32_array()
346 }
347}