use std::cell::Cell;
use std::fmt::Debug;
use std::hash::Hash;
use std::hash::Hasher;
use std::marker::PhantomData;
use std::mem::MaybeUninit;
use std::num::NonZeroU32;
use std::ops::Index;
use std::ops::IndexMut;
use bitvec::vec::BitVec;
use controlled_option::Niche;
use crate::utils::cmp_option;
use crate::utils::equals_option;
#[repr(transparent)]
pub struct Handle<T> {
index: NonZeroU32,
_phantom: PhantomData<T>,
}
impl<T> Handle<T> {
pub(crate) fn new(index: NonZeroU32) -> Handle<T> {
Handle {
index,
_phantom: PhantomData,
}
}
#[inline(always)]
pub fn as_u32(self) -> u32 {
self.index.get()
}
#[inline(always)]
pub fn as_usize(self) -> usize {
self.index.get() as usize
}
}
impl<T> Niche for Handle<T> {
type Output = u32;
#[inline]
fn none() -> Self::Output {
0
}
#[inline]
fn is_none(value: &Self::Output) -> bool {
*value == 0
}
#[inline]
fn into_some(value: Self) -> Self::Output {
value.index.get()
}
#[inline]
fn from_some(value: Self::Output) -> Self {
Self::new(unsafe { NonZeroU32::new_unchecked(value) })
}
}
impl<T> Clone for Handle<T> {
fn clone(&self) -> Handle<T> {
Handle::new(self.index)
}
}
impl<T> Copy for Handle<T> {}
impl<T> Debug for Handle<T> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_struct("Handle")
.field("index", &self.index)
.finish()
}
}
impl<T> Eq for Handle<T> {}
impl<T> Hash for Handle<T> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.index.hash(state);
}
}
impl<T> Ord for Handle<T> {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.index.cmp(&other.index)
}
}
impl<T> PartialEq for Handle<T> {
fn eq(&self, other: &Self) -> bool {
self.index == other.index
}
}
impl<T> PartialOrd for Handle<T> {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
self.index.partial_cmp(&other.index)
}
}
unsafe impl<T> Send for Handle<T> {}
unsafe impl<T> Sync for Handle<T> {}
pub struct Arena<T> {
items: Vec<MaybeUninit<T>>,
}
impl<T> Drop for Arena<T> {
fn drop(&mut self) {
unsafe {
let items = std::mem::transmute::<_, &mut [T]>(&mut self.items[1..]) as *mut [T];
items.drop_in_place();
}
}
}
impl<T> Arena<T> {
pub fn new() -> Arena<T> {
Arena {
items: vec![MaybeUninit::uninit()],
}
}
#[inline(always)]
pub fn clear(&mut self) {
self.items.truncate(1);
}
pub fn add(&mut self, item: T) -> Handle<T> {
let index = self.items.len() as u32;
self.items.push(MaybeUninit::new(item));
Handle::new(unsafe { NonZeroU32::new_unchecked(index) })
}
pub fn get(&self, handle: Handle<T>) -> &T {
unsafe { std::mem::transmute(&self.items[handle.as_usize()]) }
}
pub fn get_mut(&mut self, handle: Handle<T>) -> &mut T {
unsafe { std::mem::transmute(&mut self.items[handle.as_usize()]) }
}
pub fn iter_handles(&self) -> impl Iterator<Item = Handle<T>> {
(1..self.items.len())
.into_iter()
.map(|index| Handle::new(unsafe { NonZeroU32::new_unchecked(index as u32) }))
}
pub(crate) fn as_ptr(&self) -> *const T {
self.items.as_ptr() as *const T
}
#[inline(always)]
pub fn len(&self) -> usize {
self.items.len()
}
}
pub struct SupplementalArena<H, T> {
items: Vec<MaybeUninit<T>>,
_phantom: PhantomData<H>,
}
impl<H, T> Drop for SupplementalArena<H, T> {
fn drop(&mut self) {
unsafe {
let items = std::mem::transmute::<_, &mut [T]>(&mut self.items[1..]) as *mut [T];
items.drop_in_place();
}
}
}
impl<H, T> SupplementalArena<H, T> {
pub fn new() -> SupplementalArena<H, T> {
SupplementalArena {
items: vec![MaybeUninit::uninit()],
_phantom: PhantomData,
}
}
#[inline(always)]
pub fn clear(&mut self) {
self.items.truncate(1);
}
pub fn with_capacity(arena: &Arena<H>) -> SupplementalArena<H, T> {
let mut items = Vec::with_capacity(arena.items.len());
items[0] = MaybeUninit::uninit();
SupplementalArena {
items,
_phantom: PhantomData,
}
}
pub fn get(&self, handle: Handle<H>) -> Option<&T> {
self.items
.get(handle.as_usize())
.map(|x| unsafe { &*(x.as_ptr()) })
}
pub fn get_mut(&mut self, handle: Handle<H>) -> Option<&mut T> {
self.items
.get_mut(handle.as_usize())
.map(|x| unsafe { &mut *(x.as_mut_ptr()) })
}
pub(crate) fn as_ptr(&self) -> *const T {
self.items.as_ptr() as *const T
}
#[inline(always)]
pub fn len(&self) -> usize {
self.items.len()
}
pub(crate) fn iter(&self) -> impl Iterator<Item = (Handle<T>, &T)> {
self.items
.iter()
.enumerate()
.skip(1)
.map(|(i, x)| (Handle::from_some(i as u32), unsafe { &*(x.as_ptr()) }))
}
}
impl<H, T> SupplementalArena<H, T>
where
T: Default,
{
pub fn get_mut_or_default(&mut self, handle: Handle<H>) -> &mut T {
let index = handle.as_usize();
if self.items.len() <= index {
self.items
.resize_with(index + 1, || MaybeUninit::new(T::default()));
}
unsafe { std::mem::transmute(&mut self.items[handle.as_usize()]) }
}
}
impl<H, T> Default for SupplementalArena<H, T> {
fn default() -> SupplementalArena<H, T> {
SupplementalArena::new()
}
}
impl<H, T> Index<Handle<H>> for SupplementalArena<H, T> {
type Output = T;
fn index(&self, handle: Handle<H>) -> &T {
unsafe { std::mem::transmute(&self.items[handle.as_usize()]) }
}
}
impl<H, T> IndexMut<Handle<H>> for SupplementalArena<H, T>
where
T: Default,
{
fn index_mut(&mut self, handle: Handle<H>) -> &mut T {
self.get_mut_or_default(handle)
}
}
#[repr(C)]
pub struct HandleSet<T> {
elements: BitVec<u32, bitvec::order::Lsb0>,
_phantom: PhantomData<T>,
}
impl<T> HandleSet<T> {
pub fn new() -> HandleSet<T> {
HandleSet::default()
}
pub fn clear(&mut self) {
self.elements.clear();
}
pub fn contains(&self, handle: Handle<T>) -> bool {
let index = handle.as_usize();
self.elements.get(index).map(|bit| *bit).unwrap_or(false)
}
pub fn add(&mut self, handle: Handle<T>) {
let index = handle.as_usize();
if self.elements.len() <= index {
self.elements.resize(index + 1, false);
}
let mut bit = unsafe { self.elements.get_unchecked_mut(index) };
*bit = true;
}
pub fn remove(&mut self, handle: Handle<T>) {
let index = handle.as_usize();
if let Some(mut bit) = self.elements.get_mut(index) {
*bit = false;
}
}
pub fn iter(&self) -> impl Iterator<Item = Handle<T>> + '_ {
self.elements
.iter_ones()
.map(|index| Handle::new(unsafe { NonZeroU32::new_unchecked(index as u32) }))
}
pub(crate) fn as_ptr(&self) -> *const u32 {
self.elements.as_bitptr().pointer()
}
#[inline(always)]
pub(crate) fn len(&self) -> usize {
self.elements.as_raw_slice().len()
}
}
impl<T> Default for HandleSet<T> {
fn default() -> HandleSet<T> {
HandleSet {
elements: BitVec::default(),
_phantom: PhantomData,
}
}
}
#[repr(C)]
#[derive(Niche)]
pub struct List<T> {
#[niche]
cells: Handle<ListCell<T>>,
}
#[doc(hidden)]
#[repr(C)]
pub struct ListCell<T> {
head: T,
tail: Handle<ListCell<T>>,
}
const EMPTY_LIST_HANDLE: NonZeroU32 = unsafe { NonZeroU32::new_unchecked(u32::MAX) };
pub type ListArena<T> = Arena<ListCell<T>>;
impl<T> List<T> {
pub fn new_arena() -> ListArena<T> {
ListArena::new()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.cells.index == EMPTY_LIST_HANDLE
}
pub fn empty() -> List<T> {
List {
cells: Handle::new(EMPTY_LIST_HANDLE),
}
}
pub fn from_handle(handle: Handle<ListCell<T>>) -> List<T> {
List { cells: handle }
}
pub fn handle(&self) -> Handle<ListCell<T>> {
self.cells
}
pub fn push_front(&mut self, arena: &mut ListArena<T>, head: T) {
self.cells = arena.add(ListCell {
head,
tail: self.cells,
});
}
pub fn pop_front<'a>(&mut self, arena: &'a ListArena<T>) -> Option<&'a T> {
if self.is_empty() {
return None;
}
let cell = arena.get(self.cells);
self.cells = cell.tail;
Some(&cell.head)
}
pub fn iter<'a>(mut self, arena: &'a ListArena<T>) -> impl Iterator<Item = &'a T> + 'a {
std::iter::from_fn(move || self.pop_front(arena))
}
}
impl<T> List<T> {
pub fn equals_with<F>(mut self, arena: &ListArena<T>, mut other: List<T>, mut eq: F) -> bool
where
F: FnMut(&T, &T) -> bool,
{
loop {
if self.cells == other.cells {
return true;
}
if !equals_option(self.pop_front(arena), other.pop_front(arena), &mut eq) {
return false;
}
}
}
pub fn cmp_with<F>(
mut self,
arena: &ListArena<T>,
mut other: List<T>,
mut cmp: F,
) -> std::cmp::Ordering
where
F: FnMut(&T, &T) -> std::cmp::Ordering,
{
use std::cmp::Ordering;
loop {
if self.cells == other.cells {
return Ordering::Equal;
}
match cmp_option(self.pop_front(arena), other.pop_front(arena), &mut cmp) {
Ordering::Equal => (),
result @ _ => return result,
}
}
}
}
impl<T> List<T>
where
T: Eq,
{
pub fn equals(self, arena: &ListArena<T>, other: List<T>) -> bool {
self.equals_with(arena, other, |a, b| *a == *b)
}
}
impl<T> List<T>
where
T: Ord,
{
pub fn cmp(self, arena: &ListArena<T>, other: List<T>) -> std::cmp::Ordering {
self.cmp_with(arena, other, |a, b| a.cmp(b))
}
}
impl<T> Clone for List<T> {
fn clone(&self) -> List<T> {
List { cells: self.cells }
}
}
impl<T> Copy for List<T> {}
#[repr(C)]
#[derive(Niche)]
pub struct ReversibleList<T> {
#[niche]
cells: Handle<ReversibleListCell<T>>,
}
#[repr(C)]
#[doc(hidden)]
pub struct ReversibleListCell<T> {
head: T,
tail: Handle<ReversibleListCell<T>>,
reversed: Cell<Option<Handle<ReversibleListCell<T>>>>,
}
pub type ReversibleListArena<T> = Arena<ReversibleListCell<T>>;
impl<T> ReversibleList<T> {
pub fn new_arena() -> ReversibleListArena<T> {
ReversibleListArena::new()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
ReversibleListCell::is_empty_handle(self.cells)
}
pub fn empty() -> ReversibleList<T> {
ReversibleList {
cells: ReversibleListCell::empty_handle(),
}
}
pub fn have_reversal(&self, arena: &ReversibleListArena<T>) -> bool {
if self.is_empty() {
return true;
}
arena.get(self.cells).reversed.get().is_some()
}
pub fn push_front(&mut self, arena: &mut ReversibleListArena<T>, head: T) {
self.cells = arena.add(ReversibleListCell::new(head, self.cells, None));
}
pub fn pop_front<'a>(&mut self, arena: &'a ReversibleListArena<T>) -> Option<&'a T> {
if self.is_empty() {
return None;
}
let cell = arena.get(self.cells);
self.cells = cell.tail;
Some(&cell.head)
}
pub fn iter<'a>(
mut self,
arena: &'a ReversibleListArena<T>,
) -> impl Iterator<Item = &'a T> + 'a {
std::iter::from_fn(move || self.pop_front(arena))
}
}
impl<T> ReversibleList<T>
where
T: Clone,
{
pub fn reverse(&mut self, arena: &mut ReversibleListArena<T>) {
if self.is_empty() {
return;
}
self.ensure_reversal_available(arena);
self.cells = arena.get(self.cells).reversed.get().unwrap();
}
pub fn ensure_reversal_available(&mut self, arena: &mut ReversibleListArena<T>) {
if self.is_empty() {
return;
}
if arena.get(self.cells).reversed.get().is_some() {
return;
}
let new_reversed = ReversibleListCell::reverse(self.cells, arena);
arena.get(self.cells).reversed.set(Some(new_reversed));
}
}
impl<T> ReversibleList<T> {
pub fn reverse_reused(&mut self, arena: &ReversibleListArena<T>) -> Result<(), ()> {
if self.is_empty() {
return Ok(());
}
self.cells = arena.get(self.cells).reversed.get().ok_or(())?;
Ok(())
}
}
impl<T> ReversibleListCell<T> {
fn new(
head: T,
tail: Handle<ReversibleListCell<T>>,
reversed: Option<Handle<ReversibleListCell<T>>>,
) -> ReversibleListCell<T> {
ReversibleListCell {
head,
tail,
reversed: Cell::new(reversed),
}
}
fn empty_handle() -> Handle<ReversibleListCell<T>> {
Handle::new(EMPTY_LIST_HANDLE)
}
fn is_empty_handle(handle: Handle<ReversibleListCell<T>>) -> bool {
handle.index == EMPTY_LIST_HANDLE
}
}
impl<T> ReversibleListCell<T>
where
T: Clone,
{
fn reverse(
forwards: Handle<ReversibleListCell<T>>,
arena: &mut ReversibleListArena<T>,
) -> Handle<ReversibleListCell<T>> {
let mut reversed = ReversibleListCell::empty_handle();
let mut current = forwards;
while !ReversibleListCell::is_empty_handle(current) {
let cell = arena.get(current);
let head = cell.head.clone();
current = cell.tail;
reversed = arena.add(Self::new(
head,
reversed,
if ReversibleListCell::is_empty_handle(current) {
Some(forwards)
} else {
None
},
));
}
reversed
}
}
impl<T> ReversibleList<T> {
pub fn equals_with<F>(
mut self,
arena: &ReversibleListArena<T>,
mut other: ReversibleList<T>,
mut eq: F,
) -> bool
where
F: FnMut(&T, &T) -> bool,
{
loop {
if self.cells == other.cells {
return true;
}
if !equals_option(self.pop_front(arena), other.pop_front(arena), &mut eq) {
return false;
}
}
}
pub fn cmp_with<F>(
mut self,
arena: &ReversibleListArena<T>,
mut other: ReversibleList<T>,
mut cmp: F,
) -> std::cmp::Ordering
where
F: FnMut(&T, &T) -> std::cmp::Ordering,
{
use std::cmp::Ordering;
loop {
if self.cells == other.cells {
return Ordering::Equal;
}
match cmp_option(self.pop_front(arena), other.pop_front(arena), &mut cmp) {
Ordering::Equal => (),
result @ _ => return result,
}
}
}
}
impl<T> ReversibleList<T>
where
T: Eq,
{
pub fn equals(self, arena: &ReversibleListArena<T>, other: ReversibleList<T>) -> bool {
self.equals_with(arena, other, |a, b| *a == *b)
}
}
impl<T> ReversibleList<T>
where
T: Ord,
{
pub fn cmp(
self,
arena: &ReversibleListArena<T>,
other: ReversibleList<T>,
) -> std::cmp::Ordering {
self.cmp_with(arena, other, |a, b| a.cmp(b))
}
}
impl<T> Clone for ReversibleList<T> {
fn clone(&self) -> ReversibleList<T> {
ReversibleList { cells: self.cells }
}
}
impl<T> Copy for ReversibleList<T> {}
#[repr(C)]
#[derive(Niche)]
pub struct Deque<T> {
#[niche]
list: ReversibleList<T>,
direction: DequeDirection,
}
#[repr(C)]
#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum DequeDirection {
Forwards,
Backwards,
}
impl std::ops::Not for DequeDirection {
type Output = DequeDirection;
fn not(self) -> DequeDirection {
match self {
DequeDirection::Forwards => DequeDirection::Backwards,
DequeDirection::Backwards => DequeDirection::Forwards,
}
}
}
pub type DequeArena<T> = ReversibleListArena<T>;
impl<T> Deque<T> {
pub fn new_arena() -> DequeArena<T> {
ReversibleList::new_arena()
}
#[inline(always)]
pub fn is_empty(&self) -> bool {
self.list.is_empty()
}
pub fn empty() -> Deque<T> {
Deque {
list: ReversibleList::empty(),
direction: DequeDirection::Forwards,
}
}
pub fn have_reversal(&self, arena: &DequeArena<T>) -> bool {
self.list.have_reversal(arena)
}
fn is_backwards(&self) -> bool {
matches!(self.direction, DequeDirection::Backwards)
}
fn is_forwards(&self) -> bool {
matches!(self.direction, DequeDirection::Forwards)
}
pub fn iter_unordered<'a>(&self, arena: &'a DequeArena<T>) -> impl Iterator<Item = &'a T> + 'a {
self.list.iter(arena)
}
}
impl<T> Deque<T>
where
T: Clone,
{
pub fn ensure_backwards(&mut self, arena: &mut DequeArena<T>) {
if self.is_backwards() {
return;
}
self.list.reverse(arena);
self.direction = DequeDirection::Backwards;
}
pub fn ensure_forwards(&mut self, arena: &mut DequeArena<T>) {
if self.is_forwards() {
return;
}
self.list.reverse(arena);
self.direction = DequeDirection::Forwards;
}
pub fn push_front(&mut self, arena: &mut DequeArena<T>, element: T) {
self.ensure_forwards(arena);
self.list.push_front(arena, element);
}
pub fn push_back(&mut self, arena: &mut DequeArena<T>, element: T) {
self.ensure_backwards(arena);
self.list.push_front(arena, element);
}
pub fn pop_front<'a>(&mut self, arena: &'a mut DequeArena<T>) -> Option<&'a T> {
self.ensure_forwards(arena);
self.list.pop_front(arena)
}
pub fn pop_back<'a>(&mut self, arena: &'a mut DequeArena<T>) -> Option<&'a T> {
self.ensure_backwards(arena);
self.list.pop_front(arena)
}
pub fn iter<'a>(&self, arena: &'a mut DequeArena<T>) -> impl Iterator<Item = &'a T> + 'a {
let mut list = self.list;
if self.is_backwards() {
list.reverse(arena);
}
list.iter(arena)
}
pub fn iter_reversed<'a>(
&self,
arena: &'a mut DequeArena<T>,
) -> impl Iterator<Item = &'a T> + 'a {
let mut list = self.list;
if self.is_forwards() {
list.reverse(arena);
}
list.iter(arena)
}
fn ensure_same_direction(&mut self, arena: &mut DequeArena<T>, other: &mut Deque<T>) {
if self.direction == other.direction {
return;
}
if self.list.have_reversal(arena) {
self.list.reverse(arena);
self.direction = !self.direction;
} else {
other.list.reverse(arena);
other.direction = !other.direction;
}
}
}
impl<T> Deque<T>
where
T: Clone,
{
pub fn equals_with<F>(mut self, arena: &mut DequeArena<T>, mut other: Deque<T>, eq: F) -> bool
where
F: FnMut(&T, &T) -> bool,
{
self.ensure_same_direction(arena, &mut other);
self.list.equals_with(arena, other.list, eq)
}
pub fn cmp_with<F>(
mut self,
arena: &mut DequeArena<T>,
mut other: Deque<T>,
cmp: F,
) -> std::cmp::Ordering
where
F: FnMut(&T, &T) -> std::cmp::Ordering,
{
self.ensure_forwards(arena);
other.ensure_forwards(arena);
self.list.cmp_with(arena, other.list, cmp)
}
}
impl<T> Deque<T>
where
T: Clone + Eq,
{
pub fn equals(self, arena: &mut DequeArena<T>, other: Deque<T>) -> bool {
self.equals_with(arena, other, |a, b| *a == *b)
}
}
impl<T> Deque<T>
where
T: Clone + Ord,
{
pub fn cmp(self, arena: &mut DequeArena<T>, other: Deque<T>) -> std::cmp::Ordering {
self.cmp_with(arena, other, |a, b| a.cmp(b))
}
}
impl<T> Deque<T> {
pub fn iter_reused<'a>(&self, arena: &'a DequeArena<T>) -> impl Iterator<Item = &'a T> + 'a {
let mut list = self.list;
if self.is_backwards() {
list.reverse_reused(arena)
.expect("Forwards deque hasn't been calculated");
}
list.iter(arena)
}
pub fn iter_reversed_reused<'a>(
&self,
arena: &'a DequeArena<T>,
) -> impl Iterator<Item = &'a T> + 'a {
let mut list = self.list;
if self.is_forwards() {
list.reverse_reused(arena)
.expect("Backwards deque hasn't been calculated");
}
list.iter(arena)
}
}
impl<T> Clone for Deque<T> {
fn clone(&self) -> Deque<T> {
Deque {
list: self.list,
direction: self.direction,
}
}
}
impl<T> Copy for Deque<T> {}