alloc_traits/
layout.rs

1use core::{alloc, convert};
2use core::num::NonZeroUsize;
3
4/// Layout of an allocated block of memory.
5///
6/// Wraps the `Layout` structure from core but extends it in a few ways that would otherwise depend
7/// on nightly compiler.
8#[derive(Clone, Copy, Debug, PartialEq)]
9pub struct Layout(alloc::Layout);
10
11/// A non-empty layout which can be allocated.
12#[derive(Clone, Copy, Debug, PartialEq)]
13pub struct NonZeroLayout(Layout);
14
15#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
16pub struct EmptyLayoutError;
17
18impl Layout {
19    /// Create the layout for a type.
20    pub fn new<T>() -> Self {
21        Layout(alloc::Layout::new::<T>())
22    }
23
24    /// Return the size of the layout.
25    pub fn size(&self) -> usize {
26        self.0.size()
27    }
28
29    /// Return the alignment of the layout.
30    pub fn align(&self) -> usize {
31        self.0.align()
32    }
33}
34
35impl NonZeroLayout {
36    /// Create the layout for a type.
37    ///
38    /// This succeeds exactly if the type is not a zero-sized type. Otherwise this constructor
39    /// returns `None`.
40    pub fn new<T>() -> Option<Self> {
41        Self::from_layout(Layout::new::<T>())
42    }
43
44    /// Creates a non-empty layout if the given layout is not empty.
45    pub fn from_layout(layout: Layout) -> Option<Self> {
46        if layout.size() == 0 {
47            None
48        } else {
49            Some(NonZeroLayout(layout))
50        }
51    }
52
53    /// Return the size of the layout.
54    pub fn size(&self) -> NonZeroUsize {
55        NonZeroUsize::new(self.0.size()).unwrap()
56    }
57
58    /// Return the alignment of the layout.
59    pub fn align(&self) -> usize {
60        self.0.align()
61    }
62}
63
64impl From<Layout> for alloc::Layout {
65    fn from(layout: Layout) -> alloc::Layout {
66        layout.0
67    }
68}
69
70impl From<NonZeroLayout> for alloc::Layout {
71    fn from(layout: NonZeroLayout) -> alloc::Layout {
72        layout.0.into()
73    }
74}
75
76impl From<alloc::Layout> for Layout {
77    fn from(layout: alloc::Layout) -> Layout {
78        Layout(layout)
79    }
80}
81
82impl convert::TryFrom<Layout> for NonZeroLayout {
83    type Error = EmptyLayoutError;
84
85    fn try_from(layout: Layout) -> Result<Self, EmptyLayoutError> {
86       NonZeroLayout::from_layout(layout).ok_or(EmptyLayoutError)
87    }
88}
89
90impl convert::TryFrom<alloc::Layout> for NonZeroLayout {
91    type Error = EmptyLayoutError;
92
93    fn try_from(layout: alloc::Layout) -> Result<Self, EmptyLayoutError> {
94        NonZeroLayout::try_from(Layout::from(layout))
95    }
96}