Struct without_alloc::uninit::Uninit
source · [−]pub struct Uninit<'a, T: ?Sized> { /* private fields */ }
Expand description
Points to an uninitialized place but would otherwise be a valid reference.
This is a &mut
-like struct that is somewhat of a pendant to MaybeUninit
. It makes it
possible to deal with uninitialized allocations without requiring an unsafe
block
initializing them and offers a much safer interface for partial initialization and layout
calculations than raw pointers.
Note that it also supports slices which means it does not use MaybeUninit
internally but
offers conversion where necessary.
Usage
The basic usage is also interacting with MaybeUninit
:
use core::mem::MaybeUninit;
use without_alloc::Uninit;
let mut alloc: MaybeUninit<MyStruct> = MaybeUninit::uninit();
let uninit = Uninit::from_maybe_uninit(&mut alloc);
// notice: no unsafe
let instance: &mut MyStruct = uninit.init(MyStruct::default());
But since we are working on arbitrary uninitialized memory it is also possible to reuse the
structure for completely arbitrary other types. Just note that there is no integrated mechanis
for calling Drop
.
use core::mem::MaybeUninit;
use without_alloc::Uninit;
// Just a generic buffer.
let mut alloc: MaybeUninit<[u32; 1024]> = MaybeUninit::uninit();
let uninit = Uninit::from_maybe_uninit(&mut alloc);
// Now use the first `u32` for a counter:
let mut counter = uninit.cast().unwrap();
let mut tail = counter.split_to_fit();
let counter: &mut u32 = counter.init(0);
// And some more for a few `u64`.
// Note that these are not trivially aligned, but `Uninit` does that for us.
let mut values = tail.split_cast().unwrap();
// No more use, so don't bother with `split_to_fit` and just `init`.
let values: &mut [u64; 2] = values.init([0xdead, 0xbeef]);
Implementations
sourceimpl Uninit<'_, ()>
impl Uninit<'_, ()>
sourcepub unsafe fn from_memory(ptr: NonNull<u8>, len: usize) -> Self
pub unsafe fn from_memory(ptr: NonNull<u8>, len: usize) -> Self
Create a uninit pointer from raw memory.
Safety
A valid allocation must exist at the pointer with length at least len
. There must be no
references aliasing the memory location, and it must be valid to write uninitialized bytes
into arbitrary locations of the region.
In particular, it is UB to create this from a reference to a variable of a type for
which a completely uninitialized content is not valid. The standard type for avoiding the
UB is core::mem::MaybeUninit
.
When in doubt, refactor code such that utilization of from_maybe_uninit
is possible.
sourcepub fn split_layout(&mut self, layout: Layout) -> Option<Self>
pub fn split_layout(&mut self, layout: Layout) -> Option<Self>
Split so that the second part fits the layout.
Return Ok
if this is possible in-bounds and Err
if it is not.
sourceimpl<'a> Uninit<'a, ()>
impl<'a> Uninit<'a, ()>
sourcepub fn split_cast<U>(&mut self) -> Option<Uninit<'a, U>>
pub fn split_cast<U>(&mut self) -> Option<Uninit<'a, U>>
Split so that the tail is aligned and valid for a U
.
Return Ok
if this is possible in-bounds (aligned and enough room for at least one U
)
and Err
if it is not. The first tuple element is the Uninit
pointing to the skipped
memory.
sourcepub fn split_slice<U>(&mut self) -> Option<Uninit<'a, [U]>>
pub fn split_slice<U>(&mut self) -> Option<Uninit<'a, [U]>>
Split so that the tail is aligned for a slice [U]
.
Return Ok
if this is possible in-bounds and Err
if it is not. The first tuple element
is the Uninit
pointing to the skipped memory.
The length of the slice is the arbitrary amount that fits into the tail of the allocation.
Note that the length always fulfills the safety requirements for slice::from_raw_parts
since the Uninit
must be contained in a single allocation.
sourceimpl<T> Uninit<'_, T>
impl<T> Uninit<'_, T>
sourcepub fn invent_for_zst() -> Self
pub fn invent_for_zst() -> Self
Invent a new uninit allocation for a zero-sized type (ZST).
Panics
This method panics when the type parameter is not a zero sized type.
sourceimpl<'a, T> Uninit<'a, T>
impl<'a, T> Uninit<'a, T>
sourcepub unsafe fn from_view(view: UninitView<'a, T>) -> Self
pub unsafe fn from_view(view: UninitView<'a, T>) -> Self
Create an uninit
from a view.
Safety
The caller must prove that the pointed-to memory is mutable and that it is unaliased.
sourcepub fn from_maybe_uninit(mem: &'a mut MaybeUninit<T>) -> Self
pub fn from_maybe_uninit(mem: &'a mut MaybeUninit<T>) -> Self
Create an initializable pointer to the inner bytes of a MaybeUninit
.
sourcepub fn split_at_byte(&mut self, at: usize) -> Option<Uninit<'a, ()>>
pub fn split_at_byte(&mut self, at: usize) -> Option<Uninit<'a, ()>>
Split the uninit slice at a byte boundary.
Return Ok
if the location is in-bounds and Err
if it is out of bounds.
sourcepub fn cast<U>(self) -> Result<Uninit<'a, U>, Self>
pub fn cast<U>(self) -> Result<Uninit<'a, U>, Self>
Try to cast to an Uninit
for another type.
Return Ok
if the current Uninit
is suitably aligned and large enough to hold at least
one U
and Err
if it is not. Note that the successful result points to unused remaining
memory behind where the instance can be placed.
Use split_to_fit
to get rid of surplus memory at the end.
sourcepub fn cast_slice<U>(self) -> Result<Uninit<'a, [U]>, Self>
pub fn cast_slice<U>(self) -> Result<Uninit<'a, [U]>, Self>
Try to cast to an Uninit
for a slice type.
Return Ok
if the current Uninit
is suitably aligned and large enough to hold at least
one U
and Err
if it is not. Note that the successful result points to unused remaining
memory behind where the instances can be placed.
sourcepub fn split_to_fit(&mut self) -> Uninit<'a, ()>
pub fn split_to_fit(&mut self) -> Uninit<'a, ()>
Split off the tail that is not required for holding an instance of T
.
This operation is idempotent.
sourceimpl<'a, T: ?Sized> Uninit<'a, T>
impl<'a, T: ?Sized> Uninit<'a, T>
sourcepub const fn as_non_null(&self) -> NonNull<T>
pub const fn as_non_null(&self) -> NonNull<T>
Acquires the underlying pointer as a NonNull
.
sourcepub unsafe fn as_ref(&self) -> &T
pub unsafe fn as_ref(&self) -> &T
Dereferences the content.
The resulting lifetime is bound to self so this behaves “as if” it were actually an
instance of T that is getting borrowed. If a longer lifetime is needed, use into_ref
.
Safety
The pointee must have been initialized through other means.
sourcepub unsafe fn as_mut(&mut self) -> &mut T
pub unsafe fn as_mut(&mut self) -> &mut T
Mutably dereferences the content.
The resulting lifetime is bound to self so this behaves “as if” it were actually an
instance of T that is getting borrowed. If a longer lifetime is needed, use into_mut
.
Safety
The pointee must have been initialized through other means.
sourceimpl<'a, T> Uninit<'a, T>
impl<'a, T> Uninit<'a, T>
sourcepub fn init(self, val: T) -> &'a mut T
pub fn init(self, val: T) -> &'a mut T
Initialize the place and return a reference to the value.
sourcepub fn into_maybe_uninit(self) -> &'a mut MaybeUninit<T>
pub fn into_maybe_uninit(self) -> &'a mut MaybeUninit<T>
Turn this into a reference to standard MaybeUninit
.
This is mainly useful for interfacing with other consumers which expect standard library
types. It may also improve ergonomics for writing to the pointee partially initialized
instances of T
that are obtained via other means.
Note that the sequence from_maybe_uninit
, into_maybe_uninit
is a no-op. The converse is
however not the case, as it will potentially discard unused padding present in the original
Uninit
.
sourcepub unsafe fn read(&self) -> T
pub unsafe fn read(&self) -> T
Read a value from the uninit place without moving it.
The Uninit
ensures that the inner pointer is correctly aligned, non-null, and points to a
large enough region for reading a T
.
Safety
Caller must ensure that the memory is initialized as a valid T
. It must also avoid double
Drop
. Basically, a new instance is created.
sourceimpl<'a, T> Uninit<'a, [T]>
impl<'a, T> Uninit<'a, [T]>
sourcepub fn from_maybe_uninit_slice(mem: &'a mut [MaybeUninit<T>]) -> Self
pub fn from_maybe_uninit_slice(mem: &'a mut [MaybeUninit<T>]) -> Self
Create an initializable pointer to the inner bytes of a MaybeUninit
.
sourcepub const fn as_begin_ptr(&self) -> *mut T
pub const fn as_begin_ptr(&self) -> *mut T
Get the pointer to the first element of the slice.
If the slice would be empty then the pointer may be the past-the-end pointer as well.
sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Calculate the theoretical capacity of a slice in the pointed-to allocation.
sourcepub fn split_at(&mut self, at: usize) -> Option<Self>
pub fn split_at(&mut self, at: usize) -> Option<Self>
Split the slice at an index.
This is the pointer equivalent of slice::split_at
.
sourcepub fn shrink_to_fit(&mut self) -> Uninit<'a, ()>
pub fn shrink_to_fit(&mut self) -> Uninit<'a, ()>
Get the trailing bytes behind the slice.
The underlying allocation need not be a multiple of the slice element size which may leave
unusable bytes. This splits these unusable bytes into an untyped Uninit
which can be
reused arbitrarily.
This operation is idempotent.
sourcepub fn split_first(&mut self) -> Option<Uninit<'a, T>>
pub fn split_first(&mut self) -> Option<Uninit<'a, T>>
Split the first element from the slice.
This is the pointer equivalent of slice::split_first
.
sourcepub fn split_last(&mut self) -> Option<Uninit<'a, T>>
pub fn split_last(&mut self) -> Option<Uninit<'a, T>>
Split the last element from the slice.
This is the pointer equivalent of slice::split_last
.
sourcepub fn into_maybe_uninit_slice(self) -> &'a mut [MaybeUninit<T>]
pub fn into_maybe_uninit_slice(self) -> &'a mut [MaybeUninit<T>]
Turn this into a slice of standard MaybeUninit
s.
This is mainly useful for interfacing with other consumers which expect standard library
types. It may also improve ergonomics for writing to the pointee partially initialized
instances of T
that are obtained via other means.
Note that the sequence from_maybe_uninit_slice
, into_maybe_uninit_slice
is a no-op. The
converse is however not the case, as it will potentially discard unused padding present in
the original Uninit
.
sourceimpl<'a, T: ?Sized> Uninit<'a, T>
impl<'a, T: ?Sized> Uninit<'a, T>
sourcepub unsafe fn new(ptr: NonNull<T>, len: usize) -> Self
pub unsafe fn new(ptr: NonNull<T>, len: usize) -> Self
Create a view to typed uninitialized memory.
It is given a capacity of memory to which it refers in bytes.
Safety
The ptr
must describe a valid, sized region. Refer to Layout::for_value_raw
for
details. This criteria is trivially fulfilled for any sized T
.
A valid allocation must exist at the pointer with length at least len
.
In particular, it is UB to create this from a reference to a variable of a type for
which a completely uninitialized content is not valid. The standard type for avoiding the
UB is core::mem::MaybeUninit
.
When in doubt, refactor code such that utilization of from_maybe_uninit
is possible.
sourcepub fn byte_capacity(&self) -> usize
pub fn byte_capacity(&self) -> usize
Return the number of bytes this may view.
sourcepub fn fits(&self, layout: Layout) -> bool
pub fn fits(&self, layout: Layout) -> bool
Check if the view fits some layout.
The cast
to a type of the provided layout will work without error.
sourcepub fn borrow(&self) -> UninitView<'_, T>
pub fn borrow(&self) -> UninitView<'_, T>
Borrow a view of the Uninit
region.
This is the equivalent of &*mut_ref as *const _
but never runs afoul of accidentally
creating an actual reference.
sourcepub fn borrow_mut(&mut self) -> Uninit<'_, T>
pub fn borrow_mut(&mut self) -> Uninit<'_, T>
Borrow the Uninit
region for a shorter duration.
This is the equivalent of &mut *mut_ref as *mut _
but never runs afoul of accidentally
creating an actual reference.