use crate::{
backend::{Backend, WordRef},
utils::RcPtrMut,
word::{Word, WordLike},
};
#[derive(Debug)]
#[repr(transparent)]
pub struct Allocator<B: Backend> {
backend: RcPtrMut<B>,
}
impl<B: Backend> Allocator<B> {
#[inline]
pub fn alloc<W: Word, const N: usize, C: WordLike<W, N>>(&self, word: C) -> WordRef<B, W, N> {
return WordRef::alloc_constant(&self.backend, word.to_word());
}
}
impl<B: Backend> Clone for Allocator<B> {
fn clone(&self) -> Self {
return Self {
backend: self.backend.clone(),
};
}
}
#[derive(Debug)]
#[repr(transparent)]
pub struct Frontend<B: Backend> {
backend: RcPtrMut<B>,
}
impl<B: Backend> Frontend<B> {
#[inline]
pub fn wrap(backend: B) -> Self {
return Self {
backend: RcPtrMut::new(backend),
};
}
pub fn allocator(&self) -> Allocator<B> {
return Allocator {
backend: self.backend.clone(),
};
}
#[inline]
pub fn finalize_with_arg(self, arg: B::FinalizeArg) -> B::FinalizeResult {
return self.backend.into_inner().finalize(arg);
}
#[inline]
pub fn input<W: Word, const N: usize, C: WordLike<W, N>>(&self, word: C) -> WordRef<B, W, N> {
return WordRef::input(&self.backend, word);
}
#[inline]
pub fn alloc<W: Word, const N: usize, C: WordLike<W, N>>(&self, word: C) -> WordRef<B, W, N> {
return WordRef::alloc_constant(&self.backend, word.to_word());
}
#[inline]
pub fn output<W: Word, const N: usize>(&self, word_ref: WordRef<B, W, N>) {
self.backend.borrow_mut().output(word_ref.idx());
}
}
impl<B: Backend<FinalizeArg: Default>> Frontend<B> {
#[inline]
pub fn finalize(self) -> B::FinalizeResult {
return self.finalize_with_arg(B::FinalizeArg::default());
}
}