SliceAllocGuard

Struct SliceAllocGuard 

Source
pub struct SliceAllocGuard<'a, T, A: BasicAlloc + ?Sized> { /* private fields */ }
Expand description

A RAII guard for a heap‐allocated slice that tracks how many elements have been initialized.

On drop, it will:

  1. Run destructors for each initialized element.
  2. Deallocate the entire slice of memory.

Use init or init_unchecked to initialize elements one by one, extend_init to initialize many elements at once, and release to take ownership of the fully‐initialized slice without running cleanup.

§Examples

# extern crate alloc;
# use core::ptr::NonNull;
# use memapi2::{
#  helpers::SliceAllocGuard,
#  Alloc,
#  DefaultAlloc,
#  data::type_props::SizedProps,
#  Layout
# };
# let alloc = DefaultAlloc;
# let len = 5;

let mut guard = unsafe { SliceAllocGuard::new(
    alloc.alloc(unsafe { Layout::from_size_align_unchecked(u32::SZ * len, u32::ALN) })
            .unwrap().cast(),
    &alloc,
    len
) };

for i in 0..len {
    guard.init(i as u32).unwrap();
}

// All elements are now initialized; take ownership:
// (commented out for this example as the pointer won't be used)
// let slice_ptr = guard.release();

Implementations§

Source§

impl<'a, T, A: BasicAlloc + ?Sized> SliceAllocGuard<'a, T, A>

Source

pub const unsafe fn new( ptr: NonNull<T>, alloc: &'a A, full: usize, ) -> SliceAllocGuard<'a, T, A>

Creates a new slice guard for full elements at ptr in the given allocator.

§Safety

Callers must ensure that ptr was allocated using alloc, has space for full T, and is readable, writable, valid, and aligned.

Source

pub const unsafe fn new_with_init( ptr: NonNull<T>, alloc: &'a A, init: usize, full: usize, ) -> SliceAllocGuard<'a, T, A>

Creates a new slice guard for full elements at ptr in the given allocator.

§Safety

In addition to the restrictions of SliceAllocGuard::new, callers must ensure that init is the number of existing initialized elements in the slice.

Source

pub const fn release(self) -> NonNull<[T]>

Release ownership of the slice without deallocating memory, returning a NonNull<T> pointer to the slice.

Source

pub const fn release_first(self) -> NonNull<T>

Release ownership of the slice without deallocating memory, returning a NonNull<T> pointer to the slice’s first element.

Source

pub const fn get_init_part(&self) -> NonNull<[T]>

Gets a NonNull<[T]> pointer to the initialized elements of the slice.

Source

pub const fn get_uninit_part(&self) -> NonNull<[T]>

Gets a NonNull<[T]> pointer to the uninitialized elements of the slice.

Source

pub const fn get_full(&self) -> NonNull<[T]>

Gets a NonNull<[T]> pointer to the full slice.

Source

pub const unsafe fn set_init(&mut self, init: usize)

Sets the initialized element count.

§Safety

Callers must ensure the new count is correct.

Source

pub const fn init(&mut self, elem: T) -> Result<(), T>

Initializes the next element of the slice with elem.

§Errors

Returns Err(elem) if the slice is at capacity.

Source

pub const unsafe fn init_unchecked(&mut self, elem: T)

Initializes the next element of the slice with elem.

§Safety

Callers must ensure that the slice is not at capacity. (initialized() < full())

Source

pub const fn initialized(&self) -> usize

Returns how many elements have been initialized.

Source

pub const fn full(&self) -> usize

Returns the total number of elements in the slice.

Source

pub const fn is_full(&self) -> bool

Returns true if every element in the slice has been initialized.

Source

pub const fn is_empty(&self) -> bool

Returns true if no elements have been initialized.

Source

pub const fn copy_from_slice(&mut self, slice: &[T]) -> Result<(), usize>
where T: Copy,

Copies as many elements from slice as will fit.

On success, all elements are copied and Ok(()) is returned. If slice.len() > remaining_capacity, it copies as many elements as will fit, advances the initialized count to full, and returns Err(excess).

§Errors

Returns Err(excess) if slice.len() > remaining_capacity.

Source

pub fn clone_from_slice(&mut self, slice: &[T]) -> Result<(), usize>
where T: Clone,

Clones as many elements from slice as will fit.

On success, all elements are cloned and Ok(()) is returned. If slice.len() > remaining_capacity, it clones as many elements as will fit, advances the initialized count to full, and returns Err(excess).

§Errors

excess if slice.len() > remaining_capacity.

Source

pub fn extend_init<I: IntoIterator<Item = T>>( &mut self, iter: I, ) -> Result<(), I::IntoIter>

Initializes the next elements of the slice with the elements from iter.

§Errors

Returns Err((iter, elem)) if the slice is filled before iteration finishes. The contained iterator will have been partially consumed.

Methods from Deref<Target = NonNull<T>>§

1.25.0 · Source

pub unsafe fn as_ref<'a>(&self) -> &'a T

Returns a shared reference to the value. If the value may be uninitialized, as_uninit_ref must be used instead.

For the mutable counterpart see as_mut.

§Safety

When calling this method, you have to ensure that the pointer is convertible to a reference.

§Examples
use std::ptr::NonNull;

let mut x = 0u32;
let ptr = NonNull::new(&mut x as *mut _).expect("ptr is null!");

let ref_x = unsafe { ptr.as_ref() };
println!("{ref_x}");

Trait Implementations§

Source§

impl<T, A: BasicAlloc + ?Sized> Deref for SliceAllocGuard<'_, T, A>

Source§

type Target = NonNull<T>

The resulting type after dereferencing.
Source§

fn deref(&self) -> &NonNull<T>

Dereferences the value.
Source§

impl<T, A: BasicAlloc + ?Sized> Drop for SliceAllocGuard<'_, T, A>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'a, T, A> Freeze for SliceAllocGuard<'a, T, A>
where A: ?Sized,

§

impl<'a, T, A> RefUnwindSafe for SliceAllocGuard<'a, T, A>

§

impl<'a, T, A> !Send for SliceAllocGuard<'a, T, A>

§

impl<'a, T, A> !Sync for SliceAllocGuard<'a, T, A>

§

impl<'a, T, A> Unpin for SliceAllocGuard<'a, T, A>
where A: ?Sized,

§

impl<'a, T, A> UnwindSafe for SliceAllocGuard<'a, T, A>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> SizedProps for T

Source§

const SZ: usize = _

The size of the type.
Source§

const ALN: usize = _

The alignment of the type.
Source§

const LAYOUT: Layout = _

The memory layout for the type.
Source§

const IS_ZST: bool = _

Whether the type is zero-sized.
Source§

const MAX_SLICE_LEN: usize = _

The largest safe length for a [Self].
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

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

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.