1use core::borrow::Borrow;
6use core::fmt;
7
8use kevy_hash::KevyHash;
9
10use crate::into_iter::IntoIter;
11use crate::iter::Iter;
12use crate::map::KevyMap;
13
14#[derive(Clone)]
31pub struct KevySet<K>(KevyMap<K, ()>);
32
33impl<K> KevySet<K> {
34 pub fn new() -> Self {
36 Self(KevyMap::new())
37 }
38
39 pub fn with_capacity(cap_hint: usize) -> Self {
41 Self(KevyMap::with_capacity(cap_hint))
42 }
43
44 #[inline]
46 pub fn len(&self) -> usize {
47 self.0.len()
48 }
49 #[inline]
51 pub fn is_empty(&self) -> bool {
52 self.0.is_empty()
53 }
54 #[inline]
56 pub fn capacity(&self) -> usize {
57 self.0.capacity()
58 }
59 pub fn clear(&mut self) {
61 self.0.clear();
62 }
63
64 pub fn iter(&self) -> SetIter<'_, K> {
66 SetIter(self.0.iter())
67 }
68
69 pub fn iter_from_slot(&self, start: usize) -> impl Iterator<Item = &K> {
80 let cap = self.0.capacity();
81 let start = if cap == 0 { 0 } else { start % cap };
82 self.0.iter_from_bucket(start).chain(self.0.iter().take(start)).map(|(k, ())| k)
83 }
84
85 pub fn as_map(&self) -> &KevyMap<K, ()> {
87 &self.0
88 }
89}
90
91impl<K: KevyHash + Eq> KevySet<K> {
92 pub fn insert(&mut self, key: K) -> bool {
95 self.0.insert(key, ()).is_none()
96 }
97}
98
99impl<K> KevySet<K> {
100 pub fn contains<Q>(&self, key: &Q) -> bool
102 where
103 K: Borrow<Q>,
104 Q: KevyHash + Eq + ?Sized,
105 {
106 self.0.contains_key(key)
107 }
108
109 pub fn remove<Q>(&mut self, key: &Q) -> bool
111 where
112 K: Borrow<Q>,
113 Q: KevyHash + Eq + ?Sized,
114 {
115 self.0.remove(key).is_some()
116 }
117}
118
119impl<K> Default for KevySet<K> {
120 fn default() -> Self {
121 Self::new()
122 }
123}
124
125impl<K: fmt::Debug> fmt::Debug for KevySet<K> {
126 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
127 f.debug_set().entries(self.iter()).finish()
128 }
129}
130
131#[derive(Debug)]
140pub struct SetIter<'a, K>(Iter<'a, K, ()>);
141
142#[derive(Debug)]
151pub struct SetIntoIter<K>(IntoIter<K, ()>);
152
153impl<K> Iterator for SetIntoIter<K> {
154 type Item = K;
155 fn next(&mut self) -> Option<K> {
156 self.0.next().map(|(k, ())| k)
157 }
158 fn size_hint(&self) -> (usize, Option<usize>) {
159 self.0.size_hint()
160 }
161}
162
163impl<K> ExactSizeIterator for SetIntoIter<K> {}
164
165impl<K> IntoIterator for KevySet<K> {
166 type Item = K;
167 type IntoIter = SetIntoIter<K>;
168 fn into_iter(self) -> SetIntoIter<K> {
169 SetIntoIter(self.0.into_iter())
170 }
171}
172
173impl<K: KevyHash + Eq> PartialEq for KevySet<K> {
181 fn eq(&self, other: &Self) -> bool {
182 self.0 == other.0
183 }
184}
185
186impl<K: KevyHash + Eq> Eq for KevySet<K> {}
187
188impl<'a, K> Iterator for SetIter<'a, K> {
189 type Item = &'a K;
190 fn next(&mut self) -> Option<Self::Item> {
191 self.0.next().map(|(k, ())| k)
192 }
193}
194
195impl<'a, K> IntoIterator for &'a KevySet<K> {
196 type Item = &'a K;
197 type IntoIter = SetIter<'a, K>;
198 fn into_iter(self) -> Self::IntoIter {
199 self.iter()
200 }
201}
202
203impl<K: KevyHash + Eq> FromIterator<K> for KevySet<K> {
204 fn from_iter<I: IntoIterator<Item = K>>(iter: I) -> Self {
205 let iter = iter.into_iter();
206 let mut s = match iter.size_hint() {
207 (lo, Some(hi)) if hi <= lo.saturating_mul(2) => Self::with_capacity(hi),
208 (lo, _) => Self::with_capacity(lo),
209 };
210 for k in iter {
211 s.insert(k);
212 }
213 s
214 }
215}
216
217impl<K: KevyHash + Eq> Extend<K> for KevySet<K> {
218 fn extend<I: IntoIterator<Item = K>>(&mut self, iter: I) {
219 for k in iter {
220 self.insert(k);
221 }
222 }
223}