1#![no_std]
2use core::cmp::Ordering;
40use core::hash::{Hash, Hasher};
41
42pub trait Pad: Copy + private::Sealed {
49 const VALUE: Self;
51}
52
53#[derive(Debug)]
58pub struct PadU0(());
59
60impl Clone for PadU0 {
61 #[inline]
62 #[must_use]
63 fn clone(&self) -> Self {
64 Self::VALUE
65 }
66}
67
68impl Copy for PadU0 {}
69
70impl Default for PadU0 {
71 #[inline]
72 #[must_use]
73 fn default() -> Self {
74 Self::VALUE
75 }
76}
77
78impl Eq for PadU0 {}
79
80impl Hash for PadU0 {
81 #[inline]
82 fn hash<H: Hasher>(&self, _: &mut H) {}
83}
84
85impl Ord for PadU0 {
86 #[inline]
87 #[must_use]
88 fn cmp(&self, _: &Self) -> Ordering {
89 Ordering::Equal
90 }
91}
92
93impl Pad for PadU0 {
94 const VALUE: Self = Self(());
95}
96
97impl PartialEq for PadU0 {
98 #[inline]
99 #[must_use]
100 fn eq(&self, _: &Self) -> bool {
101 true
102 }
103}
104
105impl PartialOrd for PadU0 {
106 #[inline]
107 #[must_use]
108 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
109 Some(Ordering::Equal)
110 }
111}
112
113#[derive(Debug)]
118#[repr(transparent)]
119pub struct PadU8(PadU8Inner);
120
121impl Clone for PadU8 {
122 #[inline]
123 #[must_use]
124 fn clone(&self) -> Self {
125 Self::VALUE
126 }
127}
128
129impl Copy for PadU8 {}
130
131impl Default for PadU8 {
132 #[inline]
133 #[must_use]
134 fn default() -> Self {
135 Self::VALUE
136 }
137}
138
139impl Eq for PadU8 {}
140
141impl Hash for PadU8 {
142 #[inline]
143 fn hash<H: Hasher>(&self, _: &mut H) {}
144}
145
146impl Ord for PadU8 {
147 #[inline]
148 #[must_use]
149 fn cmp(&self, _: &Self) -> Ordering {
150 Ordering::Equal
151 }
152}
153
154impl Pad for PadU8 {
155 const VALUE: Self = Self(PadU8Inner::VALUE);
156}
157
158impl PartialEq for PadU8 {
159 #[inline]
160 #[must_use]
161 fn eq(&self, _: &Self) -> bool {
162 true
163 }
164}
165
166impl PartialOrd for PadU8 {
167 #[inline]
168 #[must_use]
169 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
170 Some(Ordering::Equal)
171 }
172}
173
174#[derive(Debug)]
175#[repr(u8)]
176enum PadU8Inner {
177 VALUE = 0,
178}
179
180impl Clone for PadU8Inner {
181 #[inline]
182 #[must_use]
183 fn clone(&self) -> Self {
184 Self::VALUE
185 }
186}
187
188impl Copy for PadU8Inner {}
189
190#[derive(Debug)]
195#[repr(transparent)]
196pub struct PadU16(PadU16Inner);
197
198impl Clone for PadU16 {
199 #[inline]
200 #[must_use]
201 fn clone(&self) -> Self {
202 Self::VALUE
203 }
204}
205
206impl Copy for PadU16 {}
207
208impl Default for PadU16 {
209 #[inline]
210 #[must_use]
211 fn default() -> Self {
212 Self::VALUE
213 }
214}
215
216impl Eq for PadU16 {}
217
218impl Hash for PadU16 {
219 #[inline]
220 fn hash<H: Hasher>(&self, _: &mut H) {}
221}
222
223impl Ord for PadU16 {
224 #[inline]
225 #[must_use]
226 fn cmp(&self, _: &Self) -> Ordering {
227 Ordering::Equal
228 }
229}
230
231impl Pad for PadU16 {
232 const VALUE: Self = Self(PadU16Inner::VALUE);
233}
234
235impl PartialEq for PadU16 {
236 #[inline]
237 #[must_use]
238 fn eq(&self, _: &Self) -> bool {
239 true
240 }
241}
242
243impl PartialOrd for PadU16 {
244 #[inline]
245 #[must_use]
246 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
247 Some(Ordering::Equal)
248 }
249}
250
251#[derive(Debug)]
252#[repr(u16)]
253enum PadU16Inner {
254 VALUE = 0,
255}
256
257impl Clone for PadU16Inner {
258 #[inline]
259 #[must_use]
260 fn clone(&self) -> Self {
261 Self::VALUE
262 }
263}
264
265impl Copy for PadU16Inner {}
266
267#[derive(Debug)]
272#[repr(transparent)]
273pub struct PadU32(PadU32Inner);
274
275impl Clone for PadU32 {
276 #[inline]
277 #[must_use]
278 fn clone(&self) -> Self {
279 Self::VALUE
280 }
281}
282
283impl Copy for PadU32 {}
284
285impl Default for PadU32 {
286 #[inline]
287 #[must_use]
288 fn default() -> Self {
289 Self::VALUE
290 }
291}
292
293impl Eq for PadU32 {}
294
295impl Hash for PadU32 {
296 #[inline]
297 fn hash<H: Hasher>(&self, _: &mut H) {}
298}
299
300impl Ord for PadU32 {
301 #[inline]
302 #[must_use]
303 fn cmp(&self, _: &Self) -> Ordering {
304 Ordering::Equal
305 }
306}
307
308impl Pad for PadU32 {
309 const VALUE: Self = Self(PadU32Inner::VALUE);
310}
311
312impl PartialEq for PadU32 {
313 #[inline]
314 #[must_use]
315 fn eq(&self, _: &Self) -> bool {
316 true
317 }
318}
319
320impl PartialOrd for PadU32 {
321 #[inline]
322 #[must_use]
323 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
324 Some(Ordering::Equal)
325 }
326}
327
328#[derive(Debug)]
329#[repr(u32)]
330enum PadU32Inner {
331 VALUE = 0,
332}
333
334impl Clone for PadU32Inner {
335 #[inline]
336 #[must_use]
337 fn clone(&self) -> Self {
338 Self::VALUE
339 }
340}
341
342impl Copy for PadU32Inner {}
343
344#[derive(Debug)]
349#[repr(transparent)]
350pub struct PadU64(PadU64Inner);
351
352impl Clone for PadU64 {
353 #[inline]
354 #[must_use]
355 fn clone(&self) -> Self {
356 Self::VALUE
357 }
358}
359
360impl Copy for PadU64 {}
361
362impl Default for PadU64 {
363 #[inline]
364 #[must_use]
365 fn default() -> Self {
366 Self::VALUE
367 }
368}
369
370impl Eq for PadU64 {}
371
372impl Hash for PadU64 {
373 #[inline]
374 fn hash<H: Hasher>(&self, _: &mut H) {}
375}
376
377impl Ord for PadU64 {
378 #[inline]
379 #[must_use]
380 fn cmp(&self, _: &Self) -> Ordering {
381 Ordering::Equal
382 }
383}
384
385impl Pad for PadU64 {
386 const VALUE: Self = Self(PadU64Inner::VALUE);
387}
388
389impl PartialEq for PadU64 {
390 #[inline]
391 #[must_use]
392 fn eq(&self, _: &Self) -> bool {
393 true
394 }
395}
396
397impl PartialOrd for PadU64 {
398 #[inline]
399 #[must_use]
400 fn partial_cmp(&self, _: &Self) -> Option<Ordering> {
401 Some(Ordering::Equal)
402 }
403}
404
405#[derive(Debug)]
406#[repr(u64)]
407enum PadU64Inner {
408 VALUE = 0,
409}
410
411impl Clone for PadU64Inner {
412 #[inline]
413 #[must_use]
414 fn clone(&self) -> Self {
415 Self::VALUE
416 }
417}
418
419impl Copy for PadU64Inner {}
420
421#[cfg(target_pointer_width = "16")]
426pub type PadUsize = PadU16;
427#[cfg(target_pointer_width = "32")]
432pub type PadUsize = PadU32;
433#[cfg(target_pointer_width = "64")]
438pub type PadUsize = PadU64;
439
440mod private {
441 pub use super::*;
442 pub trait Sealed {}
443 impl Sealed for PadU0 {}
444 impl Sealed for PadU8 {}
445 impl Sealed for PadU16 {}
446 impl Sealed for PadU32 {}
447 impl Sealed for PadU64 {}
448}
449
450#[cfg(test)]
451mod tests {
452 use super::*;
453 use core::mem::{align_of, size_of};
454
455 #[test]
456 fn align() {
457 assert_eq!(align_of::<PadU0>(), align_of::<()>());
458 assert_eq!(align_of::<PadU8>(), align_of::<u8>());
459 assert_eq!(align_of::<PadU16>(), align_of::<u16>());
460 assert_eq!(align_of::<PadU32>(), align_of::<u32>());
461 assert_eq!(align_of::<PadU64>(), align_of::<u64>());
462 assert_eq!(align_of::<PadUsize>(), align_of::<usize>());
463 }
464
465 #[test]
466 fn align_option() {
467 assert_eq!(align_of::<Option<PadU0>>(), align_of::<Option<()>>());
468 assert_eq!(align_of::<Option<PadU8>>(), align_of::<u8>());
469 assert_eq!(align_of::<Option<PadU16>>(), align_of::<u16>());
470 assert_eq!(align_of::<Option<PadU32>>(), align_of::<u32>());
471 assert_eq!(align_of::<Option<PadU64>>(), align_of::<u64>());
472 assert_eq!(align_of::<Option<PadUsize>>(), align_of::<usize>());
473 }
474
475 #[test]
476 fn size() {
477 assert_eq!(size_of::<PadU0>(), size_of::<()>());
478 assert_eq!(size_of::<PadU8>(), size_of::<u8>());
479 assert_eq!(size_of::<PadU16>(), size_of::<u16>());
480 assert_eq!(size_of::<PadU32>(), size_of::<u32>());
481 assert_eq!(size_of::<PadU64>(), size_of::<u64>());
482 assert_eq!(size_of::<PadUsize>(), size_of::<usize>());
483 }
484
485 #[test]
486 fn size_option() {
487 assert_eq!(size_of::<Option<PadU0>>(), size_of::<Option<()>>());
488 assert_eq!(size_of::<Option<PadU8>>(), size_of::<u8>());
489 assert_eq!(size_of::<Option<PadU16>>(), size_of::<u16>());
490 assert_eq!(size_of::<Option<PadU32>>(), size_of::<u32>());
491 assert_eq!(size_of::<Option<PadU64>>(), size_of::<u64>());
492 assert_eq!(size_of::<Option<PadUsize>>(), size_of::<usize>());
493 }
494
495 #[test]
496 fn bit_pattern() {
497 assert_eq!(PadU8::VALUE.0 as u8, 0);
498 assert_eq!(PadU16::VALUE.0 as u16, 0);
499 assert_eq!(PadU32::VALUE.0 as u32, 0);
500 assert_eq!(PadU64::VALUE.0 as u64, 0);
501 assert_eq!(PadUsize::VALUE.0 as usize, 0);
502 }
503
504 #[test]
505 fn bit_pattern_default() {
506 assert_eq!(PadU8::default().0 as u8, 0);
507 assert_eq!(PadU16::default().0 as u16, 0);
508 assert_eq!(PadU32::default().0 as u32, 0);
509 assert_eq!(PadU64::default().0 as u64, 0);
510 assert_eq!(PadUsize::default().0 as usize, 0);
511 }
512}