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#[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 pub fn new() -> Self {
58 Self {
59 map: BTreeIndexMap::new(),
60 }
61 }
62
63 pub fn singleton(value: T) -> Self
65 where
66 T: Ord,
67 {
68 Self {
69 map: BTreeIndexMap::singleton(value, ()),
70 }
71 }
72
73 pub fn clear(&mut self) {
77 self.map.clear();
78 }
79
80 pub fn is_empty(&self) -> bool {
82 self.map.is_empty()
83 }
84
85 pub fn len(&self) -> usize {
87 self.map.len()
88 }
89
90 pub fn as_slice(&self) -> &[T] {
93 entries_as_slice(self.map.as_entries())
94 }
95
96 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 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 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 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 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 pub fn insert(&mut self, value: T) -> bool
141 where
142 T: Ord,
143 {
144 self.insert_full(value).1
145 }
146
147 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 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 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 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 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 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 pub fn iter(&self) -> Iter<'_, T> {
217 self.as_slice().iter()
218 }
219
220 pub fn iter_sorted(&self) -> IterSorted<'_, T> {
223 IterSorted(self.map.iter_sorted())
224 }
225
226 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 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
304pub 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
319pub 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
351pub 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
377pub 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> {}