ckb_util/
linked_hash_set.rs1use linked_hash_map::{self, Keys, LinkedHashMap};
4use std::collections::hash_map::DefaultHasher;
5use std::hash::{BuildHasher, BuildHasherDefault, Hash};
6use std::iter::Extend;
7
8type DefaultBuildHasher = BuildHasherDefault<DefaultHasher>;
9
10pub struct LinkedHashSet<T, S = DefaultBuildHasher> {
26 map: LinkedHashMap<T, (), S>,
27}
28
29pub struct Iter<'a, K: 'a> {
30 iter: Keys<'a, K, ()>,
31}
32
33impl<K> Clone for Iter<'_, K> {
34 fn clone(&self) -> Self {
35 Iter {
36 iter: self.iter.clone(),
37 }
38 }
39}
40
41impl<'a, K> Iterator for Iter<'a, K>
42where
43 K: Eq + Hash,
44{
45 type Item = &'a K;
46
47 fn next(&mut self) -> Option<&'a K> {
48 self.iter.next()
49 }
50 fn size_hint(&self) -> (usize, Option<usize>) {
51 self.iter.size_hint()
52 }
53}
54pub struct Difference<'a, T: 'a, S: 'a> {
55 iter: Iter<'a, T>,
57 other: &'a LinkedHashSet<T, S>,
59}
60
61impl<T, S> Clone for Difference<'_, T, S> {
62 fn clone(&self) -> Self {
63 Difference {
64 iter: self.iter.clone(),
65 ..*self
66 }
67 }
68}
69
70impl<'a, T, S> Iterator for Difference<'a, T, S>
71where
72 T: Eq + Hash,
73 S: BuildHasher,
74{
75 type Item = &'a T;
76
77 fn next(&mut self) -> Option<&'a T> {
78 loop {
79 let elt = self.iter.next()?;
80 if !self.other.contains(elt) {
81 return Some(elt);
82 }
83 }
84 }
85
86 fn size_hint(&self) -> (usize, Option<usize>) {
87 let (_, upper) = self.iter.size_hint();
88 (0, upper)
89 }
90}
91
92impl<T: Hash + Eq> LinkedHashSet<T, DefaultBuildHasher> {
93 pub fn new() -> LinkedHashSet<T, DefaultBuildHasher> {
102 LinkedHashSet {
103 map: LinkedHashMap::default(),
104 }
105 }
106
107 pub fn with_capacity(capacity: usize) -> LinkedHashSet<T, DefaultBuildHasher> {
116 LinkedHashSet {
117 map: LinkedHashMap::with_capacity_and_hasher(capacity, Default::default()),
118 }
119 }
120}
121
122impl<T, S> LinkedHashSet<T, S>
123where
124 T: Eq + Hash,
125 S: BuildHasher,
126{
127 pub fn contains(&self, value: &T) -> bool {
140 self.map.contains_key(value)
141 }
142
143 pub fn capacity(&self) -> usize {
145 self.map.capacity()
146 }
147
148 pub fn len(&self) -> usize {
150 self.map.len()
151 }
152
153 pub fn is_empty(&self) -> bool {
155 self.map.is_empty()
156 }
157
158 pub fn insert(&mut self, value: T) -> bool {
164 self.map.insert(value, ()).is_none()
165 }
166
167 pub fn iter(&self) -> Iter<T> {
171 Iter {
172 iter: self.map.keys(),
173 }
174 }
175
176 pub fn difference<'a>(&'a self, other: &'a LinkedHashSet<T, S>) -> Difference<'a, T, S> {
178 Difference {
179 iter: self.iter(),
180 other,
181 }
182 }
183
184 pub fn clear(&mut self) {
186 self.map.clear();
187 }
188}
189
190impl<T: Hash + Eq> Default for LinkedHashSet<T, DefaultBuildHasher> {
191 fn default() -> LinkedHashSet<T, DefaultBuildHasher> {
193 LinkedHashSet {
194 map: LinkedHashMap::default(),
195 }
196 }
197}
198
199impl<T, S> Extend<T> for LinkedHashSet<T, S>
200where
201 T: Eq + Hash,
202 S: BuildHasher,
203{
204 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
205 self.map.extend(iter.into_iter().map(|k| (k, ())));
206 }
207}
208
209impl<'a, T, S> IntoIterator for &'a LinkedHashSet<T, S>
210where
211 T: Eq + Hash,
212 S: BuildHasher,
213{
214 type Item = &'a T;
215 type IntoIter = Iter<'a, T>;
216
217 fn into_iter(self) -> Iter<'a, T> {
218 self.iter()
219 }
220}
221
222impl<T, S> IntoIterator for LinkedHashSet<T, S>
223where
224 T: Eq + Hash,
225 S: BuildHasher,
226{
227 type Item = T;
228 type IntoIter = IntoIter<T>;
229
230 fn into_iter(self) -> IntoIter<T> {
231 IntoIter {
232 iter: self.map.into_iter(),
233 }
234 }
235}
236
237pub struct IntoIter<K> {
238 iter: linked_hash_map::IntoIter<K, ()>,
239}
240
241impl<K> Iterator for IntoIter<K> {
242 type Item = K;
243
244 fn next(&mut self) -> Option<K> {
245 self.iter.next().map(|(k, _)| k)
246 }
247 fn size_hint(&self) -> (usize, Option<usize>) {
248 self.iter.size_hint()
249 }
250}
251
252impl<K> ExactSizeIterator for IntoIter<K> {
253 fn len(&self) -> usize {
254 self.iter.len()
255 }
256}