use crate::common::cell::RefCell;
use crate::common::BVec;
use bumpalo::Bump;
use bytemuck::Pod;
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::fmt::Formatter;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use std::slice::{from_raw_parts, from_raw_parts_mut};
use std::{fmt, mem};
pub struct LCell<'a, T: ?Sized>(&'a RefCell<T>);
impl<'a, T> Clone for LCell<'a, T> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<'a, T> Copy for LCell<'a, T> {}
impl<'a, T> LCell<'a, T> {
pub fn new_in(x: T, a: &'a Bump) -> LCell<'a, T> {
LCell(a.alloc(RefCell::new(x)))
}
}
impl<'a, T> Deref for LCell<'a, T> {
type Target = RefCell<T>;
#[inline]
fn deref(&self) -> &Self::Target {
self.0
}
}
impl<'a, T> PartialEq for LCell<'a, T>
where
T: PartialEq,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.deref() == other.deref()
}
}
impl<'a, T> Eq for LCell<'a, T> where T: Eq {}
pub struct BCell<'a, T: Sized, B: Sized>(
pub(crate) *const (RefCell<T>, B),
pub(crate) PhantomData<&'a T>,
);
impl<'a, T, B> Clone for BCell<'a, T, B> {
#[inline]
fn clone(&self) -> Self {
*self
}
}
impl<'a, T, B> Copy for BCell<'a, T, B> {}
impl<'a, T, B: Copy> BCell<'a, T, B> {
pub fn new_in(t: T, b: B, a: &'a Bump) -> BCell<'a, T, B> {
BCell(a.alloc((RefCell::new(t), b)), PhantomData)
}
#[inline]
pub fn bound(&self) -> B {
unsafe { &*self.0 }.1
}
}
impl<'a, T, B> Deref for BCell<'a, T, B> {
type Target = RefCell<T>;
#[inline]
fn deref(&self) -> &Self::Target {
&unsafe { &*self.0 }.0
}
}
impl<'a, T, B> PartialEq for BCell<'a, T, B>
where
T: PartialEq,
{
#[inline]
fn eq(&self, other: &Self) -> bool {
self.deref() == other.deref()
}
}
impl<'a, T, B> Eq for BCell<'a, T, B> where T: Eq {}
#[derive(Copy, Clone)]
pub enum CodSlice<'tx, T: Pod> {
Owned(&'tx [T]),
Mapped(&'tx [T]),
}
impl<'tx, T: Pod> CodSlice<'tx, T>
where
T: Clone,
{
#[inline]
pub fn is_mapped(&self) -> bool {
match self {
CodSlice::Owned(_) => false,
CodSlice::Mapped(_) => true,
}
}
pub fn own_in(&mut self, bump: &'tx Bump) {
if self.is_mapped() {
let o = bump.alloc_slice_copy(Deref::deref(self));
*self = CodSlice::Owned(o);
}
}
#[inline]
pub fn get_ref(&self) -> &'tx [T] {
match self {
CodSlice::Owned(s) => s,
CodSlice::Mapped(m) => m,
}
}
}
impl<'tx, T: Pod> Deref for CodSlice<'tx, T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
match self {
CodSlice::Owned(s) => s,
CodSlice::Mapped(m) => m,
}
}
}
impl<'tx, T: Pod> Borrow<[T]> for CodSlice<'tx, T> {
#[inline]
fn borrow(&self) -> &[T] {
self.deref()
}
}
impl<'tx, T: Pod> PartialEq for CodSlice<'tx, T>
where
T: PartialEq,
{
fn eq(&self, other: &Self) -> bool {
self.deref() == other.deref()
}
}
impl<'tx, T: Pod> Eq for CodSlice<'tx, T> where T: Eq {}
impl<'tx, T: Pod> PartialOrd for CodSlice<'tx, T>
where
T: PartialOrd,
{
#[inline]
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
self.deref().partial_cmp(other.deref())
}
}
impl<'tx, T: Pod> Ord for CodSlice<'tx, T>
where
T: Ord,
{
#[inline]
fn cmp(&self, other: &Self) -> Ordering {
self.deref().cmp(other.deref())
}
}
impl<'a, T: Pod> fmt::Debug for CodSlice<'a, T>
where
T: fmt::Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.deref().fmt(f)
}
}
pub(crate) trait IsAligned: Copy {
fn is_aligned_to<U>(self) -> bool;
}
impl IsAligned for *const u8 {
#[inline(always)]
fn is_aligned_to<U>(self) -> bool {
(self as usize & (mem::align_of::<U>() - 1)) == 0
}
}
impl IsAligned for *mut u8 {
#[inline(always)]
fn is_aligned_to<U>(self) -> bool {
(self as usize & (mem::align_of::<U>() - 1)) == 0
}
}
pub type PhantomUnsend = PhantomData<*mut ()>;
#[derive(Clone)]
pub(crate) struct SplitArray<'a, T> {
ptr: NonNull<T>,
len: usize,
marker: PhantomData<&'a mut [T]>,
}
impl<'a, T> SplitArray<'a, T> {
pub(crate) fn new(mut vec: BVec<'a, T>) -> SplitArray<'a, T> {
let s = SplitArray {
ptr: NonNull::new(vec.as_mut_ptr()).unwrap(),
len: vec.len(),
marker: PhantomData,
};
mem::forget(vec);
s
}
pub(crate) fn split_left_off(&mut self, at: usize) -> SplitArray<'a, T> {
assert!(
self.len >= at,
"splitting off at {} larget than len {}",
at,
self.len
);
let left = SplitArray {
ptr: self.ptr,
len: at,
marker: PhantomData,
};
unsafe {
self.ptr = NonNull::new_unchecked(self.ptr.as_ptr().add(at));
}
self.len -= at;
left
}
}
unsafe impl<'a, T: Send> Send for SplitArray<'a, T> {}
unsafe impl<'a, T: Sync> Sync for SplitArray<'a, T> {}
impl<'a, T> From<BVec<'a, T>> for SplitArray<'a, T> {
fn from(value: BVec<'a, T>) -> Self {
SplitArray::new(value)
}
}
impl<'a, T> Deref for SplitArray<'a, T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
unsafe { from_raw_parts(self.ptr.as_ptr(), self.len) }
}
}
impl<'a, T> DerefMut for SplitArray<'a, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { from_raw_parts_mut(self.ptr.as_ptr(), self.len) }
}
}
impl<'a, T> AsRef<[T]> for SplitArray<'a, T> {
#[inline]
fn as_ref(&self) -> &[T] {
self.deref()
}
}
impl<'a, T> AsMut<[T]> for SplitArray<'a, T> {
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self.deref_mut()
}
}
pub(crate) enum VecOrSplit<'a, T> {
Vec(BVec<'a, T>),
Split(SplitArray<'a, T>),
}
impl<'a, T> VecOrSplit<'a, T> {
pub(crate) fn get_vec(&self) -> &BVec<'a, T> {
match self {
VecOrSplit::Vec(v) => v,
VecOrSplit::Split(_) => panic!("split access"),
}
}
pub(crate) fn get_mut_vec(&mut self) -> &mut BVec<'a, T> {
match self {
VecOrSplit::Vec(v) => v,
VecOrSplit::Split(_) => panic!("split access"),
}
}
}
impl<'a, T> Deref for VecOrSplit<'a, T> {
type Target = [T];
#[inline]
fn deref(&self) -> &Self::Target {
match self {
VecOrSplit::Vec(v) => v,
VecOrSplit::Split(s) => s,
}
}
}
impl<'a, T> DerefMut for VecOrSplit<'a, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
match self {
VecOrSplit::Vec(v) => v,
VecOrSplit::Split(s) => s,
}
}
}
impl<'a, T> AsRef<[T]> for VecOrSplit<'a, T> {
#[inline]
fn as_ref(&self) -> &[T] {
self.deref()
}
}
impl<'a, T> AsMut<[T]> for VecOrSplit<'a, T> {
#[inline]
fn as_mut(&mut self) -> &mut [T] {
self.deref_mut()
}
}
impl<'a, T> From<BVec<'a, T>> for VecOrSplit<'a, T> {
fn from(value: BVec<'a, T>) -> Self {
VecOrSplit::Vec(value)
}
}
impl<'a, T> From<SplitArray<'a, T>> for VecOrSplit<'a, T> {
fn from(value: SplitArray<'a, T>) -> Self {
VecOrSplit::Split(value)
}
}