use crate::{ClearModp, SecretI64, SecretModp};
use crate::{__deletec, __deleteint, __deletes, __deletesint, __newc, __newint, __news, __newsint};
pub struct Allocator<T> {
phantom: core::marker::PhantomData<T>,
}
impl<T> Allocator<T> {
const DEFAULT: Self = Self::new();
const fn new() -> Self {
Self {
phantom: core::marker::PhantomData,
}
}
}
pub trait Allocate {
const N: u64;
unsafe fn free(&self, n: u64);
fn allocate(&self, n: u64) -> u64;
}
impl Allocate for &'static Allocator<ClearModp> {
const N: u64 = 1;
#[inline(always)]
unsafe fn free(&self, addr: u64) {
__deletec(addr as i64);
}
#[inline(always)]
fn allocate(&self, n: u64) -> u64 {
unsafe { __newc(n as i64) as u64 }
}
}
impl Allocate for &'static Allocator<SecretModp> {
const N: u64 = 1;
#[inline(always)]
unsafe fn free(&self, addr: u64) {
__deletes(addr as i64);
}
#[inline(always)]
fn allocate(&self, n: u64) -> u64 {
unsafe { __news(n as i64) as u64 }
}
}
impl Allocate for &'static Allocator<i64> {
const N: u64 = 1;
#[inline(always)]
unsafe fn free(&self, addr: u64) {
__deleteint(addr as i64);
}
#[inline(always)]
fn allocate(&self, n: u64) -> u64 {
unsafe { __newint(n as i64) as u64 }
}
}
impl Allocate for &'static Allocator<SecretI64> {
const N: u64 = 1;
#[inline(always)]
unsafe fn free(&self, addr: u64) {
__deletesint(addr as i64);
}
#[inline(always)]
fn allocate(&self, n: u64) -> u64 {
unsafe { __newsint(n as i64) as u64 }
}
}
pub trait GetAllocator: Sized + 'static {
type Allocator: Allocate;
fn get_allocator() -> Self::Allocator;
}
impl GetAllocator for SecretI64 {
type Allocator = &'static Allocator<Self>;
fn get_allocator() -> &'static Allocator<Self> {
&Allocator::DEFAULT
}
}
impl GetAllocator for i64 {
type Allocator = &'static Allocator<Self>;
fn get_allocator() -> &'static Allocator<Self> {
&Allocator::DEFAULT
}
}
impl GetAllocator for ClearModp {
type Allocator = &'static Allocator<Self>;
fn get_allocator() -> &'static Allocator<Self> {
&Allocator::DEFAULT
}
}
impl GetAllocator for SecretModp {
type Allocator = &'static Allocator<Self>;
fn get_allocator() -> &'static Allocator<Self> {
&Allocator::DEFAULT
}
}