1#[cfg(not(target_arch = "spirv"))]
4use core::fmt;
5use core::ops::*;
6
7#[derive(Clone, Copy, PartialEq, Eq, Hash)]
9#[repr(C, align(1))]
10pub struct BVec2 {
11 pub x: bool,
12 pub y: bool,
13}
14
15const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
16
17impl BVec2 {
18 pub const FALSE: Self = Self::splat(false);
20
21 pub const TRUE: Self = Self::splat(true);
23
24 #[inline(always)]
26 #[must_use]
27 pub const fn new(x: bool, y: bool) -> Self {
28 Self { x, y }
29 }
30
31 #[inline]
33 #[must_use]
34 pub const fn splat(v: bool) -> Self {
35 Self::new(v, v)
36 }
37
38 #[inline]
40 #[must_use]
41 pub const fn from_array(a: [bool; 2]) -> Self {
42 Self::new(a[0], a[1])
43 }
44
45 #[inline]
50 #[must_use]
51 pub fn bitmask(self) -> u32 {
52 (self.x as u32) | (self.y as u32) << 1
53 }
54
55 #[inline]
57 #[must_use]
58 pub fn any(self) -> bool {
59 self.x || self.y
60 }
61
62 #[inline]
64 #[must_use]
65 pub fn all(self) -> bool {
66 self.x && self.y
67 }
68
69 #[inline]
73 #[must_use]
74 pub fn test(&self, index: usize) -> bool {
75 match index {
76 0 => self.x,
77 1 => self.y,
78 _ => panic!("index out of bounds"),
79 }
80 }
81
82 #[inline]
86 pub fn set(&mut self, index: usize, value: bool) {
87 match index {
88 0 => self.x = value,
89 1 => self.y = value,
90 _ => panic!("index out of bounds"),
91 }
92 }
93
94 #[inline]
95 #[must_use]
96 fn into_bool_array(self) -> [bool; 2] {
97 [self.x, self.y]
98 }
99
100 #[inline]
101 #[must_use]
102 fn into_u32_array(self) -> [u32; 2] {
103 [MASK[self.x as usize], MASK[self.y as usize]]
104 }
105}
106
107impl Default for BVec2 {
108 #[inline]
109 fn default() -> Self {
110 Self::FALSE
111 }
112}
113
114impl BitAnd for BVec2 {
115 type Output = Self;
116 #[inline]
117 fn bitand(self, rhs: Self) -> Self {
118 Self {
119 x: self.x & rhs.x,
120 y: self.y & rhs.y,
121 }
122 }
123}
124
125impl BitAndAssign for BVec2 {
126 #[inline]
127 fn bitand_assign(&mut self, rhs: Self) {
128 *self = self.bitand(rhs);
129 }
130}
131
132impl BitOr for BVec2 {
133 type Output = Self;
134 #[inline]
135 fn bitor(self, rhs: Self) -> Self {
136 Self {
137 x: self.x | rhs.x,
138 y: self.y | rhs.y,
139 }
140 }
141}
142
143impl BitOrAssign for BVec2 {
144 #[inline]
145 fn bitor_assign(&mut self, rhs: Self) {
146 *self = self.bitor(rhs);
147 }
148}
149
150impl BitXor for BVec2 {
151 type Output = Self;
152 #[inline]
153 fn bitxor(self, rhs: Self) -> Self {
154 Self {
155 x: self.x ^ rhs.x,
156 y: self.y ^ rhs.y,
157 }
158 }
159}
160
161impl BitXorAssign for BVec2 {
162 #[inline]
163 fn bitxor_assign(&mut self, rhs: Self) {
164 *self = self.bitxor(rhs);
165 }
166}
167
168impl Not for BVec2 {
169 type Output = Self;
170 #[inline]
171 fn not(self) -> Self {
172 Self {
173 x: !self.x,
174 y: !self.y,
175 }
176 }
177}
178
179#[cfg(not(target_arch = "spirv"))]
180impl fmt::Debug for BVec2 {
181 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
182 let arr = self.into_u32_array();
183 write!(f, "{}({:#x}, {:#x})", stringify!(BVec2), arr[0], arr[1])
184 }
185}
186
187#[cfg(not(target_arch = "spirv"))]
188impl fmt::Display for BVec2 {
189 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 let arr = self.into_bool_array();
191 write!(f, "[{}, {}]", arr[0], arr[1])
192 }
193}
194
195impl From<[bool; 2]> for BVec2 {
196 #[inline]
197 fn from(a: [bool; 2]) -> Self {
198 Self::from_array(a)
199 }
200}
201
202impl From<BVec2> for [bool; 2] {
203 #[inline]
204 fn from(mask: BVec2) -> Self {
205 mask.into_bool_array()
206 }
207}
208
209impl From<BVec2> for [u32; 2] {
210 #[inline]
211 fn from(mask: BVec2) -> Self {
212 mask.into_u32_array()
213 }
214}