Name Description Size
alloc.rs Memory allocation APIs 31452
boxed.rs A pointer type for bump allocation. [`Box<'a, T>`] provides the simplest form of bump allocation in `bumpalo`. Boxes provide ownership for this allocation, and drop their contents when they go out of scope. # Examples Move a value from the stack to the heap by creating a [`Box`]: ``` use bumpalo::{Bump, boxed::Box}; let b = Bump::new(); let val: u8 = 5; let boxed: Box<u8> = Box::new_in(val, &b); ``` Move a value from a [`Box`] back to the stack by [dereferencing]: ``` use bumpalo::{Bump, boxed::Box}; let b = Bump::new(); let boxed: Box<u8> = Box::new_in(5, &b); let val: u8 = *boxed; ``` Running [`Drop`] implementations on bump-allocated values: ``` use bumpalo::{Bump, boxed::Box}; use std::sync::atomic::{AtomicUsize, Ordering}; static NUM_DROPPED: AtomicUsize = AtomicUsize::new(0); struct CountDrops; impl Drop for CountDrops { fn drop(&mut self) { NUM_DROPPED.fetch_add(1, Ordering::SeqCst); } } // Create a new bump arena. let bump = Bump::new(); // Create a `CountDrops` inside the bump arena. let mut c = Box::new_in(CountDrops, &bump); // No `CountDrops` have been dropped yet. assert_eq!(NUM_DROPPED.load(Ordering::SeqCst), 0); // Drop our `Box<CountDrops>`. drop(c); // Its `Drop` implementation was run, and so `NUM_DROPS` has been incremented. assert_eq!(NUM_DROPPED.load(Ordering::SeqCst), 1); ``` Creating a recursive data structure: ``` use bumpalo::{Bump, boxed::Box}; let b = Bump::new(); #[derive(Debug)] enum List<'a, T> { Cons(T, Box<'a, List<'a, T>>), Nil, } let list: List<i32> = List::Cons(1, Box::new_in(List::Cons(2, Box::new_in(List::Nil, &b)), &b)); println!("{:?}", list); ``` This will print `Cons(1, Cons(2, Nil))`. Recursive structures must be boxed, because if the definition of `Cons` looked like this: ```compile_fail,E0072 # enum List<T> { Cons(T, List<T>), # } ``` It wouldn't work. This is because the size of a `List` depends on how many elements are in the list, and so we don't know how much memory to allocate for a `Cons`. By introducing a [`Box<'a, T>`], which has a defined size, we know how big `Cons` needs to be. # Memory layout For non-zero-sized values, a [`Box`] will use the provided [`Bump`] allocator for its allocation. It is valid to convert both ways between a [`Box`] and a pointer allocated with the [`Bump`] allocator, given that the [`Layout`] used with the allocator is correct for the type. More precisely, a `value: *mut T` that has been allocated with the [`Bump`] allocator with `Layout::for_value(&*value)` may be converted into a box using [`Box::<T>::from_raw(value)`]. Conversely, the memory backing a `value: *mut T` obtained from [`Box::<T>::into_raw`] will be deallocated by the [`Bump`] allocator with [`Layout::for_value(&*value)`]. Note that roundtrip `Box::from_raw(Box::into_raw(b))` looses the lifetime bound to the [`Bump`] immutable borrow which guarantees that the allocator will not be reset and memory will not be freed. [dereferencing]: https://doc.rust-lang.org/std/ops/trait.Deref.html [`Box`]: struct.Box.html [`Box<'a, T>`]: struct.Box.html [`Box::<T>::from_raw(value)`]: struct.Box.html#method.from_raw [`Box::<T>::into_raw`]: struct.Box.html#method.into_raw [`Bump`]: ../struct.Bump.html [`Drop`]: https://doc.rust-lang.org/std/ops/trait.Drop.html [`Layout`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html [`Layout::for_value(&*value)`]: https://doc.rust-lang.org/std/alloc/struct.Layout.html#method.for_value 20560
collections
lib.rs 76490