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 #[track_caller]
84 pub fn test(self, index: usize) -> bool {
85 match index {
86 0 => self.x,
87 1 => self.y,
88 2 => self.z,
89 3 => self.w,
90 _ => panic!("index out of bounds"),
91 }
92 }
93
94 #[inline]
98 #[track_caller]
99 pub fn set(&mut self, index: usize, value: bool) {
100 match index {
101 0 => self.x = value,
102 1 => self.y = value,
103 2 => self.z = value,
104 3 => self.w = value,
105 _ => panic!("index out of bounds"),
106 }
107 }
108
109 #[inline]
110 #[must_use]
111 fn into_bool_array(self) -> [bool; 4] {
112 [self.x, self.y, self.z, self.w]
113 }
114
115 #[inline]
116 #[must_use]
117 fn into_u32_array(self) -> [u32; 4] {
118 [
119 MASK[self.x as usize],
120 MASK[self.y as usize],
121 MASK[self.z as usize],
122 MASK[self.w as usize],
123 ]
124 }
125}
126
127impl Default for BVec4 {
128 #[inline]
129 fn default() -> Self {
130 Self::FALSE
131 }
132}
133
134impl BitAnd for BVec4 {
135 type Output = Self;
136 #[inline]
137 fn bitand(self, rhs: Self) -> Self {
138 Self {
139 x: self.x & rhs.x,
140 y: self.y & rhs.y,
141 z: self.z & rhs.z,
142 w: self.w & rhs.w,
143 }
144 }
145}
146
147impl BitAnd<&Self> for BVec4 {
148 type Output = Self;
149 #[inline]
150 fn bitand(self, rhs: &Self) -> Self {
151 self.bitand(*rhs)
152 }
153}
154
155impl BitAnd<&BVec4> for &BVec4 {
156 type Output = BVec4;
157 #[inline]
158 fn bitand(self, rhs: &BVec4) -> BVec4 {
159 (*self).bitand(*rhs)
160 }
161}
162
163impl BitAnd<BVec4> for &BVec4 {
164 type Output = BVec4;
165 #[inline]
166 fn bitand(self, rhs: BVec4) -> BVec4 {
167 (*self).bitand(rhs)
168 }
169}
170
171impl BitAndAssign for BVec4 {
172 #[inline]
173 fn bitand_assign(&mut self, rhs: Self) {
174 *self = self.bitand(rhs);
175 }
176}
177
178impl BitAndAssign<&Self> for BVec4 {
179 #[inline]
180 fn bitand_assign(&mut self, rhs: &Self) {
181 self.bitand_assign(*rhs);
182 }
183}
184
185impl BitOr for BVec4 {
186 type Output = Self;
187 #[inline]
188 fn bitor(self, rhs: Self) -> Self {
189 Self {
190 x: self.x | rhs.x,
191 y: self.y | rhs.y,
192 z: self.z | rhs.z,
193 w: self.w | rhs.w,
194 }
195 }
196}
197
198impl BitOr<&Self> for BVec4 {
199 type Output = Self;
200 #[inline]
201 fn bitor(self, rhs: &Self) -> Self {
202 self.bitor(*rhs)
203 }
204}
205
206impl BitOr<&BVec4> for &BVec4 {
207 type Output = BVec4;
208 #[inline]
209 fn bitor(self, rhs: &BVec4) -> BVec4 {
210 (*self).bitor(*rhs)
211 }
212}
213
214impl BitOr<BVec4> for &BVec4 {
215 type Output = BVec4;
216 #[inline]
217 fn bitor(self, rhs: BVec4) -> BVec4 {
218 (*self).bitor(rhs)
219 }
220}
221
222impl BitOrAssign for BVec4 {
223 #[inline]
224 fn bitor_assign(&mut self, rhs: Self) {
225 *self = self.bitor(rhs);
226 }
227}
228
229impl BitOrAssign<&Self> for BVec4 {
230 #[inline]
231 fn bitor_assign(&mut self, rhs: &Self) {
232 self.bitor_assign(*rhs);
233 }
234}
235
236impl BitXor for BVec4 {
237 type Output = Self;
238 #[inline]
239 fn bitxor(self, rhs: Self) -> Self {
240 Self {
241 x: self.x ^ rhs.x,
242 y: self.y ^ rhs.y,
243 z: self.z ^ rhs.z,
244 w: self.w ^ rhs.w,
245 }
246 }
247}
248
249impl BitXor<&Self> for BVec4 {
250 type Output = Self;
251 #[inline]
252 fn bitxor(self, rhs: &Self) -> Self {
253 self.bitxor(*rhs)
254 }
255}
256
257impl BitXor<&BVec4> for &BVec4 {
258 type Output = BVec4;
259 #[inline]
260 fn bitxor(self, rhs: &BVec4) -> BVec4 {
261 (*self).bitxor(*rhs)
262 }
263}
264
265impl BitXor<BVec4> for &BVec4 {
266 type Output = BVec4;
267 #[inline]
268 fn bitxor(self, rhs: BVec4) -> BVec4 {
269 (*self).bitxor(rhs)
270 }
271}
272
273impl BitXorAssign for BVec4 {
274 #[inline]
275 fn bitxor_assign(&mut self, rhs: Self) {
276 *self = self.bitxor(rhs);
277 }
278}
279
280impl BitXorAssign<&Self> for BVec4 {
281 #[inline]
282 fn bitxor_assign(&mut self, rhs: &Self) {
283 self.bitxor_assign(*rhs);
284 }
285}
286
287impl Not for BVec4 {
288 type Output = Self;
289 #[inline]
290 fn not(self) -> Self {
291 Self {
292 x: !self.x,
293 y: !self.y,
294 z: !self.z,
295 w: !self.w,
296 }
297 }
298}
299
300impl Not for &BVec4 {
301 type Output = BVec4;
302 #[inline]
303 fn not(self) -> BVec4 {
304 (*self).not()
305 }
306}
307
308impl fmt::Debug for BVec4 {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 let arr = self.into_u32_array();
311 write!(
312 f,
313 "{}({:#x}, {:#x}, {:#x}, {:#x})",
314 stringify!(BVec4),
315 arr[0],
316 arr[1],
317 arr[2],
318 arr[3]
319 )
320 }
321}
322
323impl fmt::Display for BVec4 {
324 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
325 let arr = self.into_bool_array();
326 write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
327 }
328}
329
330impl From<[bool; 4]> for BVec4 {
331 #[inline]
332 fn from(a: [bool; 4]) -> Self {
333 Self::from_array(a)
334 }
335}
336
337impl From<BVec4> for [bool; 4] {
338 #[inline]
339 fn from(mask: BVec4) -> Self {
340 mask.into_bool_array()
341 }
342}
343
344impl From<BVec4> for [u32; 4] {
345 #[inline]
346 fn from(mask: BVec4) -> Self {
347 mask.into_u32_array()
348 }
349}