Skip to main content

btree_indexmap/
multi_set.rs

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/// BTree-based index multi-set.
16///
17/// This is a thin wrapper around
18/// [`BTreeIndexMultiMap<T, ()>`](BTreeIndexMultiMap) providing a multi-set
19/// API: a value can occur any number of times, every occurrence keeps a
20/// stable index until it (or an earlier entry) is removed, and occurrences
21/// can be iterated either in insertion order or in sorted order.
22///
23/// # Example
24///
25/// ```
26/// use btree_indexmap::BTreeIndexMultiSet;
27///
28/// let mut set = BTreeIndexMultiSet::new();
29///
30/// // Multiple occurrences of the same value, each with its own stable
31/// // index.
32/// set.push_back("apple");
33/// set.push_back("carrot");
34/// set.push_back("apple");
35///
36/// assert_eq!(set.count("apple"), 2);
37///
38/// let apples: Vec<_> = set.get("apple").copied().collect();
39/// assert_eq!(apples, ["apple", "apple"]);
40///
41/// // Iterate in sorted order, occurrences in position order.
42/// let sorted: Vec<_> = set.iter_sorted().copied().collect();
43/// assert_eq!(sorted, ["apple", "apple", "carrot"]);
44/// ```
45#[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	/// Creates a new, empty multi-set.
58	pub fn new() -> Self {
59		Self {
60			map: BTreeIndexMultiMap::new(),
61		}
62	}
63
64	/// Creates a new, empty multi-set with space reserved for at least
65	/// `capacity` occurrences.
66	pub fn with_capacity(capacity: usize) -> Self {
67		Self {
68			map: BTreeIndexMultiMap::with_capacity(capacity),
69		}
70	}
71
72	/// Creates a new multi-set containing the single `value`.
73	pub fn singleton(value: T) -> Self
74	where
75		T: Ord,
76	{
77		Self {
78			map: BTreeIndexMultiMap::singleton(value, ()),
79		}
80	}
81
82	/// Removes all occurrences from the set.
83	///
84	/// This keeps the capacity allocated for the occurrences.
85	pub fn clear(&mut self) {
86		self.map.clear();
87	}
88
89	/// Returns the number of occurrences the set can hold without
90	/// reallocating.
91	pub fn capacity(&self) -> usize {
92		self.map.capacity()
93	}
94
95	/// Returns `true` if the set contains no occurrences.
96	pub fn is_empty(&self) -> bool {
97		self.map.is_empty()
98	}
99
100	/// Returns the total number of occurrences in the set.
101	pub fn len(&self) -> usize {
102		self.map.len()
103	}
104
105	/// Returns the values of the set as a slice, in insertion (index)
106	/// order.
107	pub fn as_slice(&self) -> &[T] {
108		entries_as_slice(self.map.as_entries())
109	}
110
111	/// Returns a reference to the first occurrence in the set (in insertion
112	/// order), if any.
113	pub fn first(&self) -> Option<&T> {
114		self.map.first().map(|(t, ())| t)
115	}
116
117	/// Returns a reference to the last occurrence in the set (in insertion
118	/// order), if any.
119	pub fn last(&self) -> Option<&T> {
120		self.map.last().map(|(t, ())| t)
121	}
122
123	/// Returns `true` if the set contains at least one occurrence of
124	/// `value`.
125	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	/// Returns the number of occurrences of `value` in the set.
133	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	/// Returns an iterator over the indexes of every occurrence of `value`.
141	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	/// Returns the index of the first occurrence of `value`.
149	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	/// Returns an iterator over `(index, &value)` for every occurrence of
157	/// `value`.
158	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	/// Returns an iterator over a reference to `value` for every occurrence
166	/// found in the set.
167	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	/// Inserts a new occurrence of `value` at the end of the set.
175	///
176	/// Returns the index of the new occurrence, and whether `value` was not
177	/// already present in the set.
178	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	/// Inserts a new occurrence of `value` at the front of the set.
186	///
187	/// Returns whether `value` was not already present in the set.
188	pub fn push_front(&mut self, value: T) -> bool
189	where
190		T: Ord,
191	{
192		self.map.push_front(value, ())
193	}
194
195	/// Inserts a new occurrence of `value` at the given `index`.
196	///
197	/// Returns whether `value` was not already present in the set.
198	///
199	/// # Panics
200	///
201	/// Panics if `index > len`.
202	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	/// Inserts a new occurrence of `value` in the set, without removing any
210	/// existing occurrence.
211	///
212	/// This is an alias for [`Self::push_back`].
213	pub fn insert(&mut self, value: T) -> (usize, bool)
214	where
215		T: Ord,
216	{
217		self.push_back(value)
218	}
219
220	/// Removes the occurrence at the given `index`, shifting every
221	/// following occurrence one index down.
222	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	/// Removes the occurrence at the given `index`, moving the last
230	/// occurrence into its place.
231	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	/// Removes every occurrence of `value`, returning an iterator over the
239	/// removed occurrences.
240	///
241	/// Shifts the remaining occurrences down to fill the gaps.
242	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	/// Removes every occurrence of `value`, returning an iterator over the
250	/// removed occurrences.
251	///
252	/// Moves occurrences from the end of the set into the gaps.
253	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	/// Returns an iterator over the values of the set, in insertion (index)
262	/// order.
263	pub fn iter(&self) -> Iter<'_, T> {
264		self.as_slice().iter()
265	}
266
267	/// Returns an iterator over the values of the set, sorted according to
268	/// `T`'s implementation of [`Ord`].
269	pub fn iter_sorted(&self) -> IterSorted<'_, T> {
270		IterSorted(self.map.iter_sorted())
271	}
272
273	/// Turns this set into an iterator over its values, sorted according to
274	/// `T`'s implementation of [`Ord`].
275	pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
276		IntoIterSorted(self.map.into_iter_sorted())
277	}
278
279	/// Sorts the entries of the set by value.
280	///
281	/// The relative order of equal values is unchanged.
282	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	/// # Panics
294	///
295	/// Panics if `index` is out of bounds.
296	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
361/// An iterator over `(index, &value)` for every occurrence of a value in a
362/// [`BTreeIndexMultiSet`].
363///
364/// See [`BTreeIndexMultiSet::get_indexed`].
365pub 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
375/// An iterator over a reference to a value for every occurrence found in a
376/// [`BTreeIndexMultiSet`].
377///
378/// See [`BTreeIndexMultiSet::get`].
379pub 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
389/// An iterator over the occurrences removed by
390/// [`BTreeIndexMultiSet::shift_remove`].
391pub 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
407/// An iterator over the occurrences removed by
408/// [`BTreeIndexMultiSet::swap_remove`].
409pub 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
425/// An iterator over the values of a [`BTreeIndexMultiSet`], in insertion
426/// order.
427///
428/// Since the set's entries are exposed as a plain `&[T]` slice (see
429/// [`BTreeIndexMultiSet::as_slice`]), this is just [`std::slice::Iter`].
430pub 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
441/// An iterator over the values of a [`BTreeIndexMultiSet`], sorted
442/// according to `T`'s implementation of [`Ord`].
443pub 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
467/// An owning iterator over the values of a [`BTreeIndexMultiSet`], sorted
468/// according to `T`'s implementation of [`Ord`].
469pub 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
487/// An owning iterator over the values of a [`BTreeIndexMultiSet`], in
488/// insertion order.
489pub 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> {}