use alloc::sync::Arc;
use core::convert::Infallible;
use core::marker::PhantomData;
use core::mem::MaybeUninit;
pub struct Usize<const N: usize>(());
pub struct Bool<const B: bool>(());
mod detail {
pub trait ChunkSizePriv<T> {
type Array;
}
pub trait SupportsPositionsPriv {
type Rc: Clone + Send + Sync;
fn init_rc(_rc: &mut Option<Self::Rc>) {}
}
pub trait MutablePriv {}
}
pub(crate) use detail::*;
pub trait ChunkSize<T>: ChunkSizePriv<T> {}
impl<T, const N: usize> ChunkSize<T> for Usize<N> {}
impl<T, const N: usize> ChunkSizePriv<T> for Usize<N> {
type Array = [MaybeUninit<T>; N];
}
pub trait SupportsPositions: SupportsPositionsPriv {}
impl SupportsPositions for Bool<false> {}
impl SupportsPositions for Bool<true> {}
impl SupportsPositionsPriv for Bool<false> {
type Rc = Infallible;
}
impl SupportsPositionsPriv for Bool<true> {
type Rc = Arc<()>;
fn init_rc(rc: &mut Option<Self::Rc>) {
rc.get_or_insert_with(Arc::default);
}
}
pub trait Mutable: MutablePriv {}
impl Mutable for Bool<false> {}
impl Mutable for Bool<true> {}
impl<const B: bool> MutablePriv for Bool<B> {}
mod sealed {
pub trait Sealed {}
}
pub trait ArenaOptions<T>: sealed::Sealed {
type ChunkSize: ChunkSize<T>;
type SupportsPositions: SupportsPositions;
type Mutable: Mutable;
}
#[rustfmt::skip]
pub type Options<
const CHUNK_SIZE: usize = 16,
const SUPPORTS_POSITIONS: bool = false,
const MUTABLE: bool = true,
> = TypedOptions<
Usize<CHUNK_SIZE>,
Bool<SUPPORTS_POSITIONS>,
Bool<MUTABLE>,
>;
#[allow(clippy::type_complexity)]
#[rustfmt::skip]
pub struct TypedOptions<
ChunkSize = Usize<16>,
SupportsPositions = Bool<false>,
Mutable = Bool<true>,
>(PhantomData<fn() -> (
ChunkSize,
SupportsPositions,
Mutable,
)>);
#[rustfmt::skip]
impl<
ChunkSize,
SupportsPositions,
Mutable,
> sealed::Sealed for TypedOptions<
ChunkSize,
SupportsPositions,
Mutable,
> {}
#[rustfmt::skip]
impl<
T,
ChunkSize: self::ChunkSize<T>,
SupportsPositions: self::SupportsPositions,
Mutable: self::Mutable,
> ArenaOptions<T> for TypedOptions<
ChunkSize,
SupportsPositions,
Mutable,
> {
type ChunkSize = ChunkSize;
type SupportsPositions = SupportsPositions;
type Mutable = Mutable;
}