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
use core::{
    mem::forget,
    ops::{Deref, DerefMut},
};

use crate::mem::{block::Block, object::Object};

use super::{manager::Dealloc, ref_::Ref};

/// A reference to a mutable object allocated by a memory manager.
#[repr(transparent)]
#[derive(Debug)]
pub struct MutRef<T: Object, D: Dealloc>(*mut Block<T, D>);

impl<T: Object, D: Dealloc> MutRef<T, D> {
    #[inline(always)]
    pub const unsafe fn new(v: *mut Block<T, D>) -> Self {
        Self(v)
    }
    #[inline(always)]
    pub const fn to_ref(self) -> Ref<T, D> {
        let result = unsafe { Ref::from_internal(self.0) };
        forget(self);
        result
    }
}

impl<T: Object, D: Dealloc> Drop for MutRef<T, D> {
    #[inline(always)]
    fn drop(&mut self) {
        unsafe { (*self.0).delete() }
    }
}

impl<T: Object, D: Dealloc> Deref for MutRef<T, D> {
    type Target = T;
    #[inline(always)]
    fn deref(&self) -> &Self::Target {
        unsafe { (*self.0).object() }
    }
}

impl<T: Object, D: Dealloc> DerefMut for MutRef<T, D> {
    #[inline(always)]
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { (*self.0).object_mut() }
    }
}