yoyu 0.0.2

A compact infrastructure built from scratch.
Documentation

use std::alloc::{alloc, Layout};
use std::sync::{Mutex, OnceLock};

pub struct CellHeap<T> {
    pool: Mutex<Vec<*mut T>>,
    layout: Layout,
}

impl<T: 'static> CellHeap<T> {
    fn global() -> &'static Self {
        static INIT: OnceLock<Mutex<Vec<u8>>> = OnceLock::new(); // ダミーで型付きOnceLock
        static mut HEAP_PTR: *const () = std::ptr::null();

        unsafe {
            if HEAP_PTR.is_null() {
                let layout = Layout::new::<T>();
                let heap = Box::new(CellHeap {
                    pool: Mutex::new(Vec::<*mut T>::new()),
                    layout,
                });
                HEAP_PTR = Box::into_raw(heap) as *const ();
                INIT.get_or_init(|| Mutex::new(vec![])); // 強制初期化
            }
            &*(HEAP_PTR as *const CellHeap<T>)
        }
    }

    fn alloc(&self) -> *mut T {
        self.pool.lock().unwrap().pop().unwrap_or_else(|| unsafe {
            alloc(self.layout) as *mut T
        })
    }

    unsafe fn free(&self, ptr: *mut T) {
        self.pool.lock().unwrap().push(ptr);
    }
}

pub struct Cell<T: 'static> {
    ptr: *mut T,
    heap: &'static CellHeap<T>,
}

impl<T: 'static> Cell<T> {
    pub fn new(value: T) -> Self {
        let heap = CellHeap::<T>::global();
        let ptr = heap.alloc();
        unsafe { ptr.write(value) }
        Self { ptr, heap }
    }
}

impl<T: 'static> Drop for Cell<T> {
    fn drop(&mut self) {
        unsafe {
            self.ptr.drop_in_place();
            self.heap.free(self.ptr);
        }
    }
}

impl<T: 'static> std::ops::Deref for Cell<T> {
    type Target = T;
    fn deref(&self) -> &Self::Target {
        unsafe { &*self.ptr }
    }
}

impl<T: 'static> std::ops::DerefMut for Cell<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { &mut *self.ptr }
    }
}