memkit 0.2.0-beta.1

Deterministic, intent-driven memory allocation for systems requiring predictable performance
Documentation
//! Frame-allocated vector type.

use std::marker::PhantomData;

/// A Vec-like container backed by frame memory.
///
/// Has a fixed capacity determined at creation time.
pub struct MkFrameVec<'a, T> {
    ptr: *mut T,
    len: usize,
    capacity: usize,
    _marker: PhantomData<&'a T>,
}

impl<'a, T> MkFrameVec<'a, T> {
    /// Create a new MkFrameVec with the given capacity.
    ///
    /// # Safety
    ///
    /// The pointer must point to memory with capacity for `capacity` elements.
    pub(crate) unsafe fn from_raw_parts(ptr: *mut T, capacity: usize) -> Self {
        Self {
            ptr,
            len: 0,
            capacity,
            _marker: PhantomData,
        }
    }

    /// Push a value onto the vector.
    ///
    /// Returns `Err(value)` if the vector is at capacity.
    pub fn push(&mut self, value: T) -> Result<(), T> {
        if self.len >= self.capacity {
            return Err(value);
        }
        unsafe {
            self.ptr.add(self.len).write(value);
        }
        self.len += 1;
        Ok(())
    }

    /// Get the length of the vector.
    pub fn len(&self) -> usize {
        self.len
    }

    /// Check if the vector is empty.
    pub fn is_empty(&self) -> bool {
        self.len == 0
    }

    /// Get the capacity of the vector.
    pub fn capacity(&self) -> usize {
        self.capacity
    }

    /// Clear the vector.
    pub fn clear(&mut self) {
        // Drop all elements
        for i in 0..self.len {
            unsafe {
                std::ptr::drop_in_place(self.ptr.add(i));
            }
        }
        self.len = 0;
    }
}

impl<'a, T> std::ops::Deref for MkFrameVec<'a, T> {
    type Target = [T];

    fn deref(&self) -> &Self::Target {
        unsafe { std::slice::from_raw_parts(self.ptr, self.len) }
    }
}

impl<'a, T> std::ops::DerefMut for MkFrameVec<'a, T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        unsafe { std::slice::from_raw_parts_mut(self.ptr, self.len) }
    }
}