use crate::ArrayLayout;
trait Sealed {}
#[expect(private_bounds)]
pub trait BumpAllocatorSettings: Sealed {
const MIN_ALIGN: usize = Self::MinimumAlignment::VALUE;
const UP: bool = Self::Up::VALUE;
const GUARANTEED_ALLOCATED: bool = Self::GuaranteedAllocated::VALUE;
const CLAIMABLE: bool = Self::Claimable::VALUE;
const DEALLOCATES: bool = Self::Deallocates::VALUE;
const SHRINKS: bool = Self::Shrinks::VALUE;
const MINIMUM_CHUNK_SIZE: usize;
type MinimumAlignment: SupportedMinimumAlignment;
type Up: Boolean;
type GuaranteedAllocated: Boolean;
type Claimable: Boolean;
type Deallocates: Boolean;
type Shrinks: Boolean;
type WithMinimumAlignment<const NEW_MIN_ALIGN: usize>: BumpAllocatorSettings<
MinimumAlignment = MinimumAlignment<NEW_MIN_ALIGN>,
Up = Self::Up,
GuaranteedAllocated = Self::GuaranteedAllocated,
Claimable = Self::Claimable,
Deallocates = Self::Deallocates,
Shrinks = Self::Shrinks,
>
where
MinimumAlignment<NEW_MIN_ALIGN>: SupportedMinimumAlignment;
type WithUp<const VALUE: bool>: BumpAllocatorSettings<
MinimumAlignment = Self::MinimumAlignment,
Up = Bool<VALUE>,
GuaranteedAllocated = Self::GuaranteedAllocated,
Claimable = Self::Claimable,
Deallocates = Self::Deallocates,
Shrinks = Self::Shrinks,
>;
type WithGuaranteedAllocated<const VALUE: bool>: BumpAllocatorSettings<
MinimumAlignment = Self::MinimumAlignment,
Up = Self::Up,
GuaranteedAllocated = Bool<VALUE>,
Claimable = Self::Claimable,
Deallocates = Self::Deallocates,
Shrinks = Self::Shrinks,
>;
type WithClaimable<const VALUE: bool>: BumpAllocatorSettings<
MinimumAlignment = Self::MinimumAlignment,
Up = Self::Up,
GuaranteedAllocated = Self::GuaranteedAllocated,
Claimable = Bool<VALUE>,
Deallocates = Self::Deallocates,
Shrinks = Self::Shrinks,
>;
type WithDeallocates<const VALUE: bool>: BumpAllocatorSettings<
MinimumAlignment = Self::MinimumAlignment,
Up = Self::Up,
GuaranteedAllocated = Self::GuaranteedAllocated,
Claimable = Self::Claimable,
Deallocates = Bool<VALUE>,
Shrinks = Self::Shrinks,
>;
type WithShrinks<const VALUE: bool>: BumpAllocatorSettings<
MinimumAlignment = Self::MinimumAlignment,
Up = Self::Up,
GuaranteedAllocated = Self::GuaranteedAllocated,
Claimable = Self::Claimable,
Deallocates = Self::Deallocates,
Shrinks = Bool<VALUE>,
>;
type WithMinimumChunkSize<const VALUE: usize>: BumpAllocatorSettings<
MinimumAlignment = Self::MinimumAlignment,
Up = Self::Up,
GuaranteedAllocated = Self::GuaranteedAllocated,
Claimable = Self::Claimable,
Deallocates = Self::Deallocates,
Shrinks = Self::Shrinks,
>;
}
pub struct BumpSettings<
const MIN_ALIGN: usize = 1,
const UP: bool = true,
const GUARANTEED_ALLOCATED: bool = true,
const CLAIMABLE: bool = true,
const DEALLOCATES: bool = true,
const SHRINKS: bool = true,
const MINIMUM_CHUNK_SIZE: usize = 512,
>;
impl<
const MIN_ALIGN: usize,
const UP: bool,
const GUARANTEED_ALLOCATED: bool,
const CLAIMABLE: bool,
const DEALLOCATES: bool,
const SHRINKS: bool,
const MINIMUM_CHUNK_SIZE: usize,
> Sealed for BumpSettings<MIN_ALIGN, UP, GUARANTEED_ALLOCATED, CLAIMABLE, DEALLOCATES, SHRINKS, MINIMUM_CHUNK_SIZE>
{
}
impl<
const MIN_ALIGN: usize,
const UP: bool,
const GUARANTEED_ALLOCATED: bool,
const CLAIMABLE: bool,
const DEALLOCATES: bool,
const SHRINKS: bool,
const MINIMUM_CHUNK_SIZE: usize,
> BumpAllocatorSettings
for BumpSettings<MIN_ALIGN, UP, GUARANTEED_ALLOCATED, CLAIMABLE, DEALLOCATES, SHRINKS, MINIMUM_CHUNK_SIZE>
where
MinimumAlignment<MIN_ALIGN>: SupportedMinimumAlignment,
{
const MINIMUM_CHUNK_SIZE: usize = MINIMUM_CHUNK_SIZE;
type MinimumAlignment = MinimumAlignment<MIN_ALIGN>;
type Up = Bool<UP>;
type GuaranteedAllocated = Bool<GUARANTEED_ALLOCATED>;
type Claimable = Bool<CLAIMABLE>;
type Deallocates = Bool<DEALLOCATES>;
type Shrinks = Bool<SHRINKS>;
type WithMinimumAlignment<const VALUE: usize>
= BumpSettings<VALUE, UP, GUARANTEED_ALLOCATED, CLAIMABLE, DEALLOCATES, SHRINKS, MINIMUM_CHUNK_SIZE>
where
MinimumAlignment<VALUE>: SupportedMinimumAlignment;
type WithUp<const VALUE: bool> =
BumpSettings<MIN_ALIGN, VALUE, GUARANTEED_ALLOCATED, CLAIMABLE, DEALLOCATES, SHRINKS, MINIMUM_CHUNK_SIZE>;
type WithGuaranteedAllocated<const VALUE: bool> =
BumpSettings<MIN_ALIGN, UP, VALUE, CLAIMABLE, DEALLOCATES, SHRINKS, MINIMUM_CHUNK_SIZE>;
type WithClaimable<const VALUE: bool> =
BumpSettings<MIN_ALIGN, UP, GUARANTEED_ALLOCATED, VALUE, DEALLOCATES, SHRINKS, MINIMUM_CHUNK_SIZE>;
type WithDeallocates<const VALUE: bool> =
BumpSettings<MIN_ALIGN, UP, GUARANTEED_ALLOCATED, CLAIMABLE, VALUE, SHRINKS, MINIMUM_CHUNK_SIZE>;
type WithShrinks<const VALUE: bool> =
BumpSettings<MIN_ALIGN, UP, GUARANTEED_ALLOCATED, CLAIMABLE, DEALLOCATES, VALUE, MINIMUM_CHUNK_SIZE>;
type WithMinimumChunkSize<const VALUE: usize> =
BumpSettings<MIN_ALIGN, UP, GUARANTEED_ALLOCATED, CLAIMABLE, DEALLOCATES, SHRINKS, VALUE>;
}
#[expect(private_bounds)]
pub trait Boolean: Sealed {
const VALUE: bool;
}
pub type True = Bool<true>;
pub type False = Bool<false>;
pub struct Bool<const VALUE: bool>;
impl<const VALUE: bool> Sealed for Bool<VALUE> {}
impl<const VALUE: bool> Boolean for Bool<VALUE> {
const VALUE: bool = VALUE;
}
pub struct MinimumAlignment<const ALIGNMENT: usize>;
mod supported_minimum_alignment {
use crate::ArrayLayout;
pub trait Sealed {
#[doc(hidden)]
#[expect(private_interfaces)]
const LAYOUT: ArrayLayout;
}
}
pub trait SupportedMinimumAlignment: supported_minimum_alignment::Sealed {
const VALUE: usize;
}
macro_rules! supported_alignments {
($($i:literal)*) => {
$(
impl supported_minimum_alignment::Sealed for MinimumAlignment<$i> {
#[expect(private_interfaces)]
const LAYOUT: ArrayLayout = match ArrayLayout::from_size_align(0, $i) {
Ok(layout) => layout,
Err(_) => unreachable!(),
};
}
impl SupportedMinimumAlignment for MinimumAlignment<$i> {
const VALUE: usize = $i;
}
)*
};
}
supported_alignments!(1 2 4 8 16);