pub struct BumpInto<'a> { /* private fields */ }
Expand description
A bump allocator sourcing space from an &mut [MaybeUninit]
.
Allocation methods produce mutable references with lifetimes
tied to the lifetime of the backing slice, meaning the
BumpInto
itself can be freely moved around, including
between threads.
Values held in BumpInto
allocations are never dropped.
If they must be dropped, you can use
core::mem::ManuallyDrop::drop
or core::ptr::drop_in_place
to drop them explicitly (and unsafely). In safe code, you can
allocate an Option
and drop the value inside by overwriting
it with None
.
Implementations§
source§impl<'a> BumpInto<'a>
impl<'a> BumpInto<'a>
sourcepub fn from_slice<S>(array: &'a mut [MaybeUninit<S>]) -> Self
pub fn from_slice<S>(array: &'a mut [MaybeUninit<S>]) -> Self
Creates a new BumpInto
, wrapping a slice of MaybeUninit<S>
.
sourcepub fn available_bytes(&self) -> usize
pub fn available_bytes(&self) -> usize
Returns the number of bytes remaining in the allocator’s space.
sourcepub fn available_spaces<L: Into<Option<Layout>>>(&self, layout: L) -> usize
pub fn available_spaces<L: Into<Option<Layout>>>(&self, layout: L) -> usize
Returns the number of spaces of the given layout that could be allocated in a contiguous region within the allocator’s remaining space.
Returns usize::MAX
if the layout is zero-sized.
Notes
This function is safe, but it will return an unspecified
value if layout
has a size that isn’t a multiple of its
alignment. All types in Rust have sizes that are multiples
of their alignments, so this function will behave as
expected when given Layout
s corresponding to actual
types, such as those created with Layout::new
or
Layout::array
. You can use Layout::pad_to_align
to
make sure a Layout
meets the requirement.
sourcepub fn available_spaces_for<T>(&self) -> usize
pub fn available_spaces_for<T>(&self) -> usize
Returns the number of T
that could be allocated in a
contiguous region within the allocator’s remaining space.
Returns usize::MAX
if T
is a zero-sized type.
sourcepub fn alloc_space<L: Into<Option<Layout>>>(
&self,
layout: L
) -> *mut MaybeUninit<u8>
pub fn alloc_space<L: Into<Option<Layout>>>( &self, layout: L ) -> *mut MaybeUninit<u8>
Tries to allocate a space of the given layout. Returns a null pointer on failure.
sourcepub fn alloc_space_for<T>(&self) -> *mut T
pub fn alloc_space_for<T>(&self) -> *mut T
Tries to allocate enough space to store a T
.
Returns a properly aligned pointer to uninitialized T
if
there was enough space; otherwise returns a null pointer.
sourcepub fn alloc_space_for_n<T>(&self, count: usize) -> *mut T
pub fn alloc_space_for_n<T>(&self, count: usize) -> *mut T
Tries to allocate enough space to store count
number of T
.
Returns a properly aligned pointer to uninitialized T
if
there was enough space; otherwise returns a null pointer.
sourcepub fn alloc_space_to_limit_for<T>(&self) -> (NonNull<T>, usize)
pub fn alloc_space_to_limit_for<T>(&self) -> (NonNull<T>, usize)
Allocates space for as many aligned T
as will fit in the
free space of this BumpInto
. Returns a tuple holding a
pointer to the lowest T
-space that was just allocated and
the count of T
that will fit (which may be zero).
This method will produce a count of usize::MAX
if T
is
a zero-sized type.
sourcepub fn alloc<T>(&self, x: T) -> Result<&'a mut T, T>
pub fn alloc<T>(&self, x: T) -> Result<&'a mut T, T>
Tries to allocate enough space to store a T
and place x
there.
On success (i.e. if there was enough space) produces a mutable
reference to x
with the lifetime of this BumpInto
’s backing
slice ('a
).
On failure, produces x
.
sourcepub fn alloc_with<T, F: FnOnce() -> T>(&self, f: F) -> Result<&'a mut T, F>
pub fn alloc_with<T, F: FnOnce() -> T>(&self, f: F) -> Result<&'a mut T, F>
Tries to allocate enough space to store a T
and place the result
of calling f
there.
On success (i.e. if there was enough space) produces a mutable
reference to the stored result with the lifetime of this
BumpInto
’s backing slice ('a
).
On failure, produces f
.
Allocating within f
is allowed; f
is only called after the
initial allocation succeeds.
sourcepub fn alloc_copy<T: Copy>(&self, x: &T) -> Option<&'a mut T>
pub fn alloc_copy<T: Copy>(&self, x: &T) -> Option<&'a mut T>
Tries to allocate enough space to store a T
and copy the value
pointed to by x
into it.
On success (i.e. if there was enough space) produces a mutable
reference to the copy with the lifetime of this BumpInto
’s
backing slice ('a
).
sourcepub fn alloc_copy_slice<T: Copy>(&self, xs: &[T]) -> Option<&'a mut [T]>
pub fn alloc_copy_slice<T: Copy>(&self, xs: &[T]) -> Option<&'a mut [T]>
Tries to allocate enough space to store a copy of xs
and copy
xs
into it.
On success (i.e. if there was enough space) produces a mutable
reference to the copy with the lifetime of this BumpInto
’s
backing slice ('a
).
sourcepub fn alloc_copy_concat_slices<T: Copy>(
&self,
xs_s: &[&[T]]
) -> Option<&'a mut [T]>
pub fn alloc_copy_concat_slices<T: Copy>( &self, xs_s: &[&[T]] ) -> Option<&'a mut [T]>
Tries to allocate enough space to store the concatenation of
the slices in xs_s
and build said concatenation by copying
the contents of each slice in order.
On success (i.e. if there was enough space) produces a mutable
reference to the copy with the lifetime of this BumpInto
’s
backing slice ('a
).
Example
use bump_into::{self, BumpInto};
let mut space = bump_into::space_uninit!(16);
let bump_into = BumpInto::from_slice(&mut space[..]);
let bytestring = b"Hello, World!";
let null_terminated_bytestring = bump_into
.alloc_copy_concat_slices(&[bytestring, &[0]])
.unwrap();
assert_eq!(null_terminated_bytestring, b"Hello, World!\0");
sourcepub fn alloc_copy_concat_strs(&self, strs: &[&str]) -> Option<&'a mut str>
pub fn alloc_copy_concat_strs(&self, strs: &[&str]) -> Option<&'a mut str>
Tries to allocate enough space to store the concatenation of
the str
s in strs
and build said concatenation by copying
the contents of each str
in order.
On success (i.e. if there was enough space) produces a mutable
reference to the copy with the lifetime of this BumpInto
’s
backing slice ('a
).
Example
use bump_into::{self, BumpInto};
let mut space = bump_into::space_uninit!(16);
let bump_into = BumpInto::from_slice(&mut space[..]);
let string = "Hello, World!";
let null_terminated_string = bump_into
.alloc_copy_concat_strs(&[string, "\0"])
.unwrap();
assert_eq!(null_terminated_string, "Hello, World!\0");
sourcepub fn alloc_n_with<T, I: IntoIterator<Item = T>>(
&self,
count: usize,
iter: I
) -> Result<&'a mut [T], I>
pub fn alloc_n_with<T, I: IntoIterator<Item = T>>( &self, count: usize, iter: I ) -> Result<&'a mut [T], I>
Tries to allocate enough space to store count
number of T
and
fill it with the values produced by iter.into_iter()
.
On success (i.e. if there was enough space) produces a mutable
reference to the stored results as a slice, with the lifetime of
this BumpInto
’s backing slice ('a
).
On failure, produces iter
.
If the iterator ends before producing enough items to fill the allocated space, the same amount of space is allocated, but the returned slice is just long enough to hold the items that were actually produced.
Allocating within the iterator’s next
method is allowed;
iteration only begins after the initial allocation succeeds.
sourcepub fn alloc_down_with<T, I: IntoIterator<Item = T>>(
&mut self,
iter: I
) -> &'a mut [T]
pub fn alloc_down_with<T, I: IntoIterator<Item = T>>( &mut self, iter: I ) -> &'a mut [T]
Allocates enough space to store as many of the values produced
by iter.into_iter()
as possible. Produces a mutable reference
to the stored results as a slice, in the opposite order to the
order they were produced in, with the lifetime of this
BumpInto
’s backing slice ('a
).
This method will create a slice of up to usize::MAX
elements
if T
is a zero-sized type. This means it technically will not
try to exhaust an infinite iterator, but it may still take much
longer than expected in generic code if you don’t check whether
T
is zero-sized!
If you have only a shared reference, and especially if you must
call non-allocating methods of self
within the iterator,
you can use the unsafe alloc_down_with_shared
.
Unsafe version of alloc_down_with
, taking self
as a
shared reference instead of a mutable reference.
Safety
Undefined behavior may result if any methods of this BumpInto
are called from within the next
method of the iterator, with
the exception of the available_bytes
, available_spaces
,
and available_spaces_for
methods, which are safe.