use crate::error::{Result, ZiporaError};
use std::cmp::Ordering;
#[repr(C)]
#[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct DaState {
pub(crate) child0: u32,
pub(crate) parent: u32,
}
pub(crate) const FREE_BIT: u32 = 0x8000_0000;
pub(crate) const VALUE_MASK: u32 = 0x7FFF_FFFF;
pub(crate) const NIL_STATE: u32 = 0x7FFF_FFFF;
pub(crate) const MAX_STATE: u32 = 0x7FFF_FFFE;
impl DaState {
#[inline(always)]
pub(crate) const fn new_free() -> Self {
Self {
child0: NIL_STATE, parent: NIL_STATE | FREE_BIT, }
}
#[inline(always)]
pub(crate) const fn new_root() -> Self {
Self {
child0: 0, parent: NIL_STATE, }
}
#[inline(always)]
pub(crate) fn child0(&self) -> u32 {
self.child0
}
#[inline(always)]
pub(crate) fn parent(&self) -> u32 {
self.parent & VALUE_MASK
}
#[inline(always)]
pub(crate) fn is_free(&self) -> bool {
(self.parent & FREE_BIT) != 0
}
#[inline(always)]
pub(crate) fn set_child0(&mut self, val: u32) {
self.child0 = val;
}
#[inline(always)]
pub(crate) fn set_parent(&mut self, val: u32) {
self.parent = val & VALUE_MASK; }
#[inline(always)]
fn set_free_linked(&mut self, next: u32, prev: u32) {
self.child0 = next; self.parent = FREE_BIT | prev; }
#[inline(always)]
pub(crate) fn set_free(&mut self) {
self.set_free_linked(NIL_STATE, NIL_STATE);
}
#[inline(always)]
#[allow(dead_code)]
fn free_next(&self) -> u32 {
self.child0
}
#[inline(always)]
#[allow(dead_code)]
fn free_prev(&self) -> u32 {
self.parent & VALUE_MASK
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub(crate) struct NInfo {
pub(crate) sibling: u16, pub(crate) child: u16, }
pub(crate) const NINFO_NONE: u16 = 0;
pub(crate) const NINFO_TERM: u16 = 0x8000;
impl NInfo {
#[inline(always)]
pub(crate) fn is_term(&self) -> bool {
(self.child & NINFO_TERM) != 0
}
#[inline(always)]
pub(crate) fn set_term(&mut self) {
self.child |= NINFO_TERM;
}
#[inline(always)]
pub(crate) fn clear_term(&mut self) {
self.child &= !NINFO_TERM;
}
#[inline(always)]
pub(crate) fn first_child(&self) -> u16 {
self.child & !NINFO_TERM
}
#[inline(always)]
pub(crate) fn set_first_child(&mut self, val: u16) {
self.child = (self.child & NINFO_TERM) | val;
}
}
#[inline(always)]
#[allow(dead_code)]
fn ninfo_to_label(v: u16) -> Option<u8> {
if v == 0 { None } else { Some((v - 1) as u8) }
}
#[inline(always)]
pub(crate) fn label_to_ninfo(label: u8) -> u16 {
label as u16 + 1
}