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