#[cfg(feature = "memory")]
use mm0_deepsize_derive::DeepSizeOf;
use std::fmt;
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut, Index, IndexMut};
macro_rules! id_wrapper {
($id:ident: $ty:ty, $vec:ident) => {
id_wrapper!($id: $ty, $vec, concat!("An index into a [`", stringify!($vec), "`]"));
};
($id:ident: $ty:ty, $vec:ident, $svec:expr) => {
#[doc=$svec]
#[derive(Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, Default)]
pub struct $id(pub $ty);
#[cfg(feature = "memory")]
mm0_deepsize::deep_size_0!($id);
impl $id {
#[must_use]
pub fn into_inner(self) -> $ty { self.0 }
}
impl fmt::Debug for $id {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.0.fmt(f) }
}
#[cfg_attr(feature = "memory", derive(DeepSizeOf))]
#[derive(Clone, Debug)]
pub struct $vec<T>(pub Vec<T>);
#[allow(dead_code)]
impl<T> $vec<T> {
#[must_use]
pub fn get(&self, i: $id) -> Option<&T> { self.0.get(i.0 as usize) }
#[must_use]
pub fn get_mut(&mut self, i: $id) -> Option<&mut T> { self.0.get_mut(i.0 as usize) }
pub fn enum_iter(&self) -> impl Iterator<Item = ($id, &T)> {
self.0.iter().enumerate().map(|(i, t)| ($id(i as $ty), t))
}
pub fn enum_iter_mut(&mut self) -> impl Iterator<Item = ($id, &mut T)> {
self.0.iter_mut().enumerate().map(|(i, t)| ($id(i as $ty), t))
}
pub fn push(&mut self, t: T) -> $id {
let n = $id(self.0.len() as $ty);
self.0.push(t);
n
}
}
impl<T> Default for $vec<T> {
fn default() -> $vec<T> { $vec(Vec::new()) }
}
impl<T> Index<$id> for $vec<T> {
type Output = T;
fn index(&self, i: $id) -> &T { &self.0[i.0 as usize] }
}
impl<T> IndexMut<$id> for $vec<T> {
fn index_mut(&mut self, i: $id) -> &mut T { &mut self.0[i.0 as usize] }
}
impl<T> Deref for $vec<T> {
type Target = Vec<T>;
fn deref(&self) -> &Vec<T> { &self.0 }
}
impl<T> DerefMut for $vec<T> {
fn deref_mut(&mut self) -> &mut Vec<T> { &mut self.0 }
}
impl<T> FromIterator<T> for $vec<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self { $vec(Vec::from_iter(iter)) }
}
};
}
id_wrapper!(SortId: u8, SortVec);
id_wrapper!(TermId: u32, TermVec);
id_wrapper!(ThmId: u32, ThmVec);
id_wrapper!(AtomId: u32, AtomVec);
bitflags! {
pub struct Modifiers: u8 {
const PURE = 1;
const STRICT = 2;
const PROVABLE = 4;
const FREE = 8;
const PUB = 16;
const ABSTRACT = 32;
const LOCAL = 64;
}
}
#[cfg(feature = "memory")]
mm0_deepsize::deep_size_0!(Modifiers);
impl Modifiers {
pub const NONE: Modifiers = Self::empty();
#[must_use]
pub fn new(bits: u8) -> Self { Self { bits } }
#[must_use]
pub fn sort_data() -> Modifiers {
Modifiers::PURE | Modifiers::STRICT | Modifiers::PROVABLE | Modifiers::FREE
}
#[must_use]
pub fn from_name(s: &[u8]) -> Modifiers {
match s {
b"pure" => Modifiers::PURE,
b"strict" => Modifiers::STRICT,
b"provable" => Modifiers::PROVABLE,
b"free" => Modifiers::FREE,
b"pub" => Modifiers::PUB,
b"abstract" => Modifiers::ABSTRACT,
b"local" => Modifiers::LOCAL,
_ => Modifiers::NONE,
}
}
}
impl fmt::Display for Modifiers {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.contains(Modifiers::PURE) {
write!(f, "pure ")?
}
if self.contains(Modifiers::STRICT) {
write!(f, "strict ")?
}
if self.contains(Modifiers::PROVABLE) {
write!(f, "provable ")?
}
if self.contains(Modifiers::FREE) {
write!(f, "free ")?
}
if self.contains(Modifiers::PUB) {
write!(f, "pub ")?
}
if self.contains(Modifiers::ABSTRACT) {
write!(f, "abstract ")?
}
if self.contains(Modifiers::LOCAL) {
write!(f, "local ")?
}
Ok(())
}
}
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum Prec {
Prec(u32),
Max,
}
#[cfg(feature = "memory")]
mm0_deepsize::deep_size_0!(Prec);
impl fmt::Display for Prec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
&Prec::Prec(p) => p.fmt(f),
Prec::Max => "max".fmt(f),
}
}
}
impl fmt::Debug for Prec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::Display::fmt(self, f) }
}
pub const APP_PREC: Prec = Prec::Prec(1024);