use std::ops::Deref;
pub use bumpalo::Bump;
#[derive(Default)]
pub struct Allocator {
bump: Bump,
}
impl Allocator {
#[must_use]
pub fn new() -> Self {
Self { bump: Bump::new() }
}
#[must_use]
pub fn with_capacity(capacity: usize) -> Self {
Self { bump: Bump::with_capacity(capacity) }
}
#[must_use]
pub fn bump(&self) -> &Bump {
&self.bump
}
pub fn alloc<T>(&self, val: T) -> &mut T {
self.bump.alloc(val)
}
pub fn alloc_str(&self, s: &str) -> &str {
self.bump.alloc_str(s)
}
pub fn new_vec<T>(&self) -> Vec<'_, T> {
Vec::new_in(&self.bump)
}
pub fn new_vec_with_capacity<T>(&self, capacity: usize) -> Vec<'_, T> {
Vec::with_capacity_in(capacity, &self.bump)
}
pub fn new_string(&self) -> String<'_> {
String::new_in(&self.bump)
}
pub fn new_string_from(&self, s: &str) -> String<'_> {
String::from_str_in(s, &self.bump)
}
pub fn reset(&mut self) {
self.bump.reset();
}
#[must_use]
pub fn allocated_bytes(&self) -> usize {
self.bump.allocated_bytes()
}
}
impl Deref for Allocator {
type Target = Bump;
fn deref(&self) -> &Self::Target {
&self.bump
}
}
pub type Box<'a, T> = bumpalo::boxed::Box<'a, T>;
pub type Vec<'a, T> = bumpalo::collections::Vec<'a, T>;
pub type String<'a> = bumpalo::collections::String<'a>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_allocator_creation() {
let allocator = Allocator::new();
assert_eq!(allocator.allocated_bytes(), 0);
}
#[test]
fn test_alloc_value() {
let allocator = Allocator::new();
let value = allocator.alloc(42);
assert_eq!(*value, 42);
}
#[test]
fn test_alloc_str() {
let allocator = Allocator::new();
let s = allocator.alloc_str("hello");
assert_eq!(s, "hello");
}
#[test]
fn test_arena_vec() {
let allocator = Allocator::new();
let mut vec = allocator.new_vec();
vec.push(1);
vec.push(2);
vec.push(3);
assert_eq!(vec.as_slice(), &[1, 2, 3]);
}
#[test]
fn test_arena_string() {
let allocator = Allocator::new();
let mut s = allocator.new_string();
s.push_str("hello");
s.push_str(" world");
assert_eq!(s.as_str(), "hello world");
}
}