btree_plus_store/
set.rs

1use crate::{BTreeMap, BTreeStore};
2use std::borrow::Borrow;
3use std::fmt::{Debug, Formatter};
4use std::hash::Hash;
5use std::ops::RangeBounds;
6
7/// A b-tree set.
8///
9/// See [std::collections::BTreeSet] for more info.
10// TODO: impl Clone
11#[derive(PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct BTreeSet<'store, T>(BTreeMap<'store, T, ()>);
13
14impl<'store, T> BTreeSet<'store, T> {
15    /// Creates an empty set.
16    #[inline]
17    pub fn new_in(store: &'store BTreeStore<T, ()>) -> Self {
18        Self(BTreeMap::new_in(store))
19    }
20
21    /// Returns the number of elements in the set.
22    #[inline]
23    pub fn len(&self) -> usize {
24        self.0.len()
25    }
26
27    /// Returns `true` if the set contains no elements.
28    #[inline]
29    pub fn is_empty(&self) -> bool {
30        self.0.is_empty()
31    }
32
33    /// Clears the set, removing all values.
34    #[inline]
35    pub fn clear(&mut self) {
36        self.0.clear()
37    }
38
39    /// The first value in the set, or `None` if empty.
40    #[inline]
41    pub fn first(&self) -> Option<&T> {
42        self.0.first_key_value().map(|(k, &())| k)
43    }
44
45    /// The last value in the set, or `None` if empty.
46    #[inline]
47    pub fn last(&self) -> Option<&T> {
48        self.0.last_key_value().map(|(k, &())| k)
49    }
50
51    /// Returns `true` if the set contains a value.
52    #[inline]
53    pub fn contains<U: Ord>(&self, value: &U) -> bool
54    where
55        T: Borrow<U>,
56    {
57        self.0.contains_key(value)
58    }
59
60    /// Returns a reference to the equivalent value in the set, if any.
61    ///
62    /// This is (only) useful when `U` is a different type than `T`.
63    #[inline]
64    pub fn get<U: Ord>(&self, value: &U) -> Option<&T>
65    where
66        T: Borrow<U>,
67    {
68        self.0.get_key(value)
69    }
70
71    /// Inserts a value into the set. Returns `true` if the value was not already present.
72    #[inline]
73    pub fn insert(&mut self, value: T) -> bool
74    where
75        T: Clone + Ord,
76    {
77        self.0.insert(value, ()).is_none()
78    }
79
80    /// Removes a value from the set. Returns `true` if the value was present.
81    #[inline]
82    pub fn remove<U: Ord>(&mut self, value: &U) -> bool
83    where
84        T: Borrow<U> + Clone,
85    {
86        self.0.remove(value).is_some()
87    }
88
89    /// Removes the first value from the set.
90    #[inline]
91    pub fn pop_first(&mut self) -> Option<T>
92    where
93        T: Clone,
94    {
95        self.0.pop_first().map(|(k, ())| k)
96    }
97
98    /// Removes the last value from the set.
99    #[inline]
100    pub fn pop_last(&mut self) -> Option<T>
101    where
102        T: Clone,
103    {
104        self.0.pop_last().map(|(k, ())| k)
105    }
106
107    /// Validates the set, *panic*ing if it is invalid. Specifically, we check that the number of
108    /// entries in each node is within the b-tree invariant bounds, and that the elements are in
109    /// order.
110    ///
111    /// Ideally, this should always be a no-op.
112    #[inline]
113    pub fn validate(&self)
114    where
115        T: Debug + Ord,
116    {
117        self.0.validate()
118    }
119
120    /// Prints the b-tree in ascii
121    #[inline]
122    pub fn print(&self, f: &mut Formatter<'_>) -> std::fmt::Result
123    where
124        T: Debug,
125    {
126        self.0.print(f)
127    }
128
129    /// Returns an iterator over the set.
130    #[inline]
131    pub fn iter(&self) -> Iter<'_, T> {
132        Iter(self.0.iter())
133    }
134
135    /// Returns an iterator over the set within the given bounds
136    #[inline]
137    pub fn range<U: Ord>(&self, bounds: impl RangeBounds<U>) -> Range<T>
138    where
139        T: Borrow<U>,
140    {
141        Range(self.0.range(bounds))
142    }
143}
144
145// region common trait impls
146impl<'store, T: Debug> Debug for BTreeSet<'store, T> {
147    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
148        self.print(f)
149    }
150}
151// endregion
152
153// region iterators
154impl<'store, T> IntoIterator for BTreeSet<'store, T> {
155    type Item = T;
156    type IntoIter = IntoIter<'store, T>;
157
158    #[inline]
159    fn into_iter(self) -> Self::IntoIter {
160        IntoIter(self.0.into_iter())
161    }
162}
163
164//noinspection DuplicatedCode
165impl<'a, 'store: 'a, T> IntoIterator for &'a BTreeSet<'store, T> {
166    type Item = &'a T;
167    type IntoIter = Iter<'a, T>;
168
169    #[inline]
170    fn into_iter(self) -> Self::IntoIter {
171        self.iter()
172    }
173}
174
175pub struct Iter<'a, T>(crate::map::Iter<'a, T, ()>);
176
177impl<'a, T> Iterator for Iter<'a, T> {
178    type Item = &'a T;
179
180    #[inline]
181    fn next(&mut self) -> Option<Self::Item> {
182        self.0.next().map(|(k, &())| k)
183    }
184
185    #[inline]
186    fn size_hint(&self) -> (usize, Option<usize>) {
187        self.0.size_hint()
188    }
189}
190
191pub struct IntoIter<'store, T>(crate::map::IntoIter<'store, T, ()>);
192
193impl<'store, T> Iterator for IntoIter<'store, T> {
194    type Item = T;
195
196    #[inline]
197    fn next(&mut self) -> Option<Self::Item> {
198        self.0.next().map(|(k, ())| k)
199    }
200
201    #[inline]
202    fn size_hint(&self) -> (usize, Option<usize>) {
203        self.0.size_hint()
204    }
205}
206
207pub struct Range<'a, T>(crate::map::Range<'a, T, ()>);
208
209impl<'a, T> Iterator for Range<'a, T> {
210    type Item = &'a T;
211
212    #[inline]
213    fn next(&mut self) -> Option<Self::Item> {
214        self.0.next().map(|(k, &())| k)
215    }
216
217    #[inline]
218    fn size_hint(&self) -> (usize, Option<usize>) {
219        self.0.size_hint()
220    }
221}
222// endregion
223
224#[cfg(feature = "copyable")]
225impl<'store, T> crate::copyable::sealed::BTree<'store, T, ()> for BTreeSet<'store, T> {
226    #[inline]
227    fn assert_store(&self, store: &BTreeStore<T, ()>) {
228        self.0.assert_store(store)
229    }
230
231    #[inline]
232    fn nodes(&self) -> crate::copyable::sealed::NodeIter<'store, T, ()> {
233        self.0.nodes()
234    }
235}