1use std::hash::Hash;
7use std::ops::Range;
8
9use derivative::Derivative;
10use derive_more::{From, Into};
11use indexmap::IndexSet;
12use ref_cast::RefCast;
13use ustr::Ustr;
14
15pub trait Set {
21 type Elem: Eq + Clone;
27
28 fn contains(&self, x: &Self::Elem) -> bool;
30}
31
32pub trait FinSet: Set {
39 fn iter(&self) -> impl Iterator<Item = Self::Elem>;
46
47 fn len(&self) -> usize {
49 self.iter().count()
50 }
51
52 fn is_empty(&self) -> bool {
54 self.len() == 0
55 }
56}
57
58#[derive(Clone, Copy, Debug, From, Into, PartialEq, Eq, RefCast)]
63#[repr(transparent)]
64pub struct SkelFinSet(usize);
65
66impl SkelFinSet {
67 pub fn insert(&mut self) -> usize {
69 let new = self.0;
70 self.0 += 1;
71 new
72 }
73
74 pub fn extend(&mut self, n: usize) -> Range<usize> {
76 let start = self.0;
77 self.0 += n;
78 start..(self.0)
79 }
80}
81
82impl Default for SkelFinSet {
83 fn default() -> Self {
84 Self::from(0)
85 }
86}
87
88impl Set for SkelFinSet {
89 type Elem = usize;
90
91 fn contains(&self, x: &usize) -> bool {
92 *x < self.0
93 }
94}
95
96impl FinSet for SkelFinSet {
97 fn iter(&self) -> impl Iterator<Item = usize> {
98 0..(self.0)
99 }
100 fn len(&self) -> usize {
101 self.0
102 }
103}
104
105impl IntoIterator for SkelFinSet {
106 type Item = usize;
107 type IntoIter = Range<usize>;
108
109 fn into_iter(self) -> Self::IntoIter {
110 0..(self.0)
111 }
112}
113
114#[derive(Clone, Debug, Derivative)]
120#[derivative(Default(bound = ""))]
121#[derivative(PartialEq(bound = "T: Eq + Hash"))]
122#[derivative(Eq(bound = "T: Eq + Hash"))]
123pub struct HashFinSet<T>(IndexSet<T>);
124
125pub type UstrFinSet = HashFinSet<Ustr>;
127
128impl<T> HashFinSet<T>
129where
130 T: Eq + Hash,
131{
132 pub fn insert(&mut self, x: T) -> bool {
134 self.0.insert(x)
135 }
136}
137
138impl<T> Extend<T> for HashFinSet<T>
139where
140 T: Eq + Hash,
141{
142 fn extend<Iter>(&mut self, iter: Iter)
143 where
144 Iter: IntoIterator<Item = T>,
145 {
146 self.0.extend(iter)
147 }
148}
149
150impl<T> Set for HashFinSet<T>
151where
152 T: Eq + Clone + Hash,
153{
154 type Elem = T;
155
156 fn contains(&self, x: &T) -> bool {
157 self.0.contains(x)
158 }
159}
160
161impl<T> FinSet for HashFinSet<T>
162where
163 T: Eq + Hash + Clone,
164{
165 fn iter(&self) -> impl Iterator<Item = T> {
166 self.0.iter().cloned()
167 }
168 fn len(&self) -> usize {
169 self.0.len()
170 }
171 fn is_empty(&self) -> bool {
172 self.0.is_empty()
173 }
174}
175
176impl<T> IntoIterator for HashFinSet<T>
177where
178 T: Eq + Hash,
179{
180 type Item = T;
181 type IntoIter = indexmap::set::IntoIter<T>;
182
183 fn into_iter(self) -> Self::IntoIter {
184 self.0.into_iter()
185 }
186}
187
188#[derive(Clone, Debug, From, Derivative)]
192#[derivative(Default(bound = ""))]
193#[derivative(PartialEq(bound = "T: PartialEq"))]
194#[derivative(Eq(bound = "T: Eq"))]
195pub struct AttributedSkelSet<T>(Vec<T>);
196
197impl<T> AttributedSkelSet<T> {
198 pub fn insert(&mut self, value: T) -> usize {
200 let new = self.0.len();
201 self.0.push(value);
202 new
203 }
204
205 pub fn extend<Iter>(&mut self, iter: Iter) -> Range<usize>
207 where
208 Iter: IntoIterator<Item = T>,
209 {
210 let start = self.0.len();
211 self.0.extend(iter);
212 start..(self.0.len())
213 }
214
215 pub fn view(&self, x: usize) -> &T {
217 &self.0[x]
218 }
219}
220
221impl<T> Set for AttributedSkelSet<T> {
222 type Elem = usize;
223
224 fn contains(&self, x: &usize) -> bool {
225 *x < self.0.len()
226 }
227}
228
229impl<T> FinSet for AttributedSkelSet<T> {
230 fn iter(&self) -> impl Iterator<Item = usize> {
231 0..(self.0.len())
232 }
233 fn len(&self) -> usize {
234 self.0.len()
235 }
236 fn is_empty(&self) -> bool {
237 self.0.is_empty()
238 }
239}
240
241#[cfg(test)]
242mod tests {
243 use super::*;
244
245 #[test]
246 fn skel_fin_set() {
247 let mut s: SkelFinSet = Default::default();
248 assert!(s.is_empty());
249 assert_eq!(s.insert(), 0);
250 assert!(!s.is_empty());
251 assert_eq!(s.extend(2), 1..3);
252 assert_eq!(s.len(), 3);
253 assert!(s.contains(&2));
254 assert!(!s.contains(&3));
255 let n: usize = s.into();
256 assert_eq!(n, 3);
257
258 let s = SkelFinSet::from(3);
259 let sum: usize = s.iter().sum();
260 assert_eq!(sum, 3);
261 let elems: Vec<usize> = s.into_iter().collect();
262 assert_eq!(elems, vec![0, 1, 2]);
263 }
264
265 #[test]
266 fn hash_fin_set() {
267 let mut s: HashFinSet<i32> = Default::default();
268 assert!(s.is_empty());
269 s.insert(3);
270 s.extend([5, 7]);
271 assert!(!s.is_empty());
272 assert_eq!(s.len(), 3);
273 assert!(s.contains(&3));
274 assert!(s.contains(&7));
275 assert!(!s.contains(&2));
276 assert_eq!(s.iter().sum::<i32>(), 15);
277 assert_eq!(s.len(), 3);
278 }
279
280 #[test]
281 fn attributed_skel_set() {
282 let mut s: AttributedSkelSet<char> = Default::default();
283 assert!(s.is_empty());
284 assert_eq!(s.insert('a'), 0);
285 assert_eq!(s.extend(['b', 'c'].into_iter()), 1..3);
286 assert!(!s.is_empty());
287 assert_eq!(s.len(), 3);
288 assert!(s.contains(&2));
289 assert!(!s.contains(&3));
290 assert_eq!(*s.view(1), 'b');
291 }
292}