use std::num::{NonZero, NonZeroU32};
use crate::solver_id::DenseId;
pub trait DenseIndex {
fn from_index(x: usize) -> Self;
fn to_index(self) -> usize;
}
pub type NameId = DenseId<NameTag>;
pub enum NameTag {}
#[repr(transparent)]
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct StringId(pub u32);
impl DenseIndex for StringId {
fn from_index(x: usize) -> Self {
Self(x as u32)
}
fn to_index(self) -> usize {
self.0 as usize
}
}
#[repr(transparent)]
#[derive(Clone, Default, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct VersionSetId(pub u32);
impl DenseIndex for VersionSetId {
fn from_index(x: usize) -> Self {
Self(x as u32)
}
fn to_index(self) -> usize {
self.0 as usize
}
}
#[repr(transparent)]
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct ConditionId(NonZero<u32>);
impl ConditionId {
pub fn new(id: u32) -> Self {
Self::from_index(id as usize)
}
pub fn as_u32(self) -> u32 {
self.0.get() - 1
}
}
impl DenseIndex for ConditionId {
fn from_index(x: usize) -> Self {
let id = (x + 1).try_into().expect("condition id too big");
Self(unsafe { NonZero::new_unchecked(id) })
}
fn to_index(self) -> usize {
(self.0.get() - 1) as usize
}
}
#[repr(transparent)]
#[derive(Clone, Default, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
pub struct VersionSetUnionId(pub u32);
impl DenseIndex for VersionSetUnionId {
fn from_index(x: usize) -> Self {
Self(x as u32)
}
fn to_index(self) -> usize {
self.0 as usize
}
}
pub type SolvableId = DenseId<SolvableTag>;
pub enum SolvableTag {}
#[repr(transparent)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
pub struct VariableId(NonZeroU32);
impl VariableId {
const ROOT_ID: u32 = 1;
pub fn root() -> Self {
Self(unsafe { NonZeroU32::new_unchecked(Self::ROOT_ID) })
}
pub fn is_root(self) -> bool {
self.0.get() == Self::ROOT_ID
}
}
impl DenseIndex for VariableId {
#[inline]
fn from_index(x: usize) -> Self {
let raw: u32 = (x + Self::ROOT_ID as usize)
.try_into()
.expect("variable id too big");
Self(unsafe { NonZeroU32::new_unchecked(raw) })
}
#[inline]
fn to_index(self) -> usize {
(self.0.get() - Self::ROOT_ID) as usize
}
}