#![deny(missing_docs)]
use std::borrow::Cow;
pub trait Alloc<'a, 't, T: 't> {
fn alloc(&'a self, value: T) -> &'t mut T;
}
impl<'z, 'a, 'p: 'a, 't, T: 't> Alloc<'z, 't, T> for &'p Alloc<'a, 't, T> {
fn alloc(&'z self, value: T) -> &'t mut T {
Alloc::alloc(*self, value)
}
}
pub trait AllocSelf<T>: for<'a> Alloc<'a, 'a, T> {}
impl<T, A> AllocSelf<T> for A where A: for<'a> Alloc<'a, 'a, T> {}
pub trait AllocInto<'t, T: 't>: for<'a> Alloc<'a, 't, T> {}
impl<'t, T, A> AllocInto<'t, T> for A
where
T: 't,
A: for<'a> Alloc<'a, 't, T>,
{
}
pub trait AllocOwned<'a, 't, T: ToOwned + ?Sized + 't> {
fn alloc_owned(&'a self, value: <T as ToOwned>::Owned) -> &'t T;
fn maybe_alloc(&'a self, value: Cow<'t, T>) -> &'t T {
match value {
Cow::Borrowed(x) => x,
Cow::Owned(x) => self.alloc_owned(x),
}
}
fn force_alloc(&'a self, value: Cow<T>) -> &'t T {
self.alloc_owned(value.into_owned())
}
}
impl<'a, 't, T: ToOwned<Owned = T> + 't> AllocOwned<'a, 't, T> for Alloc<'a, 't, T> {
fn alloc_owned(&'a self, value: T) -> &'t T {
self.alloc(value)
}
}
pub trait AllocOwnedSelf<T: ToOwned + ?Sized>: for<'a> AllocOwned<'a, 'a, T> {}
impl<T, A> AllocOwnedSelf<T> for A
where
T: ToOwned + ?Sized,
A: for<'a> AllocOwned<'a, 'a, T>,
{
}
pub trait AllocOwnedInto<'t, T: ToOwned + ?Sized + 't>: for<'a> AllocOwned<'a, 't, T> {}
impl<'t, T, A> AllocOwnedInto<'t, T> for A
where
T: ToOwned + ?Sized + 't,
A: for<'a> AllocOwned<'a, 't, T>,
{
}
#[macro_export]
macro_rules! make_arenas {
($(#[$arena_attr:meta])* pub struct $arena_name:ident { $($name:ident: $type:ty,)* }) => {
make_arenas!{ IMPL $($arena_attr),*; $arena_name; []; $($name: $type,)* }
};
($(#[$arena_attr:meta])* pub struct $arena_name:ident<$($lt:tt),+> { $($name:ident: $type:ty,)* }) => {
make_arenas!{ IMPL $($arena_attr),*; $arena_name; [$($lt),+]; $($name: $type,)* }
};
(IMPL $($arena_attr:meta),*; $arena_name:ident; [$($lt:tt),*]; $($name:ident: $type:ty,)*) => {
$(#[$arena_attr])*
#[allow(missing_docs)]
pub struct $arena_name<$($lt),*> {
$(pub $name: ::typed_arena::Arena<$type>,)*
}
make_arenas!(STRUCT_IMPL $arena_name; [$($lt),*]; $($name: $type,)*);
};
(STRUCT_IMPL $arena_name:ident; [$($lt:tt),*]; $($name:ident: $type:ty,)*) => {
impl<$($lt),*> $arena_name<$($lt),*> {
pub fn new() -> $arena_name<$($lt),*> {
$arena_name {
$($name: ::typed_arena::Arena::new(),)*
}
}
}
impl<$($lt),*> Default for $arena_name<$($lt),*> {
fn default() -> $arena_name<$($lt),*> {
$arena_name::new()
}
}
make_arenas!(TRAIT_IMPL $arena_name; [$($lt),*]; $($name: $type,)*);
};
(TRAIT_IMPL $arena_name:ident; [$($lt:tt),*]; $name:ident: $type:ty, $($tail_name:ident: $tail_type:ty,)*) => {
impl<'a, $($lt),*> $crate::arenas::Alloc<'a, 'a, $type> for $arena_name<$($lt),*> where $($lt: 'a),* {
fn alloc(&'a self, value: $type) -> &'a mut $type {
self.$name.alloc(value)
}
}
make_arenas!(TRAIT_IMPL $arena_name; [$($lt),*]; $($tail_name: $tail_type,)*);
};
(TRAIT_IMPL $arena_name:ident; [$($lt:tt),*];) => {}
}