1#[cfg(not(target_arch = "spirv"))]
4use core::fmt;
5use core::ops::*;
6
7#[inline(always)]
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 pub const fn new(x: bool, y: bool, z: bool, w: bool) -> Self {
35 Self { x, y, z, w }
36 }
37
38 #[inline]
40 pub const fn splat(v: bool) -> Self {
41 Self::new(v, v, v, v)
42 }
43
44 #[inline]
49 pub fn bitmask(self) -> u32 {
50 (self.x as u32) | (self.y as u32) << 1 | (self.z as u32) << 2 | (self.w as u32) << 3
51 }
52
53 #[inline]
55 pub fn any(self) -> bool {
56 self.x || self.y || self.z || self.w
57 }
58
59 #[inline]
61 pub fn all(self) -> bool {
62 self.x && self.y && self.z && self.w
63 }
64
65 #[inline]
69 pub fn test(&self, index: usize) -> bool {
70 match index {
71 0 => self.x,
72 1 => self.y,
73 2 => self.z,
74 3 => self.w,
75 _ => panic!("index out of bounds"),
76 }
77 }
78
79 #[inline]
83 pub fn set(&mut self, index: usize, value: bool) {
84 match index {
85 0 => self.x = value,
86 1 => self.y = value,
87 2 => self.z = value,
88 3 => self.w = value,
89 _ => panic!("index out of bounds"),
90 }
91 }
92
93 #[inline]
94 fn into_bool_array(self) -> [bool; 4] {
95 [self.x, self.y, self.z, self.w]
96 }
97
98 #[inline]
99 fn into_u32_array(self) -> [u32; 4] {
100 [
101 MASK[self.x as usize],
102 MASK[self.y as usize],
103 MASK[self.z as usize],
104 MASK[self.w as usize],
105 ]
106 }
107}
108
109impl Default for BVec4 {
110 #[inline]
111 fn default() -> Self {
112 Self::FALSE
113 }
114}
115
116impl BitAnd for BVec4 {
117 type Output = Self;
118 #[inline]
119 fn bitand(self, rhs: Self) -> Self {
120 Self {
121 x: self.x & rhs.x,
122 y: self.y & rhs.y,
123 z: self.z & rhs.z,
124 w: self.w & rhs.w,
125 }
126 }
127}
128
129impl BitAndAssign for BVec4 {
130 #[inline]
131 fn bitand_assign(&mut self, rhs: Self) {
132 *self = self.bitand(rhs);
133 }
134}
135
136impl BitOr for BVec4 {
137 type Output = Self;
138 #[inline]
139 fn bitor(self, rhs: Self) -> Self {
140 Self {
141 x: self.x | rhs.x,
142 y: self.y | rhs.y,
143 z: self.z | rhs.z,
144 w: self.w | rhs.w,
145 }
146 }
147}
148
149impl BitOrAssign for BVec4 {
150 #[inline]
151 fn bitor_assign(&mut self, rhs: Self) {
152 *self = self.bitor(rhs);
153 }
154}
155
156impl BitXor for BVec4 {
157 type Output = Self;
158 #[inline]
159 fn bitxor(self, rhs: Self) -> Self {
160 Self {
161 x: self.x ^ rhs.x,
162 y: self.y ^ rhs.y,
163 z: self.z ^ rhs.z,
164 w: self.w ^ rhs.w,
165 }
166 }
167}
168
169impl BitXorAssign for BVec4 {
170 #[inline]
171 fn bitxor_assign(&mut self, rhs: Self) {
172 *self = self.bitxor(rhs);
173 }
174}
175
176impl Not for BVec4 {
177 type Output = Self;
178 #[inline]
179 fn not(self) -> Self {
180 Self {
181 x: !self.x,
182 y: !self.y,
183 z: !self.z,
184 w: !self.w,
185 }
186 }
187}
188
189#[cfg(not(target_arch = "spirv"))]
190impl fmt::Debug for BVec4 {
191 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
192 let arr = self.into_u32_array();
193 write!(
194 f,
195 "{}({:#x}, {:#x}, {:#x}, {:#x})",
196 stringify!(BVec4),
197 arr[0],
198 arr[1],
199 arr[2],
200 arr[3]
201 )
202 }
203}
204
205#[cfg(not(target_arch = "spirv"))]
206impl fmt::Display for BVec4 {
207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
208 let arr = self.into_bool_array();
209 write!(f, "[{}, {}, {}, {}]", arr[0], arr[1], arr[2], arr[3])
210 }
211}
212
213impl From<BVec4> for [bool; 4] {
214 #[inline]
215 fn from(mask: BVec4) -> Self {
216 mask.into_bool_array()
217 }
218}
219
220impl From<BVec4> for [u32; 4] {
221 #[inline]
222 fn from(mask: BVec4) -> Self {
223 mask.into_u32_array()
224 }
225}