1#![cfg(feature = "ordered")]
2use crate::AnySet;
9use crate::SmallOrderedMap;
10use std::borrow::Borrow;
11use std::fmt::{self, Debug};
12use std::hash::Hash;
13use std::iter::FromIterator;
14
15pub struct SmallOrderedSet<T: Eq + Hash, const N: usize> {
32 map: SmallOrderedMap<T, (), N>,
33}
34
35impl<T, const N: usize> SmallOrderedSet<T, N>
36where
37 T: Eq + Hash,
38{
39 pub fn new() -> Self {
41 Self {
42 map: SmallOrderedMap::new(),
43 }
44 }
45
46 #[inline]
48 pub fn is_on_stack(&self) -> bool {
49 self.map.is_on_stack()
50 }
51
52 #[inline]
54 pub fn len(&self) -> usize {
55 self.map.len()
56 }
57
58 #[inline]
60 pub fn is_empty(&self) -> bool {
61 self.map.is_empty()
62 }
63
64 #[inline]
66 pub fn clear(&mut self) {
67 self.map.clear();
68 }
69
70 pub fn insert(&mut self, value: T) -> bool {
72 if self.map.contains_key(&value) {
73 false
74 } else {
75 self.map.insert(value, ());
76 true
77 }
78 }
79
80 pub fn contains<Q>(&self, value: &Q) -> bool
82 where
83 T: Borrow<Q>,
84 Q: Hash + Eq + ?Sized,
85 {
86 self.map.contains_key(value)
87 }
88
89 pub fn remove<Q>(&mut self, value: &Q) -> bool
91 where
92 T: Borrow<Q> + PartialEq<Q>,
93 Q: Hash + Eq + ?Sized,
94 {
95 self.map.remove(value).is_some()
96 }
97
98 pub fn retain<F>(&mut self, mut f: F)
100 where
101 F: FnMut(&T) -> bool,
102 {
103 let old_map = std::mem::replace(&mut self.map, SmallOrderedMap::new());
104 for (k, _) in old_map {
105 if f(&k) {
106 self.map.insert(k, ());
107 }
108 }
109 }
110
111 pub fn iter(&self) -> SetRefIter<'_, T> {
113 SetRefIter {
114 iter: self.map.iter(),
115 }
116 }
117}
118
119impl<T, const N: usize> AnySet<T> for SmallOrderedSet<T, N>
122where
123 T: Eq + Hash,
124{
125 fn contains(&self, value: &T) -> bool {
126 self.contains(value)
127 }
128
129 fn len(&self) -> usize {
130 self.len()
131 }
132}
133
134impl<T, const N: usize> Clone for SmallOrderedSet<T, N>
135where
136 T: Eq + Hash + Clone,
137{
138 fn clone(&self) -> Self {
139 Self {
140 map: self.map.clone(),
141 }
142 }
143}
144
145impl<T, const N: usize> Default for SmallOrderedSet<T, N>
146where
147 T: Eq + Hash,
148{
149 fn default() -> Self {
150 Self::new()
151 }
152}
153
154impl<T, const N: usize> Debug for SmallOrderedSet<T, N>
155where
156 T: Eq + Hash + Debug,
157{
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 f.debug_set().entries(self.iter()).finish()
160 }
161}
162
163impl<T, const N: usize> FromIterator<T> for SmallOrderedSet<T, N>
164where
165 T: Eq + Hash,
166{
167 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
168 let mut set = Self::new();
169 for val in iter {
170 set.insert(val);
171 }
172 set
173 }
174}
175
176impl<T, const N: usize> IntoIterator for SmallOrderedSet<T, N>
177where
178 T: Eq + Hash,
179{
180 type Item = T;
181 type IntoIter = SmallSetIntoIter<T, N>;
182
183 fn into_iter(self) -> Self::IntoIter {
184 SmallSetIntoIter {
185 iter: self.map.into_iter(),
186 }
187 }
188}
189
190pub struct SmallSetIntoIter<T: Eq, const N: usize> {
192 iter: crate::maps::ordered_map::SmallMapIntoIter<T, (), N>,
193}
194
195impl<T, const N: usize> Iterator for SmallSetIntoIter<T, N>
196where
197 T: Eq + Hash,
198{
199 type Item = T;
200 fn next(&mut self) -> Option<Self::Item> {
201 self.iter.next().map(|(k, _)| k)
202 }
203}
204
205pub struct SetRefIter<'a, T> {
207 iter: crate::maps::ordered_map::SmallMapIter<'a, T, ()>,
208}
209
210impl<'a, T> Iterator for SetRefIter<'a, T> {
211 type Item = &'a T;
212 fn next(&mut self) -> Option<Self::Item> {
213 self.iter.next().map(|(k, _)| k)
214 }
215}
216
217impl<T, const N: usize> Extend<T> for SmallOrderedSet<T, N>
218where
219 T: Eq + Hash,
220{
221 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
222 for item in iter {
223 self.insert(item);
224 }
225 }
226}
227
228impl<T, const N: usize, S> PartialEq<S> for SmallOrderedSet<T, N>
229where
230 T: Eq + Hash,
231 S: AnySet<T>,
232{
233 fn eq(&self, other: &S) -> bool {
234 if self.len() != other.len() {
235 return false;
236 }
237 self.iter().all(|v| other.contains(v))
238 }
239}
240
241impl<T, const N: usize> Eq for SmallOrderedSet<T, N> where T: Eq + Hash {}
242
243#[cfg(test)]
244mod tests {
245 use super::*;
246
247 #[test]
248 fn test_ordered_set_stack_ops_insertion_order() {
249 let mut set: SmallOrderedSet<i32, 4> = SmallOrderedSet::new();
250 set.insert(3);
251 set.insert(1);
252 set.insert(2);
253
254 let vals: Vec<_> = set.iter().cloned().collect();
255 assert_eq!(vals, vec![3, 1, 2]);
256 }
257
258 #[test]
259 fn test_ordered_set_spill_trigger_on_insert() {
260 let mut set: SmallOrderedSet<i32, 2> = SmallOrderedSet::new();
261 set.insert(1);
262 set.insert(2);
263 assert!(set.is_on_stack());
264
265 set.insert(3);
266 assert!(!set.is_on_stack());
267
268 let vals: Vec<_> = set.iter().cloned().collect();
269 assert_eq!(vals, vec![1, 2, 3]);
270 }
271
272 #[test]
273 fn test_ordered_set_any_storage_lifecycle_duplicates() {
274 let mut set: SmallOrderedSet<String, 2> = SmallOrderedSet::new();
275 assert!(set.insert("a".into()));
276 assert!(!set.insert("a".into())); assert!(set.insert("b".into()));
278 assert_eq!(set.len(), 2);
279 assert!(set.is_on_stack());
280
281 assert!(set.insert("c".into())); assert!(!set.is_on_stack());
283 assert_eq!(set.len(), 3);
284 assert!(set.contains("a"));
285 assert!(set.contains("b"));
286 assert!(set.contains("c"));
287
288 assert!(set.remove("a"));
289 assert!(!set.contains("a"));
290 assert_eq!(set.len(), 2);
291 }
292
293 #[test]
294 fn test_ordered_set_traits_interop() {
295 use std::collections::HashSet;
296 let set: SmallOrderedSet<i32, 4> = vec![1, 2, 3].into_iter().collect();
297 let mut std_set = HashSet::new();
298 std_set.insert(1);
299 std_set.insert(2);
300 std_set.insert(3);
301
302 assert_eq!(set, std_set);
303 }
304
305 #[test]
306 fn test_ordered_set_any_storage_clear() {
307 let mut set: SmallOrderedSet<i32, 2> = SmallOrderedSet::new();
308 assert!(set.is_empty());
309 set.insert(1);
310 set.clear();
311 assert!(set.is_empty());
312
313 set.insert(1);
314 set.insert(2);
315 set.insert(3); set.clear();
317 assert!(set.is_empty());
318 assert!(!set.is_on_stack());
319 }
320
321 #[test]
322 fn test_ordered_set_traits_exhaustive() {
323 let mut set: SmallOrderedSet<i32, 4> = SmallOrderedSet::new();
324 set.insert(1);
325 set.insert(2);
326
327 let cloned = set.clone();
329 assert_eq!(cloned.len(), 2);
330 assert!(cloned.contains(&1));
331
332 let debug = format!("{:?}", set);
334 assert!(debug.contains("1"));
335
336 let def: SmallOrderedSet<i32, 4> = SmallOrderedSet::default();
338 assert!(def.is_empty());
339
340 let set2: SmallOrderedSet<i32, 4> = vec![1, 2].into_iter().collect();
342 let vec: Vec<_> = set2.into_iter().collect();
343 assert_eq!(vec, vec![1, 2]);
344
345 let mut set3 = SmallOrderedSet::<i32, 4>::new();
347 set3.extend(vec![1, 2]);
348 assert_eq!(set3.len(), 2);
349 }
350
351 #[test]
352 fn test_ordered_set_traits_any_set_impl() {
353 let set: SmallOrderedSet<i32, 2> = vec![1, 2, 3].into_iter().collect();
354 assert!(!set.is_on_stack());
355
356 let any: &dyn AnySet<i32> = &set;
358 assert_eq!(any.len(), 3);
359 assert!(any.contains(&1));
360 }
361
362 #[test]
363 fn test_ordered_set_traits_partial_eq_variants() {
364 let set: SmallOrderedSet<i32, 2> = vec![1, 2, 3].into_iter().collect();
365 let set2: SmallOrderedSet<i32, 2> = vec![1, 2].into_iter().collect();
366 assert_ne!(set, set2);
367 }
368
369 #[test]
370 fn test_ordered_set_coverage_gaps() {
371 let mut set: SmallOrderedSet<i32, 4> = vec![1, 2, 3, 4].into_iter().collect();
372
373 set.retain(|x| x % 2 == 0);
375
376 assert_eq!(set.len(), 2);
377 assert!(set.contains(&2));
378 assert!(set.contains(&4));
379 }
380}