reference_box/
reference_box.rs

1/// Tell Rust to take back the control over memory
2/// This is dangerous! Rust takes the control over the memory back
3pub unsafe fn from_raw<T>(pointer: *mut T) -> Box<T> {
4    assert_eq!(
5        pointer.is_null(),
6        false,
7        "from_raw(): Pointer must not be null!"
8    );
9    assert_eq!(
10        std::mem::size_of::<*mut T>(),
11        std::mem::size_of::<*mut std::ffi::c_void>(),
12        "The pointer must be compatible with void*"
13    );
14    Box::from_raw(pointer)
15}
16
17pub fn into_raw<T>(_box: Box<T>) -> *mut T {
18    assert_eq!(
19        std::mem::size_of::<*mut T>(),
20        std::mem::size_of::<*mut std::ffi::c_void>(),
21        "The pointer must be compatible with void*"
22    );
23    Box::into_raw(_box)
24}
25
26#[derive(Debug)]
27#[repr(C)]
28pub struct ReferenceBoxMut<T> {
29    referenced: *mut T,
30}
31
32impl<T> ReferenceBoxMut<T> {
33    pub fn new(_reference: &mut T) -> Self {
34        let pointer: *mut T = unsafe { std::mem::transmute(_reference) };
35        ReferenceBoxMut {
36            referenced: pointer,
37        }
38    }
39
40    pub fn into_raw(self) -> *mut Self {
41        into_raw(Box::new(self))
42    }
43
44    pub fn boxed(&self) -> *mut T {
45        self.referenced
46    }
47
48    pub fn as_ref(&self) -> &T {
49        unsafe { std::mem::transmute(self.referenced) }
50    }
51
52    pub fn as_mut(&self) -> &mut T {
53        unsafe { std::mem::transmute(self.referenced) }
54    }
55}
56
57pub trait ReferenceBoxMutPointer<T> {
58    fn with<Block, Return>(&self, block: Block) -> Return
59    where
60        Block: FnOnce(&mut T) -> Return;
61    fn with_value<Block, Return>(&self, block: Block) -> Return
62    where
63        Block: FnOnce(T) -> Return,
64        T: Copy;
65    fn with_not_null<Block>(&self, block: Block)
66    where
67        Block: FnOnce(&mut T);
68    fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
69    where
70        Block: FnOnce(&mut T) -> Return;
71    fn with_not_null_return_block<DefaultBlock, Block, Return>(
72        &self,
73        default: DefaultBlock,
74        block: Block,
75    ) -> Return
76    where
77        DefaultBlock: FnOnce() -> Return,
78        Block: FnOnce(&mut T) -> Return;
79    fn drop(self);
80}
81
82impl<T> ReferenceBoxMutPointer<T> for *mut ReferenceBoxMut<T> {
83    fn with<Block, Return>(&self, block: Block) -> Return
84    where
85        Block: FnOnce(&mut T) -> Return,
86    {
87        assert_eq!(self.is_null(), false, "Pointer must not be null!");
88
89        let mut reference_box = unsafe { from_raw(*self) };
90        let referenced_object: &mut T = unsafe { std::mem::transmute(reference_box.referenced) };
91        let result: Return = block(referenced_object);
92
93        let referenced_object_pointer: *mut T = unsafe { std::mem::transmute(referenced_object) };
94        reference_box.referenced = referenced_object_pointer;
95
96        let new_pointer = into_raw(reference_box);
97        assert_eq!(new_pointer, *self, "The pointer must not change");
98
99        result
100    }
101
102    fn with_value<Block, Return>(&self, block: Block) -> Return
103    where
104        Block: FnOnce(T) -> Return,
105        T: Copy,
106    {
107        assert_eq!(self.is_null(), false, "Pointer must not be null!");
108
109        let reference_box = unsafe { from_raw(*self) };
110        let referenced_object = *&mut unsafe { *reference_box.referenced };
111        let result: Return = block(referenced_object);
112
113        let new_pointer = into_raw(reference_box);
114        assert_eq!(new_pointer, *self, "The pointer must not change");
115
116        result
117    }
118
119    fn with_not_null<Block>(&self, block: Block)
120    where
121        Block: FnOnce(&mut T),
122    {
123        if self.is_null() {
124            return;
125        }
126        self.with(|boxed_object| {
127            block(boxed_object);
128        });
129    }
130
131    fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
132    where
133        Block: FnOnce(&mut T) -> Return,
134    {
135        if self.is_null() {
136            return default;
137        }
138        self.with(block)
139    }
140
141    fn with_not_null_return_block<DefaultBlock, Block, Return>(
142        &self,
143        default: DefaultBlock,
144        block: Block,
145    ) -> Return
146    where
147        DefaultBlock: FnOnce() -> Return,
148        Block: FnOnce(&mut T) -> Return,
149    {
150        if self.is_null() {
151            return default();
152        }
153        self.with(block)
154    }
155
156    fn drop(self) {
157        let reference_box = unsafe { from_raw(self) };
158        std::mem::drop(reference_box);
159    }
160}
161
162#[derive(Debug)]
163#[repr(C)]
164pub struct ReferenceBox<T> {
165    referenced: *const T,
166}
167
168impl<T> ReferenceBox<T> {
169    pub fn new(_reference: &T) -> Self {
170        let pointer: *const T = unsafe { std::mem::transmute(_reference) };
171        Self {
172            referenced: pointer,
173        }
174    }
175
176    pub fn into_raw(self) -> *mut Self {
177        into_raw(Box::new(self))
178    }
179
180    pub fn boxed(&self) -> *const T {
181        self.referenced
182    }
183
184    pub fn as_ref(&self) -> &T {
185        unsafe { std::mem::transmute(self.referenced) }
186    }
187}
188
189pub trait ReferenceBoxPointer<T> {
190    fn with<Block, Return>(&self, block: Block) -> Return
191    where
192        Block: FnOnce(&T) -> Return;
193    fn with_not_null<Block>(&self, block: Block)
194    where
195        Block: FnOnce(&T);
196    fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
197    where
198        Block: FnOnce(&T) -> Return;
199    fn with_not_null_return_block<DefaultBlock, Block, Return>(
200        &self,
201        default: DefaultBlock,
202        block: Block,
203    ) -> Return
204    where
205        DefaultBlock: FnOnce() -> Return,
206        Block: FnOnce(&T) -> Return;
207    fn drop(self);
208}
209
210impl<T> ReferenceBoxPointer<T> for *mut ReferenceBox<T> {
211    fn with<Block, Return>(&self, block: Block) -> Return
212    where
213        Block: FnOnce(&T) -> Return,
214    {
215        assert_eq!(self.is_null(), false, "Pointer must not be null!");
216
217        let mut reference_box = unsafe { from_raw(*self) };
218        let referenced_object: &mut T = unsafe { std::mem::transmute(reference_box.referenced) };
219        let result: Return = block(referenced_object);
220
221        let referenced_object_pointer: *const T = unsafe { std::mem::transmute(referenced_object) };
222        reference_box.referenced = referenced_object_pointer;
223
224        let new_pointer = into_raw(reference_box);
225        assert_eq!(new_pointer, *self, "The pointer must not change");
226
227        result
228    }
229
230    fn with_not_null<Block>(&self, block: Block)
231    where
232        Block: FnOnce(&T),
233    {
234        if self.is_null() {
235            return;
236        }
237        self.with(|boxed_object| {
238            block(boxed_object);
239        });
240    }
241
242    fn with_not_null_return<Block, Return>(&self, default: Return, block: Block) -> Return
243    where
244        Block: FnOnce(&T) -> Return,
245    {
246        if self.is_null() {
247            return default;
248        }
249        self.with(block)
250    }
251
252    fn with_not_null_return_block<DefaultBlock, Block, Return>(
253        &self,
254        default: DefaultBlock,
255        block: Block,
256    ) -> Return
257    where
258        DefaultBlock: FnOnce() -> Return,
259        Block: FnOnce(&T) -> Return,
260    {
261        if self.is_null() {
262            return default();
263        }
264        self.with(block)
265    }
266
267    fn drop(self) {
268        let reference_box = unsafe { from_raw(self) };
269        std::mem::drop(reference_box);
270    }
271}