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 BitAndAssign for BVec4 {
145 #[inline]
146 fn bitand_assign(&mut self, rhs: Self) {
147 *self = self.bitand(rhs);
148 }
149}
150
151impl BitOr for BVec4 {
152 type Output = Self;
153 #[inline]
154 fn bitor(self, rhs: Self) -> Self {
155 Self {
156 x: self.x | rhs.x,
157 y: self.y | rhs.y,
158 z: self.z | rhs.z,
159 w: self.w | rhs.w,
160 }
161 }
162}
163
164impl BitOrAssign for BVec4 {
165 #[inline]
166 fn bitor_assign(&mut self, rhs: Self) {
167 *self = self.bitor(rhs);
168 }
169}
170
171impl BitXor for BVec4 {
172 type Output = Self;
173 #[inline]
174 fn bitxor(self, rhs: Self) -> Self {
175 Self {
176 x: self.x ^ rhs.x,
177 y: self.y ^ rhs.y,
178 z: self.z ^ rhs.z,
179 w: self.w ^ rhs.w,
180 }
181 }
182}
183
184impl BitXorAssign for BVec4 {
185 #[inline]
186 fn bitxor_assign(&mut self, rhs: Self) {
187 *self = self.bitxor(rhs);
188 }
189}
190
191impl Not for BVec4 {
192 type Output = Self;
193 #[inline]
194 fn not(self) -> Self {
195 Self {
196 x: !self.x,
197 y: !self.y,
198 z: !self.z,
199 w: !self.w,
200 }
201 }
202}
203
204impl fmt::Debug for BVec4 {
205 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
206 let arr = self.into_u32_array();
207 write!(
208 f,
209 "{}({:#x}, {:#x}, {:#x}, {:#x})",
210 stringify!(BVec4),
211 arr[0],
212 arr[1],
213 arr[2],
214 arr[3]
215 )
216 }
217}
218
219impl fmt::Display for BVec4 {
220 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 let arr = self.into_bool_array();
222 write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
223 }
224}
225
226impl From<[bool; 4]> for BVec4 {
227 #[inline]
228 fn from(a: [bool; 4]) -> Self {
229 Self::from_array(a)
230 }
231}
232
233impl From<BVec4> for [bool; 4] {
234 #[inline]
235 fn from(mask: BVec4) -> Self {
236 mask.into_bool_array()
237 }
238}
239
240impl From<BVec4> for [u32; 4] {
241 #[inline]
242 fn from(mask: BVec4) -> Self {
243 mask.into_u32_array()
244 }
245}