1#![no_std]
2#![feature(allocator_api)]
3#![warn(rust_2018_idioms)]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7use core::{
8 alloc::{AllocError, Allocator, Layout},
9 marker::PhantomData,
10 ptr::NonNull,
11};
12
13#[repr(transparent)]
38pub struct NoopAllocator<'a>(PhantomData<&'a ()>);
39
40impl<'a> NoopAllocator<'a> {
41 pub const fn new() -> Self {
43 Self(PhantomData)
44 }
45}
46
47impl<'a> Default for NoopAllocator<'a> {
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53unsafe impl Allocator for NoopAllocator<'_> {
54 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
55 if layout.size() == 0 {
56 Ok(NonNull::slice_from_raw_parts(layout.dangling_ptr(), 0))
57 } else {
58 Err(AllocError)
59 }
60 }
61
62 unsafe fn deallocate(&self, _ptr: NonNull<u8>, _layout: Layout) {
63 }
65
66 unsafe fn grow(
67 &self,
68 ptr: NonNull<u8>,
69 old_layout: Layout,
70 new_layout: Layout,
71 ) -> Result<NonNull<[u8]>, AllocError> {
72 self.grow_zeroed(ptr, old_layout, new_layout)
73 }
74
75 unsafe fn grow_zeroed(
76 &self,
77 ptr: NonNull<u8>,
78 old_layout: Layout,
79 new_layout: Layout,
80 ) -> Result<NonNull<[u8]>, AllocError> {
81 debug_assert!(
82 new_layout.size() >= old_layout.size(),
83 "`new_layout.size()` must be greater than or equal to `old_layout.size()`"
84 );
85 if new_layout.size() > old_layout.size()
86 || (ptr.as_ptr() as usize & (new_layout.align() - 1) != 0)
87 {
88 return Err(AllocError);
89 }
90
91 let new_ptr = NonNull::slice_from_raw_parts(ptr, new_layout.size());
92
93 Ok(new_ptr)
94 }
95
96 unsafe fn shrink(
97 &self,
98 ptr: NonNull<u8>,
99 old_layout: Layout,
100 new_layout: Layout,
101 ) -> Result<NonNull<[u8]>, AllocError> {
102 debug_assert!(
103 new_layout.size() <= old_layout.size(),
104 "`new_layout.size()` must be smaller than or equal to `old_layout.size()`"
105 );
106
107 if new_layout.size() > old_layout.size()
108 || (ptr.as_ptr() as usize & (new_layout.align() - 1) != 0)
109 {
110 return Err(AllocError);
111 }
112
113 let new_ptr = NonNull::slice_from_raw_parts(ptr, new_layout.size());
114
115 Ok(new_ptr)
116 }
117}
118
119#[cfg(feature = "alloc")]
120pub mod owning_ref;
121#[cfg(feature = "alloc")]
122pub mod owning_slice;