Skip to main content

btree_indexmap/
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	map::{self, BTreeIndexMap},
12	util::entries_as_slice,
13};
14
15/// BTree-based index set.
16///
17/// This is a thin wrapper around [`BTreeIndexMap<T, ()>`](BTreeIndexMap)
18/// providing a set-like API: every value is stored at most once, values keep
19/// a stable index until they (or an earlier value) are removed, and values
20/// can be iterated either in insertion order or in sorted order.
21///
22/// # Example
23///
24/// ```
25/// use btree_indexmap::BTreeIndexSet;
26///
27/// let mut set = BTreeIndexSet::new();
28///
29/// // Values are stored in insertion order and assigned a stable index.
30/// assert!(set.insert("banana"));
31/// assert!(set.insert("apple"));
32/// assert!(!set.insert("banana")); // already present
33///
34/// // O(1) access by index (insertion order).
35/// assert_eq!(set.as_slice(), ["banana", "apple"]);
36///
37/// // O(log n) lookup, returning the stable index alongside the value.
38/// assert_eq!(set.get_full("apple"), Some((1, &"apple")));
39///
40/// // Iterate in sorted order.
41/// let sorted: Vec<_> = set.iter_sorted().copied().collect();
42/// assert_eq!(sorted, ["apple", "banana"]);
43/// ```
44#[derive(Clone)]
45pub struct BTreeIndexSet<T> {
46	map: BTreeIndexMap<T, ()>,
47}
48
49impl<T> Default for BTreeIndexSet<T> {
50	fn default() -> Self {
51		Self::new()
52	}
53}
54
55impl<T> BTreeIndexSet<T> {
56	/// Creates a new, empty set.
57	pub fn new() -> Self {
58		Self {
59			map: BTreeIndexMap::new(),
60		}
61	}
62
63	/// Creates a new set containing the single `value`.
64	pub fn singleton(value: T) -> Self
65	where
66		T: Ord,
67	{
68		Self {
69			map: BTreeIndexMap::singleton(value, ()),
70		}
71	}
72
73	/// Removes all values from the set.
74	///
75	/// This keeps the capacity allocated for the values.
76	pub fn clear(&mut self) {
77		self.map.clear();
78	}
79
80	/// Returns `true` if the set contains no values.
81	pub fn is_empty(&self) -> bool {
82		self.map.is_empty()
83	}
84
85	/// Returns the number of values in the set.
86	pub fn len(&self) -> usize {
87		self.map.len()
88	}
89
90	/// Returns the values of the set as a slice, in insertion (index)
91	/// order.
92	pub fn as_slice(&self) -> &[T] {
93		entries_as_slice(self.map.as_entries())
94	}
95
96	/// Returns the index and a reference to the value equal to `value`, if
97	/// any.
98	pub fn get_full<Q>(&self, value: &Q) -> Option<(usize, &T)>
99	where
100		Q: ?Sized + Comparable<T>,
101	{
102		self.map.get_full(value).map(|(i, t, ())| (i, t))
103	}
104
105	/// Returns the index of `value` in the set, if any.
106	pub fn get_index_of<Q>(&self, value: &Q) -> Option<usize>
107	where
108		Q: ?Sized + Comparable<T>,
109	{
110		self.get_full(value).map(|(i, _)| i)
111	}
112
113	/// Returns a reference to the value equal to `value`, if any.
114	pub fn get<Q>(&self, value: &Q) -> Option<&T>
115	where
116		Q: ?Sized + Comparable<T>,
117	{
118		self.map.get_entry(value).map(|(t, ())| t)
119	}
120
121	/// Returns `true` if the set contains `value`.
122	pub fn contains<Q>(&self, value: &Q) -> bool
123	where
124		Q: ?Sized + Comparable<T>,
125	{
126		self.map.get(value).is_some()
127	}
128
129	/// Inserts `value` in the set, returning its index and whether it was
130	/// newly inserted (`true`) or already present (`false`).
131	pub fn insert_full(&mut self, value: T) -> (usize, bool)
132	where
133		T: Ord,
134	{
135		let (i, old) = self.map.insert_full(value, ());
136		(i, old.is_none())
137	}
138
139	/// Inserts `value` in the set, returning whether it was newly inserted.
140	pub fn insert(&mut self, value: T) -> bool
141	where
142		T: Ord,
143	{
144		self.insert_full(value).1
145	}
146
147	/// Removes `value` from the set, returning its former index and the
148	/// value itself, if it was present.
149	///
150	/// Shifts every following value one index down.
151	pub fn shift_remove_full<Q>(&mut self, value: &Q) -> Option<(usize, T)>
152	where
153		Q: ?Sized + Comparable<T>,
154	{
155		self.map.shift_remove_full(value).map(|(i, t, ())| (i, t))
156	}
157
158	/// Removes `value` from the set, returning the removed value, if any.
159	///
160	/// Shifts every following value one index down.
161	pub fn shift_take<Q>(&mut self, value: &Q) -> Option<T>
162	where
163		Q: ?Sized + Comparable<T>,
164	{
165		self.shift_remove_full(value).map(|(_, t)| t)
166	}
167
168	/// Removes `value` from the set, returning whether the value was
169	/// present.
170	///
171	/// Shifts every following value one index down.
172	pub fn shift_remove<Q>(&mut self, value: &Q) -> bool
173	where
174		Q: ?Sized + Comparable<T>,
175	{
176		self.map.shift_remove(value).is_some()
177	}
178
179	/// Removes `value` from the set, returning its former index and the
180	/// value itself, if it was present.
181	///
182	/// Moves the last value into the removed slot.
183	pub fn swap_remove_full<Q>(&mut self, value: &Q) -> Option<(usize, T)>
184	where
185		Q: ?Sized + Comparable<T>,
186		T: Ord,
187	{
188		self.map.swap_remove_full(value).map(|(i, t, ())| (i, t))
189	}
190
191	/// Removes `value` from the set, returning the removed value, if any.
192	///
193	/// Moves the last value into its place.
194	pub fn swap_take<Q>(&mut self, value: &Q) -> Option<T>
195	where
196		Q: ?Sized + Comparable<T>,
197		T: Ord,
198	{
199		self.swap_remove_full(value).map(|(_, t)| t)
200	}
201
202	/// Removes `value` from the set, returning whether the value was
203	/// present.
204	///
205	/// Moves the last value into its place.
206	pub fn swap_remove<Q>(&mut self, value: &Q) -> bool
207	where
208		Q: ?Sized + Comparable<T>,
209		T: Ord,
210	{
211		self.map.swap_remove(value).is_some()
212	}
213
214	/// Returns an iterator over the values of the set, in insertion
215	/// (index) order.
216	pub fn iter(&self) -> Iter<'_, T> {
217		self.as_slice().iter()
218	}
219
220	/// Returns an iterator over the values of the set, sorted according to
221	/// `T`'s implementation of [`Ord`].
222	pub fn iter_sorted(&self) -> IterSorted<'_, T> {
223		IterSorted(self.map.iter_sorted())
224	}
225
226	/// Turns this set into an iterator over its values, sorted according to
227	/// `T`'s implementation of [`Ord`].
228	pub fn into_iter_sorted(self) -> IntoIterSorted<T> {
229		IntoIterSorted(self.map.into_iter_sorted())
230	}
231}
232
233impl<T> Index<usize> for BTreeIndexSet<T> {
234	type Output = T;
235
236	/// # Panics
237	///
238	/// Panics if `index` is out of bounds.
239	fn index(&self, index: usize) -> &Self::Output {
240		&self.as_slice()[index]
241	}
242}
243
244impl<T> IntoIterator for BTreeIndexSet<T> {
245	type IntoIter = IntoIter<T>;
246	type Item = T;
247
248	fn into_iter(self) -> Self::IntoIter {
249		IntoIter(self.map.into_iter())
250	}
251}
252
253impl<T: PartialEq> PartialEq for BTreeIndexSet<T> {
254	fn eq(&self, other: &Self) -> bool {
255		self.iter_sorted().eq(other.iter_sorted())
256	}
257}
258
259impl<T: Eq> Eq for BTreeIndexSet<T> {}
260
261impl<T: PartialOrd> PartialOrd for BTreeIndexSet<T> {
262	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
263		self.iter_sorted().partial_cmp(other.iter_sorted())
264	}
265}
266
267impl<T: Ord> Ord for BTreeIndexSet<T> {
268	fn cmp(&self, other: &Self) -> Ordering {
269		self.iter_sorted().cmp(other.iter_sorted())
270	}
271}
272
273impl<T: Hash> Hash for BTreeIndexSet<T> {
274	fn hash<H: Hasher>(&self, state: &mut H) {
275		state.write_usize(self.len());
276		for item in self.iter_sorted() {
277			item.hash(state);
278		}
279	}
280}
281
282impl<T: fmt::Debug> fmt::Debug for BTreeIndexSet<T> {
283	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284		f.debug_set().entries(self.iter()).finish()
285	}
286}
287
288impl<T: Ord> Extend<T> for BTreeIndexSet<T> {
289	fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
290		for value in iter {
291			self.insert(value);
292		}
293	}
294}
295
296impl<T: Ord> FromIterator<T> for BTreeIndexSet<T> {
297	fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
298		let mut result = Self::new();
299		result.extend(iter);
300		result
301	}
302}
303
304/// An iterator over the values of a [`BTreeIndexSet`], in insertion order.
305///
306/// Since the set's entries are exposed as a plain `&[T]` slice (see
307/// [`BTreeIndexSet::as_slice`]), this is just [`std::slice::Iter`].
308pub type Iter<'a, T> = std::slice::Iter<'a, T>;
309
310impl<'a, T> IntoIterator for &'a BTreeIndexSet<T> {
311	type IntoIter = Iter<'a, T>;
312	type Item = &'a T;
313
314	fn into_iter(self) -> Self::IntoIter {
315		self.iter()
316	}
317}
318
319/// An iterator over the values of a [`BTreeIndexSet`], sorted according to
320/// `T`'s implementation of [`Ord`].
321pub struct IterSorted<'a, T>(map::IterSorted<'a, T, ()>);
322
323impl<T> Clone for IterSorted<'_, T> {
324	fn clone(&self) -> Self {
325		Self(self.0.clone())
326	}
327}
328
329impl<'a, T> Iterator for IterSorted<'a, T> {
330	type Item = &'a T;
331
332	fn size_hint(&self) -> (usize, Option<usize>) {
333		self.0.size_hint()
334	}
335
336	fn next(&mut self) -> Option<Self::Item> {
337		self.0.next().map(|(t, ())| t)
338	}
339}
340
341impl<T> DoubleEndedIterator for IterSorted<'_, T> {
342	fn next_back(&mut self) -> Option<Self::Item> {
343		self.0.next_back().map(|(t, ())| t)
344	}
345}
346
347impl<T> ExactSizeIterator for IterSorted<'_, T> {}
348
349impl<T> FusedIterator for IterSorted<'_, T> {}
350
351/// An owning iterator over the values of a [`BTreeIndexSet`], sorted
352/// according to `T`'s implementation of [`Ord`].
353pub struct IntoIterSorted<T>(map::IntoIterSorted<T, ()>);
354
355impl<T> Iterator for IntoIterSorted<T> {
356	type Item = T;
357
358	fn size_hint(&self) -> (usize, Option<usize>) {
359		self.0.size_hint()
360	}
361
362	fn next(&mut self) -> Option<Self::Item> {
363		self.0.next().map(|(t, ())| t)
364	}
365}
366
367impl<T> DoubleEndedIterator for IntoIterSorted<T> {
368	fn next_back(&mut self) -> Option<Self::Item> {
369		self.0.next_back().map(|(t, ())| t)
370	}
371}
372
373impl<T> ExactSizeIterator for IntoIterSorted<T> {}
374
375impl<T> FusedIterator for IntoIterSorted<T> {}
376
377/// An owning iterator over the values of a [`BTreeIndexSet`], in insertion
378/// order.
379pub struct IntoIter<T>(map::IntoIter<T, ()>);
380
381impl<T> Iterator for IntoIter<T> {
382	type Item = T;
383
384	fn size_hint(&self) -> (usize, Option<usize>) {
385		self.0.size_hint()
386	}
387
388	fn next(&mut self) -> Option<Self::Item> {
389		self.0.next().map(|(t, ())| t)
390	}
391}
392
393impl<T> DoubleEndedIterator for IntoIter<T> {
394	fn next_back(&mut self) -> Option<Self::Item> {
395		self.0.next_back().map(|(t, ())| t)
396	}
397}
398
399impl<T> ExactSizeIterator for IntoIter<T> {}
400
401impl<T> FusedIterator for IntoIter<T> {}