[][src]Struct heaparray::base::MemBlock

#[repr(transparent)]
pub struct MemBlock<E, L = ()> { /* fields omitted */ }

An array block that can hold arbitrary information, and cannot be constructed on the stack.

The label type, L, and element type, E, are both held in the same block; i.e. this block holds exactly one instance of L, and some arbitrary number of instances of E.

A raw pointer to a MemBlock, i.e. *mut MemBlock, correctly implements the BaseArrayPtr trait, and can thus be used as the underlying type for a BaseArray. Additionally, AtomicPtr<MemBlock> and NonNull<MemBlock> also correctly implement BaseArrayPtr.

Invariants

The implementation of MemBlock holds the necessary invariants to be a valid implementation of BaseArrayPtr<E, L>. That means that for mutable raw pointers to a MemBlock, the following is true (a is a *mut pointer to a MemBlock and A is the class *mut MemBlock):

  • a.dealloc(len) is safe to call on the result of A::alloc(len)
  • a.elem_ptr(idx) and a.lbl_ptr() must return properly aligned pointers for the types E and L respectively
  • a.lbl_ptr() must return the same value for the lifetime of a for all let a = A::alloc(len), or at least until a.dealloc() is called.
  • a.elem_ptr(idx) must return the same value for each value of idx for the lifetime of a for all let a = A::alloc(len), or at least until a.dealloc() is called.
  • A::alloc(len).elem_ptr(idx) returns a pointer to allocated memory for all idx < len
  • A::alloc(len).lbl_ptr() returns a pointer to allocated memory
  • a._init() is safe to call on the result of A::alloc(len)
  • a._drop() is safe to call on any result of A::alloc(len) for which _init() has been called exactly once

Additionally, MemBlock provides additional guarrantees:

  • A MemBlock cannot be larger than core::isize::MAX bytes
  • Allocation functions panic instead of returning null pointers

However, note that the above invariants can be disabled for better performance, as discussed below.

Invariant Invalidation

Some crate features invalidate the invariants above. Namely:

  • mem-block-skip-size-check prevents size checks of the array being created or accessed. This can cause undefined behavior with pointer arithmetic when accessing elements.
  • mem-block-skip-layout-check prevents checking whether or not the memory layout of the block you try to allocate is valid on the platform you're allocating it on
  • mem-block-skip-ptr-check prevents checking for null pointer allocations
  • mem-block-skip-all enables mem-block-skip-layout-check, mem-block-skip-ptr-check, and mem-block-skip-size-check

Use all of the above with caution, as their behavior is inherently undefined.

Methods

impl<E, L> MemBlock<E, L>[src]

pub const fn max_len() -> usize[src]

Get the maximum length of a MemBlock, based on the types that it contains.

This function is used to maintain the invariant that all MemBlock instances are of size (in bytes) less than or equal to core::isize::MAX.

pub const fn memory_layout(len: usize) -> (usize, usize)[src]

Get size and alignment of the memory that a block of length len would need.

Returns a tuple in the form (size, align)

Auto Trait Implementations

impl<E, L = ()> !Send for MemBlock<E, L>

impl<E, L = ()> !Sync for MemBlock<E, L>

Blanket Implementations

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> From<T> for T[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]