1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#![cfg_attr(not(test), no_std)]
#![feature(ptr_metadata)]
#![feature(unsize)]
use core::{
alloc::Layout,
marker::{PhantomData, Unsize},
mem::MaybeUninit,
ops::{Deref, DerefMut},
ptr::{self, drop_in_place, metadata, DynMetadata, NonNull, Pointee},
};
#[cfg(test)]
mod tests;
pub struct Box<T, const N: usize>
where
T: ?Sized + Pointee<Metadata = DynMetadata<T>>,
{
mem: [u8; N],
phantom: PhantomData<T>,
}
impl<T, const N: usize> Box<T, N>
where
T: ?Sized + Pointee<Metadata = DynMetadata<T>>,
{
pub fn new<Value: Unsize<T>>(value: Value) -> Self {
let meta = metadata(&value as &T);
let meta_layout = Layout::for_value(&meta);
let value_layout = Layout::for_value(&value);
let (layout, offset) = meta_layout.extend(value_layout).unwrap();
assert!(layout.size() > 0);
assert!(layout.size() <= N);
unsafe {
let mut mem = MaybeUninit::uninit();
let ptr = NonNull::new(mem.as_mut_ptr()).unwrap();
ptr.cast::<DynMetadata<T>>().as_ptr().write(meta);
ptr.cast::<u8>()
.as_ptr()
.add(offset)
.cast::<Value>()
.write(value);
Self {
mem: mem.assume_init(),
phantom: PhantomData,
}
}
}
fn meta(&self) -> DynMetadata<T> {
unsafe { *self.mem.as_ptr().cast() }
}
fn layout_meta(&self) -> (Layout, usize, DynMetadata<T>) {
let meta = self.meta();
let (layout, offset) = Layout::for_value(&meta).extend(meta.layout()).unwrap();
(layout, offset, meta)
}
fn value_ptr(&self) -> *const T {
let (_, offset, meta) = self.layout_meta();
unsafe {
let ptr = self.mem.as_ptr().add(offset).cast::<()>();
ptr::from_raw_parts(ptr, meta)
}
}
fn value_mut_ptr(&mut self) -> *mut T {
let (_, offset, meta) = self.layout_meta();
unsafe {
let ptr = self.mem.as_mut_ptr().add(offset).cast::<()>();
ptr::from_raw_parts_mut(ptr, meta)
}
}
}
impl<T, const N: usize> Deref for Box<T, N>
where
T: ?Sized + Pointee<Metadata = DynMetadata<T>>,
{
type Target = T;
fn deref(&self) -> &T {
unsafe { &*self.value_ptr() }
}
}
impl<T, const N: usize> DerefMut for Box<T, N>
where
T: ?Sized + Pointee<Metadata = DynMetadata<T>>,
{
fn deref_mut(&mut self) -> &mut T {
unsafe { &mut *self.value_mut_ptr() }
}
}
impl<T, const N: usize> Drop for Box<T, N>
where
T: ?Sized + Pointee<Metadata = DynMetadata<T>>,
{
fn drop(&mut self) {
unsafe {
drop_in_place::<T>(&mut **self);
}
}
}