#[macro_export]
macro_rules! uid_basic_operations_impl {
($name:ident) => {
impl std::ops::Add<usize> for $name {
type Output = $name;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}
impl std::ops::Sub<usize> for $name {
type Output = $name;
fn sub(self, rhs: usize) -> Self::Output {
Self(self.0 - rhs)
}
}
impl std::ops::Add<u32> for $name {
type Output = $name;
fn add(self, rhs: u32) -> Self::Output {
self.add(rhs as usize)
}
}
impl std::ops::Sub<u32> for $name {
type Output = $name;
fn sub(self, rhs: u32) -> Self::Output {
self.sub(rhs as usize)
}
}
impl std::ops::Add<i32> for $name {
type Output = $name;
fn add(self, rhs: i32) -> Self::Output {
Self(((self.0 as i32) + rhs) as usize)
}
}
impl std::ops::Sub<i32> for $name {
type Output = $name;
fn sub(self, rhs: i32) -> Self::Output {
Self(((self.0 as i32) - rhs) as usize)
}
}
impl std::ops::Add for $name {
type Output = $name;
fn add(self, rhs: $name) -> Self::Output {
Self(self.0 + rhs.0)
}
}
impl std::ops::AddAssign<usize> for $name {
fn add_assign(&mut self, rhs: usize) {
self.0 += rhs
}
}
impl std::ops::Sub for $name {
type Output = $name;
fn sub(self, rhs: $name) -> Self::Output {
Self(self.0 - rhs.0)
}
}
impl std::ops::SubAssign<usize> for $name {
fn sub_assign(&mut self, rhs: usize) {
self.0 -= rhs
}
}
impl std::ops::AddAssign for $name {
fn add_assign(&mut self, rhs: $name) {
self.0 += rhs.0
}
}
impl std::ops::SubAssign for $name {
fn sub_assign(&mut self, rhs: $name) {
self.0 -= rhs.0
}
}
impl $name {
pub fn succ(mut self) -> Self {
self.0 += 1;
self
}
pub fn pred(self) -> Self {
self.nat().unwrap()
}
pub fn nat(self) -> Option<Self> {
if self.0 == 0 {
None
} else {
Some(Self(self.0 - 1))
}
}
}
impl std::fmt::Display for $name {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::result::Result<(), std::fmt::Error> {
self.0.fmt(f)
}
}
};
}
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
pub struct DBI(pub usize);
uid_basic_operations_impl!(DBI);
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
pub struct UID(pub usize);
uid_basic_operations_impl!(UID);
#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash, Default)]
pub struct GI(pub usize);
uid_basic_operations_impl!(GI);
static mut UID_COUNT: usize = 0;
pub unsafe fn reset_uid_counter() {
UID_COUNT = 0;
}
pub unsafe fn next_uid() -> UID {
let val = UID_COUNT;
UID_COUNT += 1;
UID(val)
}