1
2pub trait AlignTo {
4 type TAlign;
5 fn align_to(self, align: Self::TAlign) -> Self;
9 fn aligned_to(self, align: Self::TAlign) -> bool;
13}
14
15macro_rules! impl_align_to {
16 ($ty:ty) => {
17 impl AlignTo for $ty {
18 type TAlign = $ty;
19 #[inline(always)]
20 fn align_to(self, align: $ty) -> $ty {
21 debug_assert!(align.is_power_of_two(), "align ({:#x}) is not a power of two", align);
22 let mask = align - 1;
23 self.wrapping_add(mask) & !mask
24 }
25 #[inline(always)]
26 fn aligned_to(self, align: $ty) -> bool {
27 debug_assert!(align.is_power_of_two(), "align ({:#x}) is not a power of two", align);
28 let mask = align - 1;
29 self & mask == 0
30 }
31 }
32 };
33}
34impl_align_to!(u8);
35impl_align_to!(u16);
36impl_align_to!(u32);
37impl_align_to!(u64);
38impl_align_to!(u128);
39impl_align_to!(usize);
40
41impl<T> AlignTo for *const T {
42 type TAlign = usize;
43 #[inline(always)]
44 fn align_to(self, align: usize) -> *const T {
45 (self as usize).align_to(align) as *const T
46 }
47 #[inline(always)]
48 fn aligned_to(self, align: usize) -> bool {
49 (self as usize).aligned_to(align)
50 }
51}
52
53impl<T> AlignTo for *mut T {
54 type TAlign = usize;
55 #[inline(always)]
56 fn align_to(self, align: usize) -> *mut T {
57 (self as usize).align_to(align) as *mut T
58 }
59 #[inline(always)]
60 fn aligned_to(self, align: usize) -> bool {
61 (self as usize).aligned_to(align)
62 }
63}
64
65#[test]
66fn test_align_to() {
67 assert_eq!(0, 0_u32.align_to(256_u32));
68 assert_eq!(0, (!0_u32).align_to(256_u32));
69 assert_eq!(128, 65_u32.align_to(64_u32));
70 assert_eq!(64, 64_u32.align_to(64_u32));
71}