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