1#[inline(always)]
2pub const fn splat_4(b: u8) -> u32 {
3 u32::from_ne_bytes([b; 4])
4}
5
6#[inline(always)]
7pub const fn splat_8(b: u8) -> u64 {
8 u64::from_ne_bytes([b; 8])
9}
10
11
12macro_rules! bitmask_impl {
13 ($name:ident, $ty:ident, $splat:ident) => {
14 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
15 pub struct $name($ty);
16
17 impl $name {
18 pub const NONE: Self = Self(0);
19 pub const ALL: Self = Self($splat(0x80));
20
21 #[inline(always)]
22 pub const fn from_bits(bits: $ty) -> Self { Self(bits) }
23
24
25 #[inline(always)]
26 pub const fn none(self) -> bool { self.0 == 0 }
27
28 #[inline(always)]
29 pub const fn any(self) -> bool { self.0 != 0 }
30
31 #[inline(always)]
32 pub const fn all(self) -> bool { self.0 == $splat(0x80) }
33
34
35 #[inline(always)]
36 pub fn not(self) -> Self {
37 Self(self.0 ^ $splat(0x80))
38 }
39
40
41 #[inline]
42 pub fn find_zero_bytes(value: $ty) -> Self {
43 let zero_or_high = value.wrapping_sub($splat(1));
45 let not_high = !value & $splat(0x80);
46 let mask = zero_or_high & not_high;
47 Self(mask)
48 }
49
50 #[inline(always)]
51 pub fn find_equal_bytes(value: $ty, byte: u8) -> Self {
52 Self::find_zero_bytes(value ^ $splat(byte))
53 }
54
55 #[inline(always)]
56 pub fn find_high_bit_bytes(value: $ty) -> Self {
57 Self(value & $splat(0x80))
58 }
59 }
60
61 impl Iterator for $name {
62 type Item = usize;
63
64 #[inline(always)]
65 fn next(&mut self) -> Option<Self::Item> {
66 if self.0 != 0 {
67 let i = self.0.trailing_zeros() / 8;
68 self.0 &= self.0 - 1;
69 return Some(i as usize);
70 }
71 return None;
72 }
73 }
74
75 impl core::ops::BitAnd for $name {
76 type Output = Self;
77
78 #[inline(always)]
79 fn bitand(self, rhs: Self) -> Self {
80 Self(self.0 & rhs.0)
81 }
82 }
83
84 impl core::ops::BitOr for $name {
85 type Output = Self;
86
87 #[inline(always)]
88 fn bitor(self, rhs: Self) -> Self {
89 Self(self.0 | rhs.0)
90 }
91 }
92
93 impl core::ops::Not for $name {
94 type Output = Self;
95
96 #[inline(always)]
97 fn not(self) -> Self {
98 Self::not(self)
99 }
100 }
101 }
102}
103
104bitmask_impl!(Bitmask4, u32, splat_4);
105bitmask_impl!(Bitmask8, u64, splat_8);
106