]> git.lizzy.rs Git - rust.git/blob - crates/core_simd/src/masks/full_masks.rs
Begin reducing mask API
[rust.git] / crates / core_simd / src / masks / full_masks.rs
1 //! Masks that take up full SIMD vector registers.
2
3 macro_rules! define_mask {
4     {
5         $(#[$attr:meta])*
6         struct $name:ident<const $lanes:ident: usize>(
7             crate::$type:ident<$lanes2:ident>
8         );
9     } => {
10         $(#[$attr])*
11         #[derive(Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
12         #[repr(transparent)]
13         pub struct $name<const $lanes: usize>(crate::$type<$lanes2>)
14         where
15             crate::$type<LANES>: crate::LanesAtMost32;
16
17         impl_full_mask_reductions! { $name, $type }
18
19         impl<const LANES: usize> Copy for $name<LANES>
20         where
21             crate::$type<LANES>: crate::LanesAtMost32,
22         {}
23
24         impl<const LANES: usize> Clone for $name<LANES>
25         where
26             crate::$type<LANES>: crate::LanesAtMost32,
27         {
28             #[inline]
29             fn clone(&self) -> Self {
30                 *self
31             }
32         }
33
34         impl<const LANES: usize> $name<LANES>
35         where
36             crate::$type<LANES>: crate::LanesAtMost32,
37         {
38             pub fn splat(value: bool) -> Self {
39                 Self(<crate::$type<LANES>>::splat(
40                     if value {
41                         -1
42                     } else {
43                         0
44                     }
45                 ))
46             }
47
48             #[inline]
49             pub fn test(&self, lane: usize) -> bool {
50                 assert!(lane < LANES, "lane index out of range");
51                 self.0[lane] == -1
52             }
53
54             #[inline]
55             pub fn set(&mut self, lane: usize, value: bool) {
56                 assert!(lane < LANES, "lane index out of range");
57                 self.0[lane] = if value {
58                     -1
59                 } else {
60                     0
61                 }
62             }
63
64             #[inline]
65             pub fn to_int(self) -> crate::$type<LANES> {
66                 self.0
67             }
68
69             #[inline]
70             pub unsafe fn from_int_unchecked(value: crate::$type<LANES>) -> Self {
71                 Self(value)
72             }
73         }
74
75         impl<const LANES: usize> core::convert::From<$name<LANES>> for crate::$type<LANES>
76         where
77             crate::$type<LANES>: crate::LanesAtMost32,
78         {
79             fn from(value: $name<LANES>) -> Self {
80                 value.0
81             }
82         }
83
84         impl<const LANES: usize> core::fmt::Debug for $name<LANES>
85         where
86             crate::$type<LANES>: crate::LanesAtMost32,
87         {
88             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
89                 f.debug_list()
90                     .entries((0..LANES).map(|lane| self.test(lane)))
91                     .finish()
92             }
93         }
94
95         impl<const LANES: usize> core::fmt::Binary for $name<LANES>
96         where
97             crate::$type<LANES>: crate::LanesAtMost32,
98         {
99             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
100                 core::fmt::Binary::fmt(&self.0, f)
101             }
102         }
103
104         impl<const LANES: usize> core::fmt::Octal for $name<LANES>
105         where
106             crate::$type<LANES>: crate::LanesAtMost32,
107         {
108             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
109                 core::fmt::Octal::fmt(&self.0, f)
110             }
111         }
112
113         impl<const LANES: usize> core::fmt::LowerHex for $name<LANES>
114         where
115             crate::$type<LANES>: crate::LanesAtMost32,
116         {
117             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
118                 core::fmt::LowerHex::fmt(&self.0, f)
119             }
120         }
121
122         impl<const LANES: usize> core::fmt::UpperHex for $name<LANES>
123         where
124             crate::$type<LANES>: crate::LanesAtMost32,
125         {
126             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
127                 core::fmt::UpperHex::fmt(&self.0, f)
128             }
129         }
130
131         impl<const LANES: usize> core::ops::BitAnd for $name<LANES>
132         where
133             crate::$type<LANES>: crate::LanesAtMost32,
134         {
135             type Output = Self;
136             #[inline]
137             fn bitand(self, rhs: Self) -> Self {
138                 Self(self.0 & rhs.0)
139             }
140         }
141
142         impl<const LANES: usize> core::ops::BitOr for $name<LANES>
143         where
144             crate::$type<LANES>: crate::LanesAtMost32,
145         {
146             type Output = Self;
147             #[inline]
148             fn bitor(self, rhs: Self) -> Self {
149                 Self(self.0 | rhs.0)
150             }
151         }
152
153         impl<const LANES: usize> core::ops::BitXor for $name<LANES>
154         where
155             crate::$type<LANES>: crate::LanesAtMost32,
156         {
157             type Output = Self;
158             #[inline]
159             fn bitxor(self, rhs: Self) -> Self::Output {
160                 Self(self.0 ^ rhs.0)
161             }
162         }
163
164         impl<const LANES: usize> core::ops::Not for $name<LANES>
165         where
166             crate::$type<LANES>: crate::LanesAtMost32,
167         {
168             type Output = $name<LANES>;
169             #[inline]
170             fn not(self) -> Self::Output {
171                 Self(!self.0)
172             }
173         }
174
175         impl<const LANES: usize> core::ops::BitAndAssign for $name<LANES>
176         where
177             crate::$type<LANES>: crate::LanesAtMost32,
178         {
179             #[inline]
180             fn bitand_assign(&mut self, rhs: Self) {
181                 self.0 &= rhs.0;
182             }
183         }
184
185         impl<const LANES: usize> core::ops::BitOrAssign for $name<LANES>
186         where
187             crate::$type<LANES>: crate::LanesAtMost32,
188         {
189             #[inline]
190             fn bitor_assign(&mut self, rhs: Self) {
191                 self.0 |= rhs.0;
192             }
193         }
194
195         impl<const LANES: usize> core::ops::BitXorAssign for $name<LANES>
196         where
197             crate::$type<LANES>: crate::LanesAtMost32,
198         {
199             #[inline]
200             fn bitxor_assign(&mut self, rhs: Self) {
201                 self.0 ^= rhs.0;
202             }
203         }
204     }
205 }
206
207 define_mask! {
208     /// A mask equivalent to [SimdI8](crate::SimdI8), where all bits in the lane must be either set
209     /// or unset.
210     struct Mask8<const LANES: usize>(crate::SimdI8<LANES>);
211 }
212
213 define_mask! {
214     /// A mask equivalent to [SimdI16](crate::SimdI16), where all bits in the lane must be either set
215     /// or unset.
216     struct Mask16<const LANES: usize>(crate::SimdI16<LANES>);
217 }
218
219 define_mask! {
220     /// A mask equivalent to [SimdI32](crate::SimdI32), where all bits in the lane must be either set
221     /// or unset.
222     struct Mask32<const LANES: usize>(crate::SimdI32<LANES>);
223 }
224
225 define_mask! {
226     /// A mask equivalent to [SimdI64](crate::SimdI64), where all bits in the lane must be either set
227     /// or unset.
228     struct Mask64<const LANES: usize>(crate::SimdI64<LANES>);
229 }
230
231 define_mask! {
232     /// A mask equivalent to [SimdIsize](crate::SimdIsize), where all bits in the lane must be either set
233     /// or unset.
234     struct MaskSize<const LANES: usize>(crate::SimdIsize<LANES>);
235 }