1 use super::{mask_impl, Mask, MaskElement};
2 use crate::simd::{LaneCount, SupportedLaneCount};
3
4 mod sealed {
5 pub trait Sealed {}
6 }
7 pub use sealed::Sealed;
8
9 impl<T, const LANES: usize> Sealed for Mask<T, LANES>
10 where
11 T: MaskElement,
12 LaneCount<LANES>: SupportedLaneCount,
13 {
14 }
15
16 /// Converts masks to and from integer bitmasks.
17 ///
18 /// Each bit of the bitmask corresponds to a mask lane, starting with the LSB.
19 pub trait ToBitMask: Sealed {
20 /// The integer bitmask type.
21 type BitMask;
22
23 /// Converts a mask to a bitmask.
to_bitmask(self) -> Self::BitMask24 fn to_bitmask(self) -> Self::BitMask;
25
26 /// Converts a bitmask to a mask.
from_bitmask(bitmask: Self::BitMask) -> Self27 fn from_bitmask(bitmask: Self::BitMask) -> Self;
28 }
29
30 /// Converts masks to and from byte array bitmasks.
31 ///
32 /// Each bit of the bitmask corresponds to a mask lane, starting with the LSB of the first byte.
33 #[cfg(feature = "generic_const_exprs")]
34 pub trait ToBitMaskArray: Sealed {
35 /// The length of the bitmask array.
36 const BYTES: usize;
37
38 /// Converts a mask to a bitmask.
to_bitmask_array(self) -> [u8; Self::BYTES]39 fn to_bitmask_array(self) -> [u8; Self::BYTES];
40
41 /// Converts a bitmask to a mask.
from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self42 fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self;
43 }
44
45 macro_rules! impl_integer_intrinsic {
46 { $(impl ToBitMask<BitMask=$int:ty> for Mask<_, $lanes:literal>)* } => {
47 $(
48 impl<T: MaskElement> ToBitMask for Mask<T, $lanes> {
49 type BitMask = $int;
50
51 #[inline]
52 fn to_bitmask(self) -> $int {
53 self.0.to_bitmask_integer()
54 }
55
56 #[inline]
57 fn from_bitmask(bitmask: $int) -> Self {
58 Self(mask_impl::Mask::from_bitmask_integer(bitmask))
59 }
60 }
61 )*
62 }
63 }
64
65 impl_integer_intrinsic! {
66 impl ToBitMask<BitMask=u8> for Mask<_, 1>
67 impl ToBitMask<BitMask=u8> for Mask<_, 2>
68 impl ToBitMask<BitMask=u8> for Mask<_, 4>
69 impl ToBitMask<BitMask=u8> for Mask<_, 8>
70 impl ToBitMask<BitMask=u16> for Mask<_, 16>
71 impl ToBitMask<BitMask=u32> for Mask<_, 32>
72 impl ToBitMask<BitMask=u64> for Mask<_, 64>
73 }
74
75 /// Returns the minimum number of bytes in a bitmask with `lanes` lanes.
76 #[cfg(feature = "generic_const_exprs")]
bitmask_len(lanes: usize) -> usize77 pub const fn bitmask_len(lanes: usize) -> usize {
78 (lanes + 7) / 8
79 }
80
81 #[cfg(feature = "generic_const_exprs")]
82 impl<T: MaskElement, const LANES: usize> ToBitMaskArray for Mask<T, LANES>
83 where
84 LaneCount<LANES>: SupportedLaneCount,
85 {
86 const BYTES: usize = bitmask_len(LANES);
87
88 #[inline]
to_bitmask_array(self) -> [u8; Self::BYTES]89 fn to_bitmask_array(self) -> [u8; Self::BYTES] {
90 self.0.to_bitmask_array()
91 }
92
93 #[inline]
from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self94 fn from_bitmask_array(bitmask: [u8; Self::BYTES]) -> Self {
95 Mask(mask_impl::Mask::from_bitmask_array(bitmask))
96 }
97 }
98