1use core::fmt;
2use core::hash::{BuildHasher, Hash};
3use core::ops::{Deref, DerefMut, Index};
4
5pub use axhash_core::AxBuildHasher;
6pub use hashbrown::{HashMap as RawHashMap, HashSet as RawHashSet};
7
8pub struct AxHashMap<K, V, S = AxBuildHasher>(RawHashMap<K, V, S>);
10
11impl<K, V> AxHashMap<K, V, AxBuildHasher> {
12 #[inline]
17 pub fn new() -> Self {
18 Self(RawHashMap::with_hasher(AxBuildHasher::new()))
19 }
20
21 #[inline]
27 pub fn with_capacity(capacity: usize) -> Self {
28 Self(RawHashMap::with_capacity_and_hasher(
29 capacity,
30 AxBuildHasher::new(),
31 ))
32 }
33}
34
35impl<K, V, S: BuildHasher> AxHashMap<K, V, S> {
36 #[inline]
41 pub fn with_hasher(hasher: S) -> Self {
42 Self(RawHashMap::with_hasher(hasher))
43 }
44
45 #[inline]
48 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
49 Self(RawHashMap::with_capacity_and_hasher(capacity, hasher))
50 }
51
52 #[inline]
54 pub fn into_inner(self) -> RawHashMap<K, V, S> {
55 self.0
56 }
57}
58
59impl<K, V, S> Deref for AxHashMap<K, V, S> {
62 type Target = RawHashMap<K, V, S>;
63
64 #[inline]
65 fn deref(&self) -> &Self::Target {
66 &self.0
67 }
68}
69
70impl<K, V, S> DerefMut for AxHashMap<K, V, S> {
71 #[inline]
72 fn deref_mut(&mut self) -> &mut Self::Target {
73 &mut self.0
74 }
75}
76
77impl<K, V> Default for AxHashMap<K, V, AxBuildHasher> {
80 #[inline]
81 fn default() -> Self {
82 Self::new()
83 }
84}
85
86impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for AxHashMap<K, V, S> {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 self.0.fmt(f)
89 }
90}
91
92impl<K: Clone, V: Clone, S: Clone> Clone for AxHashMap<K, V, S> {
93 #[inline]
94 fn clone(&self) -> Self {
95 Self(self.0.clone())
96 }
97}
98
99impl<K: Hash + Eq, V: PartialEq, S: BuildHasher> PartialEq for AxHashMap<K, V, S> {
100 fn eq(&self, other: &Self) -> bool {
101 self.0 == other.0
102 }
103}
104
105impl<K: Hash + Eq, V: Eq, S: BuildHasher> Eq for AxHashMap<K, V, S> {}
106
107impl<K, Q, V, S> Index<&Q> for AxHashMap<K, V, S>
108where
109 K: Hash + Eq + core::borrow::Borrow<Q>,
110 Q: Hash + Eq + ?Sized,
111 S: BuildHasher,
112{
113 type Output = V;
114
115 #[inline]
116 fn index(&self, key: &Q) -> &Self::Output {
117 self.0.index(key)
118 }
119}
120
121impl<K: Hash + Eq, V> FromIterator<(K, V)> for AxHashMap<K, V, AxBuildHasher> {
124 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
125 let iter = iter.into_iter();
126 let (lower, _) = iter.size_hint();
127 let mut map = Self::with_capacity(lower);
128 map.extend(iter);
129 map
130 }
131}
132
133impl<K: Hash + Eq, V, S: BuildHasher> Extend<(K, V)> for AxHashMap<K, V, S> {
134 #[inline]
135 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
136 self.0.extend(iter);
137 }
138}
139
140impl<'a, K: Hash + Eq + Copy, V: Copy, S: BuildHasher> Extend<(&'a K, &'a V)>
141 for AxHashMap<K, V, S>
142{
143 #[inline]
144 fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
145 self.0.extend(iter);
146 }
147}
148
149impl<K, V, S> IntoIterator for AxHashMap<K, V, S> {
152 type Item = (K, V);
153 type IntoIter = hashbrown::hash_map::IntoIter<K, V>;
154
155 #[inline]
156 fn into_iter(self) -> Self::IntoIter {
157 self.0.into_iter()
158 }
159}
160
161impl<'a, K, V, S> IntoIterator for &'a AxHashMap<K, V, S> {
162 type Item = (&'a K, &'a V);
163 type IntoIter = hashbrown::hash_map::Iter<'a, K, V>;
164
165 #[inline]
166 fn into_iter(self) -> Self::IntoIter {
167 self.0.iter()
168 }
169}
170
171impl<'a, K, V, S> IntoIterator for &'a mut AxHashMap<K, V, S> {
172 type Item = (&'a K, &'a mut V);
173 type IntoIter = hashbrown::hash_map::IterMut<'a, K, V>;
174
175 #[inline]
176 fn into_iter(self) -> Self::IntoIter {
177 self.0.iter_mut()
178 }
179}
180
181impl<K, V, S> From<RawHashMap<K, V, S>> for AxHashMap<K, V, S> {
184 #[inline]
185 fn from(inner: RawHashMap<K, V, S>) -> Self {
186 Self(inner)
187 }
188}
189
190impl<K, V, S> From<AxHashMap<K, V, S>> for RawHashMap<K, V, S> {
191 #[inline]
192 fn from(wrapper: AxHashMap<K, V, S>) -> Self {
193 wrapper.0
194 }
195}
196
197pub struct AxHashSet<T, S = AxBuildHasher>(RawHashSet<T, S>);
199
200impl<T> AxHashSet<T, AxBuildHasher> {
201 #[inline]
203 pub fn new() -> Self {
204 Self(RawHashSet::with_hasher(AxBuildHasher::new()))
205 }
206
207 #[inline]
210 pub fn with_capacity(capacity: usize) -> Self {
211 Self(RawHashSet::with_capacity_and_hasher(
212 capacity,
213 AxBuildHasher::new(),
214 ))
215 }
216}
217
218impl<T, S: BuildHasher> AxHashSet<T, S> {
219 #[inline]
221 pub fn with_hasher(hasher: S) -> Self {
222 Self(RawHashSet::with_hasher(hasher))
223 }
224
225 #[inline]
228 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
229 Self(RawHashSet::with_capacity_and_hasher(capacity, hasher))
230 }
231
232 #[inline]
234 pub fn into_inner(self) -> RawHashSet<T, S> {
235 self.0
236 }
237}
238
239impl<T, S> Deref for AxHashSet<T, S> {
242 type Target = RawHashSet<T, S>;
243
244 #[inline]
245 fn deref(&self) -> &Self::Target {
246 &self.0
247 }
248}
249
250impl<T, S> DerefMut for AxHashSet<T, S> {
251 #[inline]
252 fn deref_mut(&mut self) -> &mut Self::Target {
253 &mut self.0
254 }
255}
256
257impl<T> Default for AxHashSet<T, AxBuildHasher> {
260 #[inline]
261 fn default() -> Self {
262 Self::new()
263 }
264}
265
266impl<T: fmt::Debug, S> fmt::Debug for AxHashSet<T, S> {
267 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
268 self.0.fmt(f)
269 }
270}
271
272impl<T: Clone, S: Clone> Clone for AxHashSet<T, S> {
273 #[inline]
274 fn clone(&self) -> Self {
275 Self(self.0.clone())
276 }
277}
278
279impl<T: Hash + Eq, S: BuildHasher> PartialEq for AxHashSet<T, S> {
280 fn eq(&self, other: &Self) -> bool {
281 self.0 == other.0
282 }
283}
284
285impl<T: Hash + Eq, S: BuildHasher> Eq for AxHashSet<T, S> {}
286
287impl<T: Hash + Eq> FromIterator<T> for AxHashSet<T, AxBuildHasher> {
290 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
291 let iter = iter.into_iter();
292 let (lower, _) = iter.size_hint();
293 let mut set = Self::with_capacity(lower);
294 set.extend(iter);
295 set
296 }
297}
298
299impl<T: Hash + Eq, S: BuildHasher> Extend<T> for AxHashSet<T, S> {
300 #[inline]
301 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
302 self.0.extend(iter);
303 }
304}
305
306impl<'a, T: Hash + Eq + Copy, S: BuildHasher> Extend<&'a T> for AxHashSet<T, S> {
307 #[inline]
308 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
309 self.0.extend(iter);
310 }
311}
312
313impl<T, S> IntoIterator for AxHashSet<T, S> {
316 type Item = T;
317 type IntoIter = hashbrown::hash_set::IntoIter<T>;
318
319 #[inline]
320 fn into_iter(self) -> Self::IntoIter {
321 self.0.into_iter()
322 }
323}
324
325impl<'a, T, S> IntoIterator for &'a AxHashSet<T, S> {
326 type Item = &'a T;
327 type IntoIter = hashbrown::hash_set::Iter<'a, T>;
328
329 #[inline]
330 fn into_iter(self) -> Self::IntoIter {
331 self.0.iter()
332 }
333}
334
335impl<T, S> From<RawHashSet<T, S>> for AxHashSet<T, S> {
338 #[inline]
339 fn from(inner: RawHashSet<T, S>) -> Self {
340 Self(inner)
341 }
342}
343
344impl<T, S> From<AxHashSet<T, S>> for RawHashSet<T, S> {
345 #[inline]
346 fn from(wrapper: AxHashSet<T, S>) -> Self {
347 wrapper.0
348 }
349}
350
351#[cfg(test)]
354mod tests {
355 use super::*;
356
357 #[test]
358 fn map_basic_operations() {
359 let mut map: AxHashMap<&str, u32> = AxHashMap::new();
360 assert!(map.is_empty());
361
362 map.insert("one", 1);
363 map.insert("two", 2);
364 map.insert("three", 3);
365
366 assert_eq!(map.len(), 3);
367 assert_eq!(map["one"], 1);
368 assert_eq!(map.get("two"), Some(&2));
369 assert_eq!(map.get("missing"), None);
370
371 map.remove("two");
372 assert_eq!(map.len(), 2);
373 }
374
375 #[test]
376 fn map_with_capacity() {
377 let map: AxHashMap<u32, u32> = AxHashMap::with_capacity(128);
378 assert!(map.capacity() >= 128);
379 }
380
381 #[test]
382 fn map_default() {
383 let map: AxHashMap<u64, u64> = AxHashMap::default();
384 assert!(map.is_empty());
385 }
386
387 #[test]
388 fn map_from_iterator() {
389 let pairs = vec![("a", 1u32), ("b", 2), ("c", 3)];
390 let map: AxHashMap<&str, u32> = pairs.into_iter().collect();
391 assert_eq!(map.len(), 3);
392 assert_eq!(map["b"], 2);
393 }
394
395 #[test]
396 fn map_extend() {
397 let mut map: AxHashMap<u32, u32> = AxHashMap::new();
398 map.extend([(1, 10), (2, 20)]);
399 map.extend([(3, 30)]);
400 assert_eq!(map.len(), 3);
401 assert_eq!(map[&2], 20);
402 }
403
404 #[test]
405 fn map_iter() {
406 let map: AxHashMap<u32, u32> = [(1, 10), (2, 20)].into_iter().collect();
407 let mut sum = 0u32;
408 for (_, v) in &map {
409 sum += v;
410 }
411 assert_eq!(sum, 30);
412 }
413
414 #[test]
415 fn map_into_inner_roundtrip() {
416 let mut map: AxHashMap<&str, i32> = AxHashMap::new();
417 map.insert("x", 99);
418 let raw: RawHashMap<&str, i32, AxBuildHasher> = map.into_inner();
419 assert_eq!(raw["x"], 99);
420 let wrapped: AxHashMap<&str, i32> = raw.into();
421 assert_eq!(wrapped["x"], 99);
422 }
423
424 #[test]
425 fn map_seeded_hasher() {
426 let hasher = AxBuildHasher::with_seed(0x1234_5678_9abc_def0);
427 let mut map: AxHashMap<&str, u32> = AxHashMap::with_hasher(hasher);
428 map.insert("seeded", 7);
429 assert_eq!(map["seeded"], 7);
430 }
431
432 #[test]
433 fn set_basic_operations() {
434 let mut set: AxHashSet<u32> = AxHashSet::new();
435 assert!(set.is_empty());
436
437 set.insert(1);
438 set.insert(2);
439 set.insert(2); set.insert(3);
441
442 assert_eq!(set.len(), 3);
443 assert!(set.contains(&1));
444 assert!(!set.contains(&99));
445
446 set.remove(&2);
447 assert_eq!(set.len(), 2);
448 }
449
450 #[test]
451 fn set_with_capacity() {
452 let set: AxHashSet<u64> = AxHashSet::with_capacity(64);
453 assert!(set.capacity() >= 64);
454 }
455
456 #[test]
457 fn set_default() {
458 let set: AxHashSet<u64> = AxHashSet::default();
459 assert!(set.is_empty());
460 }
461
462 #[test]
463 fn set_from_iterator() {
464 let set: AxHashSet<u32> = [1u32, 2, 3, 2, 1].into_iter().collect();
465 assert_eq!(set.len(), 3);
466 }
467
468 #[test]
469 fn set_extend() {
470 let mut set: AxHashSet<u32> = AxHashSet::new();
471 set.extend([1u32, 2, 3]);
472 set.extend([3u32, 4, 5]);
473 assert_eq!(set.len(), 5);
474 }
475
476 #[test]
477 fn set_set_operations() {
478 let a: AxHashSet<u32> = [1, 2, 3].into_iter().collect();
479 let b: AxHashSet<u32> = [2, 3, 4].into_iter().collect();
480
481 let union: AxHashSet<u32> = a.union(&b).copied().collect();
483 assert_eq!(union.len(), 4);
484
485 let inter: AxHashSet<u32> = a.intersection(&b).copied().collect();
486 assert_eq!(inter.len(), 2);
487 }
488
489 #[test]
490 fn set_into_inner_roundtrip() {
491 let mut set: AxHashSet<i32> = AxHashSet::new();
492 set.insert(42);
493 let raw: RawHashSet<i32, AxBuildHasher> = set.into_inner();
494 assert!(raw.contains(&42));
495 let wrapped: AxHashSet<i32> = raw.into();
496 assert!(wrapped.contains(&42));
497 }
498}