1use core::fmt;
2use equivalent::Comparable;
3use std::{
4 cmp::Ordering,
5 hash::{Hash, Hasher},
6 iter::FusedIterator,
7 ops::Index,
8};
9
10use crate::{
11 multi_map::{self, BTreeIndexMultiMap},
12 util::entries_as_slice,
13};
14
15#[derive(Clone)]
46pub struct BTreeIndexMultiSet<T> {
47 map: BTreeIndexMultiMap<T, ()>,
48}
49
50impl<T> Default for BTreeIndexMultiSet<T> {
51 fn default() -> Self {
52 Self::new()
53 }
54}
55
56impl<T> BTreeIndexMultiSet<T> {
57 pub fn new() -> Self {
59 Self {
60 map: BTreeIndexMultiMap::new(),
61 }
62 }
63
64 pub fn with_capacity(capacity: usize) -> Self {
67 Self {
68 map: BTreeIndexMultiMap::with_capacity(capacity),
69 }
70 }
71
72 pub fn singleton(value: T) -> Self
74 where
75 T: Ord,
76 {
77 Self {
78 map: BTreeIndexMultiMap::singleton(value, ()),
79 }
80 }
81
82 pub fn clear(&mut self) {
86 self.map.clear();
87 }
88
89 pub fn capacity(&self) -> usize {
92 self.map.capacity()
93 }
94
95 pub fn is_empty(&self) -> bool {
97 self.map.is_empty()
98 }
99
100 pub fn len(&self) -> usize {
102 self.map.len()
103 }
104
105 pub fn as_slice(&self) -> &[T] {
108 entries_as_slice(self.map.as_entries())
109 }
110
111 pub fn first(&self) -> Option<&T> {
114 self.map.first().map(|(t, ())| t)
115 }
116
117 pub fn last(&self) -> Option<&T> {
120 self.map.last().map(|(t, ())| t)
121 }
122
123 pub fn contains<Q>(&self, value: &Q) -> bool
126 where
127 Q: ?Sized + Comparable<T>,
128 {
129 self.map.contains_key(value)
130 }
131
132 pub fn count<Q>(&self, value: &Q) -> usize
134 where
135 Q: ?Sized + Comparable<T>,
136 {
137 self.map.key_occurences(value)
138 }
139
140 pub fn indexes_of<Q>(&self, value: &Q) -> multi_map::IndexesIter<'_>
142 where
143 Q: ?Sized + Comparable<T>,
144 {
145 self.map.indexes_of(value)
146 }
147
148 pub fn index_of<Q>(&self, value: &Q) -> Option<usize>
150 where
151 Q: ?Sized + Comparable<T>,
152 {
153 self.map.index_of(value)
154 }
155
156 pub fn get_indexed<Q>(&self, value: &Q) -> GetIndexed<'_, T>
159 where
160 Q: ?Sized + Comparable<T>,
161 {
162 GetIndexed(self.map.get_indexed_entries(value))
163 }
164
165 pub fn get<Q>(&self, value: &Q) -> Get<'_, T>
168 where
169 Q: ?Sized + Comparable<T>,
170 {
171 Get(self.map.get_indexed_entries(value))
172 }
173
174 pub fn push_back(&mut self, value: T) -> (usize, bool)
179 where
180 T: Ord,
181 {
182 self.map.push_back(value, ())
183 }
184
185 pub fn push_front(&mut self, value: T) -> bool
189 where
190 T: Ord,
191 {
192 self.map.push_front(value, ())
193 }
194
195 pub fn insert_at(&mut self, index: usize, value: T) -> bool
203 where
204 T: Ord,
205 {
206 self.map.insert_at(index, value, ())
207 }
208
209 pub fn insert(&mut self, value: T) -> (usize, bool)
214 where
215 T: Ord,
216 {
217 self.push_back(value)
218 }
219
220 pub fn shift_remove_at(&mut self, index: usize) -> Option<T>
223 where
224 T: Ord,
225 {
226 self.map.shift_remove_at(index).map(|(t, ())| t)
227 }
228
229 pub fn swap_remove_at(&mut self, index: usize) -> Option<T>
232 where
233 T: Ord,
234 {
235 self.map.swap_remove_at(index).map(|(t, ())| t)
236 }
237
238 pub fn shift_remove<Q>(&mut self, value: &Q) -> ShiftRemove<'_, T>
243 where
244 Q: ?Sized + Comparable<T>,
245 {
246 ShiftRemove(self.map.shift_remove_entries(value))
247 }
248
249 pub fn swap_remove<Q>(&mut self, value: &Q) -> SwapRemove<'_, T>
254 where
255 Q: ?Sized + Comparable<T>,
256 T: Ord,
257 {
258 SwapRemove(self.map.swap_remove_entries(value))
259 }
260
261 pub fn iter(&self) -> Iter<'_, T> {
264 self.as_slice().iter()
265 }
266
267 pub fn iter_sorted(&self) -> IterSorted<'_, T> {
270 IterSorted(self.map.iter_sorted())
271 }
272
273 pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
276 IntoIterSorted(self.map.into_iter_sorted())
277 }
278
279 pub fn sort(&mut self)
283 where
284 T: Ord,
285 {
286 self.map.sort()
287 }
288}
289
290impl<T> Index<usize> for BTreeIndexMultiSet<T> {
291 type Output = T;
292
293 fn index(&self, index: usize) -> &Self::Output {
297 &self.as_slice()[index]
298 }
299}
300
301impl<T> IntoIterator for BTreeIndexMultiSet<T> {
302 type IntoIter = IntoIter<T>;
303 type Item = T;
304
305 fn into_iter(self) -> Self::IntoIter {
306 IntoIter(self.map.into_iter())
307 }
308}
309
310impl<T: PartialEq> PartialEq for BTreeIndexMultiSet<T> {
311 fn eq(&self, other: &Self) -> bool {
312 self.iter_sorted().eq(other.iter_sorted())
313 }
314}
315
316impl<T: Eq> Eq for BTreeIndexMultiSet<T> {}
317
318impl<T: PartialOrd> PartialOrd for BTreeIndexMultiSet<T> {
319 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
320 self.iter_sorted().partial_cmp(other.iter_sorted())
321 }
322}
323
324impl<T: Ord> Ord for BTreeIndexMultiSet<T> {
325 fn cmp(&self, other: &Self) -> Ordering {
326 self.iter_sorted().cmp(other.iter_sorted())
327 }
328}
329
330impl<T: Hash> Hash for BTreeIndexMultiSet<T> {
331 fn hash<H: Hasher>(&self, state: &mut H) {
332 state.write_usize(self.len());
333 for item in self.iter_sorted() {
334 item.hash(state);
335 }
336 }
337}
338
339impl<T: fmt::Debug> fmt::Debug for BTreeIndexMultiSet<T> {
340 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
341 f.debug_set().entries(self.iter()).finish()
342 }
343}
344
345impl<T: Ord> Extend<T> for BTreeIndexMultiSet<T> {
346 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
347 for value in iter {
348 self.push_back(value);
349 }
350 }
351}
352
353impl<T: Ord> FromIterator<T> for BTreeIndexMultiSet<T> {
354 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
355 let mut result = Self::new();
356 result.extend(iter);
357 result
358 }
359}
360
361pub struct GetIndexed<'a, T>(multi_map::GetIndexedEntries<'a, T, ()>);
366
367impl<'a, T> Iterator for GetIndexed<'a, T> {
368 type Item = (usize, &'a T);
369
370 fn next(&mut self) -> Option<Self::Item> {
371 self.0.next().map(|(i, t, ())| (i, t))
372 }
373}
374
375pub struct Get<'a, T>(multi_map::GetIndexedEntries<'a, T, ()>);
380
381impl<'a, T> Iterator for Get<'a, T> {
382 type Item = &'a T;
383
384 fn next(&mut self) -> Option<Self::Item> {
385 self.0.next().map(|(_, t, ())| t)
386 }
387}
388
389pub struct ShiftRemove<'a, T>(multi_map::ShiftRemoveEntries<'a, T, ()>);
392
393impl<'a, T> Iterator for ShiftRemove<'a, T> {
394 type Item = T;
395
396 fn size_hint(&self) -> (usize, Option<usize>) {
397 self.0.size_hint()
398 }
399
400 fn next(&mut self) -> Option<Self::Item> {
401 self.0.next().map(|(t, ())| t)
402 }
403}
404
405impl<T> ExactSizeIterator for ShiftRemove<'_, T> {}
406
407pub struct SwapRemove<'a, T: Ord>(multi_map::SwapRemoveEntries<'a, T, ()>);
410
411impl<'a, T: Ord> Iterator for SwapRemove<'a, T> {
412 type Item = T;
413
414 fn size_hint(&self) -> (usize, Option<usize>) {
415 self.0.size_hint()
416 }
417
418 fn next(&mut self) -> Option<Self::Item> {
419 self.0.next().map(|(t, ())| t)
420 }
421}
422
423impl<T: Ord> ExactSizeIterator for SwapRemove<'_, T> {}
424
425pub type Iter<'a, T> = std::slice::Iter<'a, T>;
431
432impl<'a, T> IntoIterator for &'a BTreeIndexMultiSet<T> {
433 type IntoIter = Iter<'a, T>;
434 type Item = &'a T;
435
436 fn into_iter(self) -> Self::IntoIter {
437 self.iter()
438 }
439}
440
441pub struct IterSorted<'a, T>(multi_map::IterSorted<'a, T, ()>);
444
445impl<T> Clone for IterSorted<'_, T> {
446 fn clone(&self) -> Self {
447 Self(self.0.clone())
448 }
449}
450
451impl<'a, T> Iterator for IterSorted<'a, T> {
452 type Item = &'a T;
453
454 fn size_hint(&self) -> (usize, Option<usize>) {
455 self.0.size_hint()
456 }
457
458 fn next(&mut self) -> Option<Self::Item> {
459 self.0.next().map(|(t, ())| t)
460 }
461}
462
463impl<T> ExactSizeIterator for IterSorted<'_, T> {}
464
465impl<T> FusedIterator for IterSorted<'_, T> {}
466
467pub struct IntoIterSorted<T>(multi_map::IntoIterSorted<T, ()>);
470
471impl<T> Iterator for IntoIterSorted<T> {
472 type Item = T;
473
474 fn size_hint(&self) -> (usize, Option<usize>) {
475 self.0.size_hint()
476 }
477
478 fn next(&mut self) -> Option<Self::Item> {
479 self.0.next().map(|(t, ())| t)
480 }
481}
482
483impl<T> ExactSizeIterator for IntoIterSorted<T> {}
484
485impl<T> FusedIterator for IntoIterSorted<T> {}
486
487pub struct IntoIter<T>(multi_map::IntoIter<T, ()>);
490
491impl<T> Iterator for IntoIter<T> {
492 type Item = T;
493
494 fn size_hint(&self) -> (usize, Option<usize>) {
495 self.0.size_hint()
496 }
497
498 fn next(&mut self) -> Option<Self::Item> {
499 self.0.next().map(|(t, ())| t)
500 }
501}
502
503impl<T> DoubleEndedIterator for IntoIter<T> {
504 fn next_back(&mut self) -> Option<Self::Item> {
505 self.0.next_back().map(|(t, ())| t)
506 }
507}
508
509impl<T> ExactSizeIterator for IntoIter<T> {}
510
511impl<T> FusedIterator for IntoIter<T> {}