Skip to main content

foundation_arena/
boxed.rs

1// SPDX-FileCopyrightText: © 2023 Foundation Devices, Inc. <hello@foundationdevices.com>
2// SPDX-License-Identifier: GPL-3.0-or-later
3//
4// Based on code from bumpalo and Rust std.
5
6/// Alternative to `std::boxed::Box`, but using an arena allcator.
7///
8/// # Example
9///
10/// Recursive data structure:
11///
12/// ```rust
13/// use foundation_arena::{Arena, boxed::Box};
14///
15/// let a: Arena<_, 2> = Arena::new();
16/// let b: Arena<_, 2> = Arena::new();
17///
18/// #[derive(Debug, PartialEq)]
19/// enum List<'a, T> {
20///     Cons(T, Box<'a, List<'a, T>>),
21///     Nil,
22/// }
23///
24/// let list = List::<i32>::Cons(
25///     1,
26///     Box::new_in(List::Cons(2, Box::new_in(List::Nil, &a).unwrap()), &a).unwrap(),
27/// );
28///
29/// let clone = List::<i32>::Cons(
30///     1,
31///     Box::new_in(List::Cons(2, Box::new_in(List::Nil, &b).unwrap()), &b).unwrap(),
32/// );
33///
34/// println!("{:?}", list);
35///
36/// assert_eq!(list, clone);
37/// ```
38use core::{ops::Deref, ptr};
39
40use crate::Arena;
41
42#[derive(Debug)]
43pub struct Box<'a, T>(&'a mut T);
44
45impl<'a, T> Box<'a, T> {
46    pub fn new_in<const N: usize>(x: T, arena: &'a Arena<T, N>) -> Result<Self, T> {
47        arena.alloc(x).map(Self)
48    }
49}
50
51impl<'a, T> Deref for Box<'a, T> {
52    type Target = T;
53
54    fn deref(&self) -> &Self::Target {
55        &*self.0
56    }
57}
58
59impl<'a, 'b, T: PartialEq> PartialEq<Box<'b, T>> for Box<'a, T> {
60    fn eq(&self, other: &Box<'b, T>) -> bool {
61        PartialEq::eq(&**self, &**other)
62    }
63
64    fn ne(&self, other: &Box<'b, T>) -> bool {
65        PartialEq::ne(&**self, &**other)
66    }
67}
68
69impl<'a, T> Drop for Box<'a, T> {
70    fn drop(&mut self) {
71        unsafe { ptr::drop_in_place(self.0) }
72    }
73}