1use std::num::{NonZero, NonZeroU32};
4
5use crate::solver_id::DenseId;
6
7pub trait DenseIndex {
13 fn from_index(x: usize) -> Self;
15
16 fn to_index(self) -> usize;
18}
19
20pub type NameId = DenseId<NameTag>;
22
23pub enum NameTag {}
25
26#[repr(transparent)]
28#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
29#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
30#[cfg_attr(feature = "serde", serde(transparent))]
31pub struct StringId(pub u32);
32
33impl DenseIndex for StringId {
34 fn from_index(x: usize) -> Self {
35 Self(x as u32)
36 }
37
38 fn to_index(self) -> usize {
39 self.0 as usize
40 }
41}
42
43#[repr(transparent)]
45#[derive(Clone, Default, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
46#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
47#[cfg_attr(feature = "serde", serde(transparent))]
48pub struct VersionSetId(pub u32);
49
50impl DenseIndex for VersionSetId {
51 fn from_index(x: usize) -> Self {
52 Self(x as u32)
53 }
54
55 fn to_index(self) -> usize {
56 self.0 as usize
57 }
58}
59
60#[repr(transparent)]
62#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
63#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64#[cfg_attr(feature = "serde", serde(transparent))]
65pub struct ConditionId(NonZero<u32>);
66
67impl ConditionId {
68 pub fn new(id: u32) -> Self {
70 Self::from_index(id as usize)
71 }
72
73 pub fn as_u32(self) -> u32 {
75 self.0.get() - 1
76 }
77}
78
79impl DenseIndex for ConditionId {
80 fn from_index(x: usize) -> Self {
81 let id = (x + 1).try_into().expect("condition id too big");
82 Self(unsafe { NonZero::new_unchecked(id) })
83 }
84
85 fn to_index(self) -> usize {
86 (self.0.get() - 1) as usize
87 }
88}
89
90#[repr(transparent)]
92#[derive(Clone, Default, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
93#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
94#[cfg_attr(feature = "serde", serde(transparent))]
95pub struct VersionSetUnionId(pub u32);
96
97impl DenseIndex for VersionSetUnionId {
98 fn from_index(x: usize) -> Self {
99 Self(x as u32)
100 }
101
102 fn to_index(self) -> usize {
103 self.0 as usize
104 }
105}
106
107pub type SolvableId = DenseId<SolvableTag>;
109
110pub enum SolvableTag {}
112
113#[repr(transparent)]
118#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, PartialOrd, Ord)]
119pub struct VariableId(NonZeroU32);
120
121impl VariableId {
122 const ROOT_ID: u32 = 1;
123
124 pub fn root() -> Self {
126 Self(unsafe { NonZeroU32::new_unchecked(Self::ROOT_ID) })
128 }
129
130 pub fn is_root(self) -> bool {
132 self.0.get() == Self::ROOT_ID
133 }
134}
135
136impl DenseIndex for VariableId {
137 #[inline]
138 fn from_index(x: usize) -> Self {
139 let raw: u32 = (x + Self::ROOT_ID as usize)
140 .try_into()
141 .expect("variable id too big");
142 Self(unsafe { NonZeroU32::new_unchecked(raw) })
144 }
145
146 #[inline]
147 fn to_index(self) -> usize {
148 (self.0.get() - Self::ROOT_ID) as usize
149 }
150}