]> git.lizzy.rs Git - rust.git/blob - crates/core_simd/src/masks.rs
Implement `core::ops` (#10)
[rust.git] / crates / core_simd / src / masks.rs
1 /// The error type returned when converting an integer to a mask fails.
2 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
3 pub struct TryFromMaskError(());
4
5 impl core::fmt::Display for TryFromMaskError {
6     fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
7         write!(f, "mask must have all bits set or unset")
8     }
9 }
10
11 macro_rules! define_mask {
12     { $(#[$attr:meta])* struct $name:ident($type:ty); } => {
13         $(#[$attr])*
14         #[allow(non_camel_case_types)]
15         #[derive(Copy, Clone, Default, PartialEq, PartialOrd, Eq, Ord, Hash)]
16         #[repr(transparent)]
17         pub struct $name(pub(crate) $type);
18
19         impl $name {
20             /// Construct a mask from the given value.
21             pub const fn new(value: bool) -> Self {
22                 if value {
23                     Self(!0)
24                 } else {
25                     Self(0)
26                 }
27             }
28
29             /// Test if the mask is set.
30             pub const fn test(&self) -> bool {
31                 self.0 != 0
32             }
33         }
34
35         impl core::convert::From<bool> for $name {
36             fn from(value: bool) -> Self {
37                 Self::new(value)
38             }
39         }
40
41         impl core::convert::From<$name> for bool {
42             fn from(mask: $name) -> Self {
43                 mask.test()
44             }
45         }
46
47         impl core::convert::TryFrom<$type> for $name {
48             type Error = TryFromMaskError;
49             fn try_from(value: $type) -> Result<Self, Self::Error> {
50                 if value == 0 || !value == 0 {
51                     Ok(Self(value))
52                 } else {
53                     Err(TryFromMaskError(()))
54                 }
55             }
56         }
57
58         impl core::convert::From<$name> for $type {
59             fn from(value: $name) -> Self {
60                 value.0
61             }
62         }
63
64         impl core::fmt::Debug for $name {
65             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
66                 self.test().fmt(f)
67             }
68         }
69
70         impl core::fmt::Binary for $name {
71             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
72                 <$type as core::fmt::Binary>::fmt(&self.0, f)
73             }
74         }
75
76         impl core::fmt::Octal for $name {
77             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
78                 <$type as core::fmt::Octal>::fmt(&self.0, f)
79             }
80         }
81
82         impl core::fmt::LowerHex for $name {
83             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
84                 <$type as core::fmt::LowerHex>::fmt(&self.0, f)
85             }
86         }
87
88         impl core::fmt::UpperHex for $name {
89             fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
90                 <$type as core::fmt::UpperHex>::fmt(&self.0, f)
91             }
92         }
93     }
94 }
95
96 define_mask! {
97     /// 8-bit mask
98     struct mask8(i8);
99 }
100
101 define_mask! {
102     /// 16-bit mask
103     struct mask16(i16);
104 }
105
106 define_mask! {
107     /// 32-bit mask
108     struct mask32(i32);
109 }
110
111 define_mask! {
112     /// 64-bit mask
113     struct mask64(i64);
114 }
115
116 define_mask! {
117     /// 128-bit mask
118     struct mask128(i128);
119 }
120
121 define_mask! {
122     /// `isize`-wide mask
123     struct masksize(isize);
124 }