pub struct Arena<'src> { /* private fields */ }
Expand description
A memory arena, also known as a region-based allocator, or bump allocator.
See the the module-level documentation for more.
Implementations
sourceimpl Arena<'static>
impl Arena<'static>
sourcepub fn try_static_with_capacity(capacity: usize) -> Option<Self>
pub fn try_static_with_capacity(capacity: usize) -> Option<Self>
Constructs a new Arena
allocating out of heap-allocated memory.
Returns None
if the heap allocation fails.
Note that the backing memory cannot be freed even after the arena is dropped, because references to values inside it may outlive the arena.
Examples
{
let mut arena = coca::arena::Arena::try_static_with_capacity(1024 * 1024)?;
let hello = coca::fmt!(arena, "{}, {}!", "Hello", "World")?;
assert_eq!(hello.as_ref(), "Hello, World!");
}
// Backing memory is leaked!
sourcepub fn static_with_capacity(capacity: usize) -> Self
pub fn static_with_capacity(capacity: usize) -> Self
Constructs a new Arena
allocating out of heap-allocated memory.
Note that the backing memory cannot be freed even after the arena is dropped, because references to values inside it may outlive the arena.
Panics
Panics if the heap allocation fails.
sourceimpl<'src> Arena<'src>
impl<'src> Arena<'src>
sourcepub fn bytes_remaining(&self) -> usize
pub fn bytes_remaining(&self) -> usize
Calculates the size of the space remaining in the arena in bytes.
An allocation is not guaranteed to succeed even when the returned value
is greater than or equal to the requested number of bytes, because
proper alignment may require additional padding. Use the try_
methods
to handle allocation failure.
sourcepub fn make_sub_arena(&mut self) -> Arena<'_>
pub fn make_sub_arena(&mut self) -> Arena<'_>
Constructs a new Arena
allocating out of the free space remaining in self
.
self
cannot be used for allocation until the new arena is dropped.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
{
let mut tmp = arena.make_sub_arena();
let arr = tmp.alloc([0u32; 200]); // this takes up 800 / 1024 bytes...
assert!(tmp.try_alloc([0u32; 100]).is_none()); // ...so this can't succeed
}
// tmp was dropped, so the memory can be reused:
assert!(arena.try_alloc([0u32; 200]).is_some());
sourcepub fn storage_with_capacity<R: LayoutSpec>(
&mut self,
capacity: usize
) -> ArenaStorage<'src, R>
pub fn storage_with_capacity<R: LayoutSpec>(
&mut self,
capacity: usize
) -> ArenaStorage<'src, R>
Allocates enough memory in the arena for capacity
items according to
the LayoutSpec
, leaving the memory uninitialized.
Panics
Panics if capacity
is large enough to cause a LayoutError
,
or if the remaining space in the arena is insufficient.
See try_storage_with_capacity
for
a checked version that never panics.
sourcepub fn try_storage_with_capacity<R: LayoutSpec>(
&mut self,
capacity: usize
) -> Option<ArenaStorage<'src, R>>
pub fn try_storage_with_capacity<R: LayoutSpec>(
&mut self,
capacity: usize
) -> Option<ArenaStorage<'src, R>>
Allocates enough memory in the arena for capacity
items according to
the LayoutSpec
, leaving the memory uninitialized.
Returns None
if capacity
is large enough to cause a LayoutError
,
or if the remaining space in the arena is insufficient.
Examples
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let storage = arena.try_storage_with_capacity(10)?;
let pool = DirectPool::<&'static str, _>::from(storage);
assert_eq!(pool.capacity(), 10);
sourcepub fn alloc_default<T: Default + Sized>(&mut self) -> Box<'src, T>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
pub fn alloc_default<T: Default + Sized>(&mut self) -> Box<'src, T>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
Allocates memory in the arena and then places the Default
value for T
into it.
Panics
Panics if the remaining space in the arena is insufficient. See
try_alloc_default
for a checked version
that never panics.
sourcepub fn try_alloc_default<T: Default + Sized>(&mut self) -> Option<Box<'src, T>>
pub fn try_alloc_default<T: Default + Sized>(&mut self) -> Option<Box<'src, T>>
Allocates memory in the arena and then places the Default
value for T
into it.
Returns None
if the remaining space in the arena is insufficient.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
loop {
if let Some(ptr) = arena.try_alloc_default::<u128>() {
assert_eq!(*ptr, 0);
} else {
break;
}
}
assert!(arena.bytes_remaining() < 32);
sourcepub fn alloc<T: Sized>(&mut self, x: T) -> Box<'src, T>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
pub fn alloc<T: Sized>(&mut self, x: T) -> Box<'src, T>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
sourcepub fn try_alloc<T: Sized>(&mut self, x: T) -> Option<Box<'src, T>>
pub fn try_alloc<T: Sized>(&mut self, x: T) -> Option<Box<'src, T>>
Allocates memory in the arena and then places x
into it.
Returns None
if the remaining space in the arena is insufficient.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
loop {
if let Some(ptr) = arena.try_alloc(0xDEAD_BEEFu32) {
assert_eq!(*ptr, 0xDEAD_BEEF);
} else {
break;
}
}
assert!(arena.bytes_remaining() < 8);
sourcepub fn reserve<T: Sized>(&mut self) -> Box<'src, MaybeUninit<T>>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
pub fn reserve<T: Sized>(&mut self) -> Box<'src, MaybeUninit<T>>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
Allocates memory in the arena, leaving it uninitialized.
Panics
Panics if the remaining space in the arena is insufficient. See
try_reserve
for a checked version that never panics.
sourcepub fn try_reserve<T: Sized>(&mut self) -> Option<Box<'src, MaybeUninit<T>>>
pub fn try_reserve<T: Sized>(&mut self) -> Option<Box<'src, MaybeUninit<T>>>
Allocates memory in the arena, leaving it uninitialized.
Returns None
if the remaining space in the arena is insufficient.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let total = {
let reserved = arena.try_reserve::<i32>()?;
let mut tmp = arena.make_sub_arena();
let a = tmp.alloc(5);
let b = tmp.alloc(7);
reserved.init(*a + *b)
};
assert_eq!(*total, 12);
sourcepub fn reserve_array<T: Sized>(
&mut self,
count: usize
) -> Box<'src, [MaybeUninit<T>]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
pub fn reserve_array<T: Sized>(
&mut self,
count: usize
) -> Box<'src, [MaybeUninit<T>]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
Allocates memory in the arena, leaving it uninitialized.
Panics
Panics if the remaining space in the arena is insufficient. See
try_reserve_array
for a checked version
that never panics.
sourcepub fn try_reserve_array<T: Sized>(
&mut self,
count: usize
) -> Option<Box<'src, [MaybeUninit<T>]>>
pub fn try_reserve_array<T: Sized>(
&mut self,
count: usize
) -> Option<Box<'src, [MaybeUninit<T>]>>
Allocates memory in the arena, leaving it uninitialized.
Returns None
if the remaining space in the arena is insufficient.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let sums = arena
.try_reserve_array::<usize>(100)?
.init_with(|n| (n * (n + 1)) / 2);
assert!(arena.try_reserve_array::<usize>(100).is_none());
assert_eq!(&sums[..10], [0, 1, 3, 6, 10, 15, 21, 28, 36, 45]);
assert_eq!(sums.last(), Some(&4950));
sourcepub fn array_default<T>(&mut self, count: usize) -> Box<'src, [T]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
where
T: Default + Sized,
pub fn array_default<T>(&mut self, count: usize) -> Box<'src, [T]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
where
T: Default + Sized,
Allocates memory in the arena and then places count
copies of the
Default
value for T into it.
Consider using alloc_default<[T; count]>
instead when count
is known at compile time.
Panics
Panics if the remaining space in the arena is insufficient.
See try_array_default
for a checked
version that never panics.
sourcepub fn try_array_default<T>(&mut self, count: usize) -> Option<Box<'src, [T]>> where
T: Default + Sized,
pub fn try_array_default<T>(&mut self, count: usize) -> Option<Box<'src, [T]>> where
T: Default + Sized,
Allocates memory in the arena and then places count
copies of the
Default
value for T into it.
Returns None
if the remaining space in the arena is insufficient.
Consider using try_alloc_default<[T; count]>
instead when count
is known at compile time.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let array = arena.try_array_default::<u128>(16)?;
assert_eq!(&array[..], &[0; 16]);
sourcepub fn array<T>(&mut self, x: T, count: usize) -> Box<'src, [T]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
where
T: Copy + Sized,
pub fn array<T>(&mut self, x: T, count: usize) -> Box<'src, [T]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
where
T: Copy + Sized,
Allocates memory in the arena and then places count
copies of x
into it.
Consider using alloc([x; count])
instead when count
is known at compile time.
Panics
Panics if the remaining space in the arena is insufficient.
See try_array
for a checked version that never panics.
sourcepub fn try_array<T>(&mut self, x: T, count: usize) -> Option<Box<'src, [T]>> where
T: Copy + Sized,
pub fn try_array<T>(&mut self, x: T, count: usize) -> Option<Box<'src, [T]>> where
T: Copy + Sized,
Allocates memory in the arena and then places count
copies of x
into it.
Returns None
if the remaining space in the arena is insufficient.
Consider using try_alloc([x; count])
instead when
count
is known at compile time.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let array = arena.try_array(0x12345678u32, 200)?;
assert_eq!(&array[..], &[0x12345678u32; 200]);
sourcepub fn with_capacity<S, C>(&mut self, capacity: usize) -> C where
C: From<ArenaStorage<'src, S>>,
S: LayoutSpec,
pub fn with_capacity<S, C>(&mut self, capacity: usize) -> C where
C: From<ArenaStorage<'src, S>>,
S: LayoutSpec,
Constructs a collection C
with the given capacity, backed by arena-allocated memory.
Panics
Panics if the remaining space is insufficient.
See try_with_capacity
for a checked version
that never panics.
sourcepub fn try_with_capacity<S, C>(&mut self, capacity: usize) -> Option<C> where
C: From<ArenaStorage<'src, S>>,
S: LayoutSpec,
pub fn try_with_capacity<S, C>(&mut self, capacity: usize) -> Option<C> where
C: From<ArenaStorage<'src, S>>,
S: LayoutSpec,
Constructs a collection C
with the given capacity, backed by arena-allocated memory.
Returns None
if the remaining space is insufficient.
sourcepub fn string_from<I: Capacity, T: AsRef<str>>(
&mut self,
value: T
) -> ArenaString<'src, I>
pub fn string_from<I: Capacity, T: AsRef<str>>(
&mut self,
value: T
) -> ArenaString<'src, I>
Constructs an ArenaString
initialized with the given contents, and no excess capacity.
Panics
Panics if the remaining space in the arena is insufficient.
See try_string_from
for a checked version that never panics.
sourcepub fn try_string_from<I: Capacity, T: AsRef<str>>(
&mut self,
value: T
) -> Option<ArenaString<'src, I>>
pub fn try_string_from<I: Capacity, T: AsRef<str>>(
&mut self,
value: T
) -> Option<ArenaString<'src, I>>
Constructs an ArenaString
initialized with the given contents, and no excess capacity.
Returns None
if the remaining space in the arena is insufficient.
Examples
use coca::arena::Arena;
use core::mem::MaybeUninit;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let mut s: coca::ArenaString<'_, usize> = arena.try_string_from("Hello, World!")?;
assert_eq!(s, "Hello, World!");
assert_eq!(s.len(), s.capacity());
sourcepub fn string_with_capacity_from<I: Capacity, T: AsRef<str>>(
&mut self,
capacity: I,
value: T
) -> ArenaString<'src, I>
pub fn string_with_capacity_from<I: Capacity, T: AsRef<str>>(
&mut self,
capacity: I,
value: T
) -> ArenaString<'src, I>
Constructs an ArenaString
with the given capacity,
and initializes it with the given contents.
Panics
Panics if the remaining space in the arena is insufficient.
See try_string_with_capacity_from
for a checked version that never panics.
sourcepub fn try_string_with_capacity_from<I: Capacity, T: AsRef<str>>(
&mut self,
capacity: I,
value: T
) -> Option<ArenaString<'src, I>>
pub fn try_string_with_capacity_from<I: Capacity, T: AsRef<str>>(
&mut self,
capacity: I,
value: T
) -> Option<ArenaString<'src, I>>
Constructs an ArenaString
with the given capacity,
and initializes it with the given contents.
Returns None
if the remaining space in the arena is insufficient,
or if value.as_ref().len()
is larger than capacity
.
Examples
use coca::arena::Arena;
use core::mem::MaybeUninit;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let mut s = arena.try_string_with_capacity_from(100usize, "Hello, World!")?;
assert_eq!(s, "Hello, World!");
assert_eq!(s.capacity(), 100);
sourcepub fn try_cache_with_hasher<K: Eq + Hash, V, L: CacheLine<K, V>, H: BuildHasher>(
&mut self,
capacity: usize,
hash_builder: H
) -> Option<CacheTable<K, V, ArenaStorage<'src, ArrayLayout<L>>, L, H>>
pub fn try_cache_with_hasher<K: Eq + Hash, V, L: CacheLine<K, V>, H: BuildHasher>(
&mut self,
capacity: usize,
hash_builder: H
) -> Option<CacheTable<K, V, ArenaStorage<'src, ArrayLayout<L>>, L, H>>
Constructs a new CacheTable
with the specified hash builder and capacity, rounded up to the next multiple of L::CAPACITY
.
Returns None
if the remaining space in the arena is insufficient.
sourcepub fn cache_with_hasher<K: Eq + Hash, V, L: CacheLine<K, V>, H: BuildHasher>(
&mut self,
capacity: usize,
hash_builder: H
) -> CacheTable<K, V, ArenaStorage<'src, ArrayLayout<L>>, L, H>
pub fn cache_with_hasher<K: Eq + Hash, V, L: CacheLine<K, V>, H: BuildHasher>(
&mut self,
capacity: usize,
hash_builder: H
) -> CacheTable<K, V, ArenaStorage<'src, ArrayLayout<L>>, L, H>
Constructs a new CacheTable
with the specified hash builder and capacity, rounded up to the next multiple of L::CAPACITY
.
Panics
Panics if the remaining space in the arena is insufficient to exhaust
the iterator. See try_cache_with_hasher
for a checked version that never panics.
sourcepub fn collect_slice<T, I>(&mut self, iter: I) -> Box<'src, [T]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
where
T: Sized,
I: IntoIterator<Item = T>,
pub fn collect_slice<T, I>(&mut self, iter: I) -> Box<'src, [T]>ⓘNotable traits for Box<'_, I>impl<I: Iterator + ?Sized> Iterator for Box<'_, I> type Item = I::Item;
where
T: Sized,
I: IntoIterator<Item = T>,
Transforms an iterator into a boxed slice in the arena.
Panics
Panics if the remaining space in the arena is insufficient to exhaust
the iterator. See try_collect_slice
for a checked version that never panics.
sourcepub fn try_collect_slice<T, I>(&mut self, iter: I) -> Option<Box<'src, [T]>> where
T: Sized,
I: IntoIterator<Item = T>,
pub fn try_collect_slice<T, I>(&mut self, iter: I) -> Option<Box<'src, [T]>> where
T: Sized,
I: IntoIterator<Item = T>,
Transforms an iterator into a boxed slice in the arena.
Returns None
if the remaining space in the arena is insufficient
to exhaust the iterator.
Examples
use core::mem::{MaybeUninit, size_of, size_of_val};
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let a = [1, 2, 3];
let doubled = arena.try_collect_slice(a.iter().map(|&x| x * 2))?;
assert_eq!(&doubled[..], &[2, 4, 6]);
sourcepub fn collect_with_capacity<I, S, C>(&mut self, iter: I, capacity: usize) -> C where
S: LayoutSpec,
C: From<ArenaStorage<'src, S>> + Extend<I::Item>,
I: Iterator,
pub fn collect_with_capacity<I, S, C>(&mut self, iter: I, capacity: usize) -> C where
S: LayoutSpec,
C: From<ArenaStorage<'src, S>> + Extend<I::Item>,
I: Iterator,
Transforms an iterator into a collection C
with the given capacity.
The collection type must be convertible From<ArenaStorage>
,
i.e. able to use arena-allocated memory, and must be Extend
able
by including the contents of the given iterator.
Panics
Panics if the remaining space is insufficient.
sourcepub fn try_collect_with_capacity<I, S, C>(
&mut self,
iter: I,
capacity: usize
) -> Option<C> where
S: LayoutSpec,
C: From<ArenaStorage<'src, S>> + Extend<I::Item>,
I: Iterator,
pub fn try_collect_with_capacity<I, S, C>(
&mut self,
iter: I,
capacity: usize
) -> Option<C> where
S: LayoutSpec,
C: From<ArenaStorage<'src, S>> + Extend<I::Item>,
I: Iterator,
Transforms an iterator into a collection C
with the given capacity.
The collection type must be convertible From<ArenaStorage>
,
i.e. able to use arena-allocated memory, and must be Extend
able
by including the contents of the given iterator.
Returns None
if the remaining space is insufficient.
Examples
use core::mem::{MaybeUninit, size_of, size_of_val};
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let chars = ['a', 'b', 'c', 'd', 'e'];
let s: coca::ArenaString<'_, usize> = arena.try_collect_with_capacity(chars.iter(), 8)?;
assert_eq!(s, "abcde");
sourcepub fn make_writer<'a>(&'a mut self) -> Writer<'a, 'src>
pub fn make_writer<'a>(&'a mut self) -> Writer<'a, 'src>
Constructs a new Writer
backed by the free space remaining in self
.
The arena cannot be used for allocation until the writer is dropped.
Primarily intended for use in expansions of fmt!
. This should only
be used explicitly where format strings don’t work as well.
Examples
use coca::arena::{Arena, Box};
use core::{fmt::Write, mem::MaybeUninit};
let parts = ["Hello", ",", " ", "World", "!"];
let mut backing_region = [MaybeUninit::uninit(); 1024];
let mut arena = Arena::from(&mut backing_region[..]);
let mut writer = arena.make_writer();
for s in parts.iter() {
writer.write_str(s)?;
}
let combined: Box::<'_, str> = writer.into();
assert_eq!(combined.as_ref(), "Hello, World!");
sourceimpl Arena<'_>
impl Arena<'_>
sourcepub fn utilization(&self) -> UtilizationProfile
pub fn utilization(&self) -> UtilizationProfile
Returns a profile of all allocations from the arena and all sub-arenas created from it.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 256];
let mut arena = Arena::from(&mut backing_region[..]);
{
let mut tmp = arena.make_sub_arena();
let _ = tmp.array_default::<u8>(100);
}
{
let mut tmp = arena.make_sub_arena();
let _ = tmp.array_default::<u8>(50);
let _ = tmp.try_array_default::<u8>(200);
}
{
let mut tmp = arena.make_sub_arena();
let _ = tmp.array_default::<u8>(200);
}
let profile = arena.utilization();
assert_eq!(profile.peak_utilization, 200);
assert_eq!(profile.allocation_count, 4);
assert_eq!(profile.failed_allocations, 1);
Trait Implementations
sourceimpl<'src> From<&'src mut [MaybeUninit<u8>]> for Arena<'src>
impl<'src> From<&'src mut [MaybeUninit<u8>]> for Arena<'src>
sourcefn from(buf: &mut [MaybeUninit<u8>]) -> Self
fn from(buf: &mut [MaybeUninit<u8>]) -> Self
Constructs a new Arena
allocating out of buf
.
Panics
When compiled with the profile
feature, panics if buf
is too small
to fit the profiling meta data. The exact threshold depends on the size
of usize
on the target platform, and the alignment of buf
, but this
is guaranteed to succeed if buf.len() >= 40
.
Examples
use core::mem::MaybeUninit;
use coca::arena::Arena;
let mut backing_region = [MaybeUninit::uninit(); 1024];
let arena = Arena::from(&mut backing_region[..]);
Auto Trait Implementations
impl<'src> RefUnwindSafe for Arena<'src>
impl<'src> !Send for Arena<'src>
impl<'src> !Sync for Arena<'src>
impl<'src> Unpin for Arena<'src>
impl<'src> !UnwindSafe for Arena<'src>
Blanket Implementations
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more