use std::marker::PhantomData;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Transition;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Place;
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)]
pub struct Id<T> {
pub(super) index: usize,
kind: PhantomData<T>,
}
impl<T> Id<T> {
#[inline]
pub(super) fn new(index: usize) -> Self {
Self {
index,
kind: PhantomData::<T>,
}
}
}
pub type Tid = Id<Transition>;
impl Tid {
#[inline(always)]
pub(super) fn assert(self, count: usize) {
assert!(self.index < count, "Transition id out of range");
}
}
pub type Pid = Id<Place>;
impl Pid {
#[inline(always)]
pub(super) fn assert(self, count: usize) {
assert!(self.index < count, "Place id out of range");
}
}
pub struct Ids<T> {
pub(super) start: usize,
pub(super) end: usize,
pub(super) kind: PhantomData<T>,
}
impl<T: Copy> Iterator for Ids<T> {
type Item = Id<T>;
fn next(&mut self) -> Option<Id<T>> {
(self.start < self.end).then(|| {
let id = Id {
index: self.start,
kind: self.kind,
};
self.start += 1;
id
})
}
}
impl<T: Copy> DoubleEndedIterator for Ids<T> {
fn next_back(&mut self) -> Option<Id<T>> {
(self.start < self.end).then(|| {
self.end -= 1;
Id {
index: self.end,
kind: self.kind,
}
})
}
}
impl<T: Copy> ExactSizeIterator for Ids<T> {
fn len(&self) -> usize {
self.end - self.start
}
}