use crate::alloc::*;
use crate::stm::*;
use crate::PSafe;
pub trait PClone<A: MemPool>: Sized {
fn pclone(&self, journal: &Journal<A>) -> Self;
fn pclone_from(&mut self, source: &Self, journal: &Journal<A>) {
*self = source.pclone(journal)
}
}
impl<T: PSafe + PClone<A>, A: MemPool> PClone<A> for Option<T> {
fn pclone(&self, journal: &Journal<A>) -> Self {
if let Some(x) = self {
Some(x.pclone(journal))
} else {
None
}
}
}
impl<T: PSafe + PClone<A> + ?Sized, A: MemPool> PClone<A> for &[T] {
fn pclone(&self, j: &Journal<A>) -> Self {
let res = unsafe { A::new_slice(self, j) };
for i in 0..res.len() {
res[i] = self[i].pclone(j);
}
res
}
}
impl<T: PSafe + PClone<A>, A: MemPool, const N: usize> PClone<A> for [T;N] {
fn pclone(&self, j: &Journal<A>) -> Self {
use std::mem::MaybeUninit;
let mut res = unsafe { MaybeUninit::<Self>::uninit().assume_init() };
for i in 0..res.len() {
std::mem::forget(std::mem::replace(&mut res[i],self[i].pclone(j)));
}
res
}
}
use impl_trait_for_tuples::*;
#[impl_for_tuples(32)]
impl<A: MemPool> PClone<A> for Tuple {
fn pclone(&self, j: &Journal<A>) -> Self {
for_tuples!( ( #( Tuple.pclone(j) ),* ) )
}
}
mod impls {
use super::PClone;
use crate::alloc::MemPool;
use crate::stm::Journal;
macro_rules! impl_clone {
($($t:ty)*) => {
$(
impl<A: MemPool> PClone<A> for $t {
#[inline]
fn pclone(&self, _j: &Journal<A>) -> Self {
*self
}
}
)*
}
}
impl_clone! {
usize u8 u16 u32 u64 u128
isize i8 i16 i32 i64 i128
f32 f64
bool char
}
}