malloc_rust/
align.rs

1use core::num;
2
3#[derive(Copy, Clone, PartialEq, Eq)]
4#[repr(transparent)]
5///Valid alignment representation
6///
7///## Requirements
8///
9///- Must be non-zero
10///- Must be power of two
11pub struct Alignment(num::NonZeroUsize);
12
13impl Alignment {
14    #[inline(always)]
15    ///Creates new value, with panic if `alignment` doesn't fit requirements
16    pub const fn new(alignment: usize) -> Self {
17        assert!(alignment != 0, "Alignment cannot be zero");
18        assert!(alignment.is_power_of_two());
19
20        Self(unsafe {
21            num::NonZeroUsize::new_unchecked(alignment)
22        })
23    }
24
25    #[inline(always)]
26    ///Creates new value, returning `None` if value doesn't fit requirements
27    pub const fn try_new(alignment: usize) -> Option<Self> {
28        match num::NonZeroUsize::new(alignment) {
29            Some(value) if value.get().is_power_of_two() => Some(Self(value)),
30            _ => None,
31        }
32    }
33
34    #[inline(always)]
35    ///Returns value at or after `size` that is a multiple of alignment.
36    pub const fn next(&self, size: usize) -> usize {
37        let alignment = self.0.get() - 1;
38        size.saturating_add(alignment) & !alignment
39    }
40
41    #[inline(always)]
42    ///Returns value at or before `size` that is a multiple of alignment.
43    pub const fn prev(&self, size: usize) -> usize {
44        let alignment = self.0.get() - 1;
45        size & !alignment
46    }
47
48    #[inline(always)]
49    ///Returns raw value
50    pub const fn into_raw(&self) -> usize {
51        self.0.get()
52    }
53}