1use core::fmt;
2
3use crate::TAG_MASK;
4
5#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub struct Tag(pub(crate) usize);
11
12impl Tag {
13 #[inline]
15 pub const fn new(value: usize) -> Self {
16 Self(value & TAG_MASK)
17 }
18
19 #[inline]
21 pub const fn value(self) -> usize {
22 self.0
23 }
24
25 #[inline]
27 pub const fn wrapping_add(self, rhs: usize) -> Self {
28 Self::new(self.0.wrapping_add(rhs))
29 }
30
31 #[inline]
33 pub const fn wrapping_sub(self, rhs: usize) -> Self {
34 Self::new(self.0.wrapping_sub(rhs))
35 }
36
37 #[inline]
39 pub const fn next(self) -> Self {
40 self.wrapping_add(1)
41 }
42
43 #[inline]
45 pub const fn max_value() -> Self {
46 Self(TAG_MASK)
47 }
48}
49
50impl fmt::Debug for Tag {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 write!(f, "Tag({:#X})", self.0)
53 }
54}
55
56impl fmt::Display for Tag {
57 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58 write!(f, "{}", self.0)
59 }
60}
61
62impl From<usize> for Tag {
63 #[inline]
64 fn from(value: usize) -> Self {
65 Self::new(value)
66 }
67}
68
69impl From<u8> for Tag {
70 #[inline]
71 fn from(value: u8) -> Self {
72 Self::new(value as usize)
73 }
74}
75
76impl From<u16> for Tag {
77 #[inline]
78 fn from(value: u16) -> Self {
79 Self::new(value as usize)
80 }
81}
82
83impl From<u32> for Tag {
84 #[inline]
85 fn from(value: u32) -> Self {
86 Self::new(value as usize)
87 }
88}
89
90impl From<Tag> for usize {
91 #[inline]
92 fn from(tag: Tag) -> usize {
93 tag.0
94 }
95}
96
97impl core::ops::Add<usize> for Tag {
98 type Output = Self;
99
100 #[inline]
101 fn add(self, rhs: usize) -> Self::Output {
102 self.wrapping_add(rhs)
103 }
104}
105
106impl core::ops::AddAssign<usize> for Tag {
107 #[inline]
108 fn add_assign(&mut self, rhs: usize) {
109 *self = *self + rhs;
110 }
111}
112
113impl core::ops::Sub<usize> for Tag {
114 type Output = Self;
115
116 #[inline]
117 fn sub(self, rhs: usize) -> Self::Output {
118 self.wrapping_sub(rhs)
119 }
120}
121
122impl core::ops::SubAssign<usize> for Tag {
123 #[inline]
124 fn sub_assign(&mut self, rhs: usize) {
125 *self = *self - rhs;
126 }
127}
128
129impl core::ops::BitAnd<usize> for Tag {
130 type Output = Self;
131
132 #[inline]
133 fn bitand(self, rhs: usize) -> Self::Output {
134 Self::new(self.0 & rhs)
135 }
136}
137
138impl core::ops::BitAnd<Tag> for Tag {
139 type Output = Self;
140
141 #[inline]
142 fn bitand(self, rhs: Tag) -> Self::Output {
143 Self::new(self.0 & rhs.0)
144 }
145}
146
147impl core::ops::BitAndAssign<usize> for Tag {
148 #[inline]
149 fn bitand_assign(&mut self, rhs: usize) {
150 *self = *self & rhs;
151 }
152}
153
154impl core::ops::BitAndAssign<Tag> for Tag {
155 #[inline]
156 fn bitand_assign(&mut self, rhs: Tag) {
157 *self = *self & rhs.0;
158 }
159}
160
161impl core::ops::BitOr<usize> for Tag {
162 type Output = Self;
163
164 #[inline]
165 fn bitor(self, rhs: usize) -> Self::Output {
166 Self::new(self.0 | rhs)
167 }
168}
169
170impl core::ops::BitOr<Tag> for Tag {
171 type Output = Self;
172
173 #[inline]
174 fn bitor(self, rhs: Tag) -> Self::Output {
175 Self::new(self.0 | rhs.0)
176 }
177}
178
179impl core::ops::BitOrAssign<usize> for Tag {
180 #[inline]
181 fn bitor_assign(&mut self, rhs: usize) {
182 *self = *self | rhs;
183 }
184}
185
186impl core::ops::BitOrAssign<Tag> for Tag {
187 #[inline]
188 fn bitor_assign(&mut self, rhs: Tag) {
189 *self = *self | rhs.0;
190 }
191}
192
193impl core::ops::BitXor<usize> for Tag {
194 type Output = Self;
195
196 #[inline]
197 fn bitxor(self, rhs: usize) -> Self::Output {
198 Self::new(self.0 ^ rhs)
199 }
200}
201
202impl core::ops::BitXor<Tag> for Tag {
203 type Output = Self;
204
205 #[inline]
206 fn bitxor(self, rhs: Tag) -> Self::Output {
207 Self::new(self.0 ^ rhs.0)
208 }
209}
210
211impl core::ops::BitXorAssign<usize> for Tag {
212 #[inline]
213 fn bitxor_assign(&mut self, rhs: usize) {
214 *self = *self ^ rhs;
215 }
216}
217
218impl core::ops::BitXorAssign<Tag> for Tag {
219 #[inline]
220 fn bitxor_assign(&mut self, rhs: Tag) {
221 *self = *self ^ rhs.0;
222 }
223}
224
225impl core::ops::Not for Tag {
226 type Output = Self;
227
228 #[inline]
229 fn not(self) -> Self::Output {
230 Self::new(!self.0)
231 }
232}