use core::ptr;
use crate::{
BaseAllocator, Bump, BumpScope, BumpScopeGuard,
polyfill::transmute_mut,
settings::{BumpAllocatorSettings, MinimumAlignment, SupportedMinimumAlignment},
traits::MutBumpAllocatorTyped,
};
pub trait BumpAllocator: MutBumpAllocatorTyped + Sized {
type Allocator: BaseAllocator<<Self::Settings as BumpAllocatorSettings>::GuaranteedAllocated>;
type Settings: BumpAllocatorSettings;
#[must_use]
fn as_scope(&self) -> &BumpScope<'_, Self::Allocator, Self::Settings>;
#[must_use]
fn as_mut_scope(&mut self) -> &mut BumpScope<'_, Self::Allocator, Self::Settings>;
#[inline(always)]
fn scope_guard(&mut self) -> BumpScopeGuard<'_, Self::Allocator, Self::Settings> {
BumpScopeGuard::new(&mut self.as_mut_scope().raw)
}
#[inline(always)]
fn scoped<R>(&mut self, f: impl FnOnce(&mut BumpScope<'_, Self::Allocator, Self::Settings>) -> R) -> R {
let mut guard = self.scope_guard();
f(guard.scope())
}
#[cfg_attr(feature = "nightly-tests", doc = "```")]
#[cfg_attr(not(feature = "nightly-tests"), doc = "```ignore")]
#[inline(always)]
fn scoped_aligned<const NEW_MIN_ALIGN: usize, R>(
&mut self,
f: impl FnOnce(
&mut BumpScope<Self::Allocator, <Self::Settings as BumpAllocatorSettings>::WithMinimumAlignment<NEW_MIN_ALIGN>>,
) -> R,
) -> R
where
MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment,
{
let mut guard = self.scope_guard();
let scope = guard.scope();
scope.raw.align::<NEW_MIN_ALIGN>();
f(unsafe { transmute_mut(scope) })
}
}
impl<A, S> BumpAllocator for Bump<A, S>
where
A: BaseAllocator<S::GuaranteedAllocated>,
S: BumpAllocatorSettings,
{
type Allocator = A;
type Settings = S;
#[inline(always)]
fn as_scope(&self) -> &BumpScope<'_, Self::Allocator, Self::Settings> {
unsafe { &*ptr::from_ref(self).cast() }
}
#[inline(always)]
fn as_mut_scope(&mut self) -> &mut BumpScope<'_, Self::Allocator, Self::Settings> {
unsafe { transmute_mut(self) }
}
}
impl<A, S> BumpAllocator for BumpScope<'_, A, S>
where
A: BaseAllocator<S::GuaranteedAllocated>,
S: BumpAllocatorSettings,
{
type Allocator = A;
type Settings = S;
#[inline(always)]
fn as_scope(&self) -> &BumpScope<'_, Self::Allocator, Self::Settings> {
self
}
#[inline(always)]
fn as_mut_scope(&mut self) -> &mut BumpScope<'_, Self::Allocator, Self::Settings> {
unsafe { transmute_mut(self) }
}
}
impl<B> BumpAllocator for &mut B
where
B: BumpAllocator,
{
type Allocator = B::Allocator;
type Settings = B::Settings;
fn as_scope(&self) -> &BumpScope<'_, Self::Allocator, Self::Settings> {
B::as_scope(self)
}
fn as_mut_scope(&mut self) -> &mut BumpScope<'_, Self::Allocator, Self::Settings> {
B::as_mut_scope(self)
}
}