• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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