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