1 // Generated from vec_mask.rs.tera template. Edit the template, not the generated file.
2 
3 #[cfg(not(target_arch = "spirv"))]
4 use core::fmt;
5 use core::ops::*;
6 
7 #[cfg(target_arch = "x86")]
8 use core::arch::x86::*;
9 #[cfg(target_arch = "x86_64")]
10 use core::arch::x86_64::*;
11 
12 #[repr(C)]
13 union UnionCast {
14     a: [u32; 4],
15     v: BVec3A,
16 }
17 
18 /// A 3-dimensional SIMD vector mask.
19 ///
20 /// This type is 16 byte aligned.
21 #[derive(Clone, Copy)]
22 #[repr(transparent)]
23 pub struct BVec3A(pub(crate) __m128);
24 
25 const MASK: [u32; 2] = [0, 0xff_ff_ff_ff];
26 
27 impl BVec3A {
28     /// All false.
29     pub const FALSE: Self = Self::splat(false);
30 
31     /// All true.
32     pub const TRUE: Self = Self::splat(true);
33 
34     /// Creates a new vector mask.
35     #[inline(always)]
36     #[must_use]
new(x: bool, y: bool, z: bool) -> Self37     pub const fn new(x: bool, y: bool, z: bool) -> Self {
38         unsafe {
39             UnionCast {
40                 a: [MASK[x as usize], MASK[y as usize], MASK[z as usize], 0],
41             }
42             .v
43         }
44     }
45 
46     /// Creates a vector with all elements set to `v`.
47     #[inline]
48     #[must_use]
splat(v: bool) -> Self49     pub const fn splat(v: bool) -> Self {
50         Self::new(v, v, v)
51     }
52 
53     /// Returns a bitmask with the lowest 3 bits set from the elements of `self`.
54     ///
55     /// A true element results in a `1` bit and a false element in a `0` bit.  Element `x` goes
56     /// into the first lowest bit, element `y` into the second, etc.
57     #[inline]
58     #[must_use]
bitmask(self) -> u3259     pub fn bitmask(self) -> u32 {
60         unsafe { (_mm_movemask_ps(self.0) as u32) & 0x7 }
61     }
62 
63     /// Returns true if any of the elements are true, false otherwise.
64     #[inline]
65     #[must_use]
any(self) -> bool66     pub fn any(self) -> bool {
67         self.bitmask() != 0
68     }
69 
70     /// Returns true if all the elements are true, false otherwise.
71     #[inline]
72     #[must_use]
all(self) -> bool73     pub fn all(self) -> bool {
74         self.bitmask() == 0x7
75     }
76 
77     /// Tests the value at `index`.
78     ///
79     /// Panics if `index` is greater than 2.
80     #[inline]
81     #[must_use]
test(&self, index: usize) -> bool82     pub fn test(&self, index: usize) -> bool {
83         match index {
84             0 => (self.bitmask() & (1 << 0)) != 0,
85             1 => (self.bitmask() & (1 << 1)) != 0,
86             2 => (self.bitmask() & (1 << 2)) != 0,
87             _ => panic!("index out of bounds"),
88         }
89     }
90 
91     /// Sets the element at `index`.
92     ///
93     /// Panics if `index` is greater than 2.
94     #[inline]
set(&mut self, index: usize, value: bool)95     pub fn set(&mut self, index: usize, value: bool) {
96         use crate::Vec3A;
97         let mut v = Vec3A(self.0);
98         v[index] = f32::from_bits(MASK[value as usize]);
99         *self = Self(v.0);
100     }
101 
102     #[inline]
103     #[must_use]
into_bool_array(self) -> [bool; 3]104     fn into_bool_array(self) -> [bool; 3] {
105         let bitmask = self.bitmask();
106         [(bitmask & 1) != 0, (bitmask & 2) != 0, (bitmask & 4) != 0]
107     }
108 
109     #[inline]
110     #[must_use]
into_u32_array(self) -> [u32; 3]111     fn into_u32_array(self) -> [u32; 3] {
112         let bitmask = self.bitmask();
113         [
114             MASK[(bitmask & 1) as usize],
115             MASK[((bitmask >> 1) & 1) as usize],
116             MASK[((bitmask >> 2) & 1) as usize],
117         ]
118     }
119 }
120 
121 impl Default for BVec3A {
122     #[inline]
default() -> Self123     fn default() -> Self {
124         Self::FALSE
125     }
126 }
127 
128 impl PartialEq for BVec3A {
129     #[inline]
eq(&self, rhs: &Self) -> bool130     fn eq(&self, rhs: &Self) -> bool {
131         self.bitmask().eq(&rhs.bitmask())
132     }
133 }
134 
135 impl Eq for BVec3A {}
136 
137 impl core::hash::Hash for BVec3A {
138     #[inline]
hash<H: core::hash::Hasher>(&self, state: &mut H)139     fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
140         self.bitmask().hash(state);
141     }
142 }
143 
144 impl BitAnd for BVec3A {
145     type Output = Self;
146     #[inline]
bitand(self, rhs: Self) -> Self147     fn bitand(self, rhs: Self) -> Self {
148         Self(unsafe { _mm_and_ps(self.0, rhs.0) })
149     }
150 }
151 
152 impl BitAndAssign for BVec3A {
153     #[inline]
bitand_assign(&mut self, rhs: Self)154     fn bitand_assign(&mut self, rhs: Self) {
155         *self = self.bitand(rhs);
156     }
157 }
158 
159 impl BitOr for BVec3A {
160     type Output = Self;
161     #[inline]
bitor(self, rhs: Self) -> Self162     fn bitor(self, rhs: Self) -> Self {
163         Self(unsafe { _mm_or_ps(self.0, rhs.0) })
164     }
165 }
166 
167 impl BitOrAssign for BVec3A {
168     #[inline]
bitor_assign(&mut self, rhs: Self)169     fn bitor_assign(&mut self, rhs: Self) {
170         *self = self.bitor(rhs);
171     }
172 }
173 
174 impl BitXor for BVec3A {
175     type Output = Self;
176     #[inline]
bitxor(self, rhs: Self) -> Self177     fn bitxor(self, rhs: Self) -> Self {
178         Self(unsafe { _mm_xor_ps(self.0, rhs.0) })
179     }
180 }
181 
182 impl BitXorAssign for BVec3A {
183     #[inline]
bitxor_assign(&mut self, rhs: Self)184     fn bitxor_assign(&mut self, rhs: Self) {
185         *self = self.bitxor(rhs);
186     }
187 }
188 
189 impl Not for BVec3A {
190     type Output = Self;
191     #[inline]
not(self) -> Self192     fn not(self) -> Self {
193         Self(unsafe { _mm_andnot_ps(self.0, _mm_set_ps1(f32::from_bits(0xff_ff_ff_ff))) })
194     }
195 }
196 
197 impl From<BVec3A> for __m128 {
198     #[inline]
from(t: BVec3A) -> Self199     fn from(t: BVec3A) -> Self {
200         t.0
201     }
202 }
203 
204 #[cfg(not(target_arch = "spirv"))]
205 impl fmt::Debug for BVec3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result206     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207         let arr = self.into_u32_array();
208         write!(
209             f,
210             "{}({:#x}, {:#x}, {:#x})",
211             stringify!(BVec3A),
212             arr[0],
213             arr[1],
214             arr[2]
215         )
216     }
217 }
218 
219 #[cfg(not(target_arch = "spirv"))]
220 impl fmt::Display for BVec3A {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result221     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222         let arr = self.into_bool_array();
223         write!(f, "[{}, {}, {}]", arr[0], arr[1], arr[2])
224     }
225 }
226 
227 impl From<BVec3A> for [bool; 3] {
228     #[inline]
from(mask: BVec3A) -> Self229     fn from(mask: BVec3A) -> Self {
230         mask.into_bool_array()
231     }
232 }
233 
234 impl From<BVec3A> for [u32; 3] {
235     #[inline]
from(mask: BVec3A) -> Self236     fn from(mask: BVec3A) -> Self {
237         mask.into_u32_array()
238     }
239 }
240