1 /// Implemented for bitmask sizes that are supported by the implementation.
2 pub trait LanesAtMost64 {}
3 impl LanesAtMost64 for BitMask<1> {}
4 impl LanesAtMost64 for BitMask<2> {}
5 impl LanesAtMost64 for BitMask<4> {}
6 impl LanesAtMost64 for BitMask<8> {}
7 impl LanesAtMost64 for BitMask<16> {}
8 impl LanesAtMost64 for BitMask<32> {}
9 impl LanesAtMost64 for BitMask<64> {}
11 /// A mask where each lane is represented by a single bit.
12 #[derive(Copy, Clone, Debug)]
14 pub struct BitMask<const LANES: usize>(u64)
16 BitMask<LANES>: LanesAtMost64;
18 impl<const LANES: usize> BitMask<LANES>
22 /// Construct a mask by setting all lanes to the given value.
23 pub fn splat(value: bool) -> Self {
31 /// Tests the value of the specified lane.
34 /// Panics if `lane` is greater than or equal to the number of lanes in the vector.
36 pub fn test(&self, lane: usize) -> bool {
37 assert!(lane < LANES, "lane index out of range");
38 (self.0 >> lane) & 0x1 > 0
41 /// Sets the value of the specified lane.
44 /// Panics if `lane` is greater than or equal to the number of lanes in the vector.
46 pub fn set(&mut self, lane: usize, value: bool) {
47 assert!(lane < LANES, "lane index out of range");
48 self.0 ^= ((value ^ self.test(lane)) as u64) << lane
52 impl<const LANES: usize> core::ops::BitAnd for BitMask<LANES>
58 fn bitand(self, rhs: Self) -> Self {
63 impl<const LANES: usize> core::ops::BitAnd<bool> for BitMask<LANES>
69 fn bitand(self, rhs: bool) -> Self {
70 self & Self::splat(rhs)
74 impl<const LANES: usize> core::ops::BitAnd<BitMask<LANES>> for bool
76 BitMask<LANES>: LanesAtMost64,
78 type Output = BitMask<LANES>;
80 fn bitand(self, rhs: BitMask<LANES>) -> BitMask<LANES> {
81 BitMask::<LANES>::splat(self) & rhs
85 impl<const LANES: usize> core::ops::BitOr for BitMask<LANES>
91 fn bitor(self, rhs: Self) -> Self {
96 impl<const LANES: usize> core::ops::BitOr<bool> for BitMask<LANES>
102 fn bitor(self, rhs: bool) -> Self {
103 self | Self::splat(rhs)
107 impl<const LANES: usize> core::ops::BitOr<BitMask<LANES>> for bool
109 BitMask<LANES>: LanesAtMost64,
111 type Output = BitMask<LANES>;
113 fn bitor(self, rhs: BitMask<LANES>) -> BitMask<LANES> {
114 BitMask::<LANES>::splat(self) | rhs
118 impl<const LANES: usize> core::ops::BitXor for BitMask<LANES>
124 fn bitxor(self, rhs: Self) -> Self::Output {
129 impl<const LANES: usize> core::ops::BitXor<bool> for BitMask<LANES>
135 fn bitxor(self, rhs: bool) -> Self::Output {
136 self ^ Self::splat(rhs)
140 impl<const LANES: usize> core::ops::BitXor<BitMask<LANES>> for bool
142 BitMask<LANES>: LanesAtMost64,
144 type Output = BitMask<LANES>;
146 fn bitxor(self, rhs: BitMask<LANES>) -> Self::Output {
147 BitMask::<LANES>::splat(self) ^ rhs
151 impl<const LANES: usize> core::ops::Not for BitMask<LANES>
155 type Output = BitMask<LANES>;
157 fn not(self) -> Self::Output {
162 impl<const LANES: usize> core::ops::BitAndAssign for BitMask<LANES>
167 fn bitand_assign(&mut self, rhs: Self) {
172 impl<const LANES: usize> core::ops::BitAndAssign<bool> for BitMask<LANES>
177 fn bitand_assign(&mut self, rhs: bool) {
178 *self &= Self::splat(rhs);
182 impl<const LANES: usize> core::ops::BitOrAssign for BitMask<LANES>
187 fn bitor_assign(&mut self, rhs: Self) {
192 impl<const LANES: usize> core::ops::BitOrAssign<bool> for BitMask<LANES>
197 fn bitor_assign(&mut self, rhs: bool) {
198 *self |= Self::splat(rhs);
202 impl<const LANES: usize> core::ops::BitXorAssign for BitMask<LANES>
207 fn bitxor_assign(&mut self, rhs: Self) {
212 impl<const LANES: usize> core::ops::BitXorAssign<bool> for BitMask<LANES>
217 fn bitxor_assign(&mut self, rhs: bool) {
218 *self ^= Self::splat(rhs);