1 use crate::LanesAtMost64;
3 /// A mask where each lane is represented by a single bit.
4 #[derive(Copy, Clone, Debug)]
6 pub struct BitMask<const LANES: usize>(u64)
8 BitMask<LANES>: LanesAtMost64;
10 impl<const LANES: usize> BitMask<LANES>
14 /// Construct a mask by setting all lanes to the given value.
15 pub fn splat(value: bool) -> Self {
23 /// Tests the value of the specified lane.
26 /// Panics if `lane` is greater than or equal to the number of lanes in the vector.
28 pub fn test(&self, lane: usize) -> bool {
29 assert!(lane < LANES, "lane index out of range");
30 (self.0 >> lane) & 0x1 > 0
33 /// Sets the value of the specified lane.
36 /// Panics if `lane` is greater than or equal to the number of lanes in the vector.
38 pub fn set(&mut self, lane: usize, value: bool) {
39 assert!(lane < LANES, "lane index out of range");
40 self.0 ^= ((value ^ self.test(lane)) as u64) << lane
44 impl<const LANES: usize> core::ops::BitAnd for BitMask<LANES>
50 fn bitand(self, rhs: Self) -> Self {
55 impl<const LANES: usize> core::ops::BitAnd<bool> for BitMask<LANES>
61 fn bitand(self, rhs: bool) -> Self {
62 self & Self::splat(rhs)
66 impl<const LANES: usize> core::ops::BitAnd<BitMask<LANES>> for bool
68 BitMask<LANES>: LanesAtMost64,
70 type Output = BitMask<LANES>;
72 fn bitand(self, rhs: BitMask<LANES>) -> BitMask<LANES> {
73 BitMask::<LANES>::splat(self) & rhs
77 impl<const LANES: usize> core::ops::BitOr for BitMask<LANES>
83 fn bitor(self, rhs: Self) -> Self {
88 impl<const LANES: usize> core::ops::BitOr<bool> for BitMask<LANES>
94 fn bitor(self, rhs: bool) -> Self {
95 self | Self::splat(rhs)
99 impl<const LANES: usize> core::ops::BitOr<BitMask<LANES>> for bool
101 BitMask<LANES>: LanesAtMost64,
103 type Output = BitMask<LANES>;
105 fn bitor(self, rhs: BitMask<LANES>) -> BitMask<LANES> {
106 BitMask::<LANES>::splat(self) | rhs
110 impl<const LANES: usize> core::ops::BitXor for BitMask<LANES>
116 fn bitxor(self, rhs: Self) -> Self::Output {
121 impl<const LANES: usize> core::ops::BitXor<bool> for BitMask<LANES>
127 fn bitxor(self, rhs: bool) -> Self::Output {
128 self ^ Self::splat(rhs)
132 impl<const LANES: usize> core::ops::BitXor<BitMask<LANES>> for bool
134 BitMask<LANES>: LanesAtMost64,
136 type Output = BitMask<LANES>;
138 fn bitxor(self, rhs: BitMask<LANES>) -> Self::Output {
139 BitMask::<LANES>::splat(self) ^ rhs
143 impl<const LANES: usize> core::ops::Not for BitMask<LANES>
147 type Output = BitMask<LANES>;
149 fn not(self) -> Self::Output {
154 impl<const LANES: usize> core::ops::BitAndAssign for BitMask<LANES>
159 fn bitand_assign(&mut self, rhs: Self) {
164 impl<const LANES: usize> core::ops::BitAndAssign<bool> for BitMask<LANES>
169 fn bitand_assign(&mut self, rhs: bool) {
170 *self &= Self::splat(rhs);
174 impl<const LANES: usize> core::ops::BitOrAssign for BitMask<LANES>
179 fn bitor_assign(&mut self, rhs: Self) {
184 impl<const LANES: usize> core::ops::BitOrAssign<bool> for BitMask<LANES>
189 fn bitor_assign(&mut self, rhs: bool) {
190 *self |= Self::splat(rhs);
194 impl<const LANES: usize> core::ops::BitXorAssign for BitMask<LANES>
199 fn bitxor_assign(&mut self, rhs: Self) {
204 impl<const LANES: usize> core::ops::BitXorAssign<bool> for BitMask<LANES>
209 fn bitxor_assign(&mut self, rhs: bool) {
210 *self ^= Self::splat(rhs);