1use core::fmt;
2use core::hash::{BuildHasher, BuildHasherDefault, Hash};
3use core::ops::{Deref, DerefMut, Index};
4
5pub use axhash_core::{AxBuildHasher, AxHasher};
6pub use hashbrown::{HashMap as RawHashMap, HashSet as RawHashSet};
7
8pub type HashMap<K, V> = RawHashMap<K, V, BuildHasherDefault<AxHasher>>;
19
20pub type HashSet<T> = RawHashSet<T, BuildHasherDefault<AxHasher>>;
24
25pub struct AxHashMap<K, V, S = BuildHasherDefault<AxHasher>>(RawHashMap<K, V, S>);
30
31impl<K, V> AxHashMap<K, V, BuildHasherDefault<AxHasher>> {
32 #[inline]
37 pub fn new() -> Self {
38 Self(RawHashMap::with_hasher(BuildHasherDefault::default()))
39 }
40
41 #[inline]
47 pub fn with_capacity(capacity: usize) -> Self {
48 Self(RawHashMap::with_capacity_and_hasher(
49 capacity,
50 BuildHasherDefault::default(),
51 ))
52 }
53}
54
55impl<K, V, S: BuildHasher> AxHashMap<K, V, S> {
56 #[inline]
61 pub fn with_hasher(hasher: S) -> Self {
62 Self(RawHashMap::with_hasher(hasher))
63 }
64
65 #[inline]
68 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
69 Self(RawHashMap::with_capacity_and_hasher(capacity, hasher))
70 }
71
72 #[inline]
74 pub fn into_inner(self) -> RawHashMap<K, V, S> {
75 self.0
76 }
77}
78
79impl<K, V, S> Deref for AxHashMap<K, V, S> {
82 type Target = RawHashMap<K, V, S>;
83
84 #[inline]
85 fn deref(&self) -> &Self::Target {
86 &self.0
87 }
88}
89
90impl<K, V, S> DerefMut for AxHashMap<K, V, S> {
91 #[inline]
92 fn deref_mut(&mut self) -> &mut Self::Target {
93 &mut self.0
94 }
95}
96
97impl<K, V> Default for AxHashMap<K, V, BuildHasherDefault<AxHasher>> {
100 #[inline]
101 fn default() -> Self {
102 Self::new()
103 }
104}
105
106impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for AxHashMap<K, V, S> {
107 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
108 self.0.fmt(f)
109 }
110}
111
112impl<K: Clone, V: Clone, S: Clone> Clone for AxHashMap<K, V, S> {
113 #[inline]
114 fn clone(&self) -> Self {
115 Self(self.0.clone())
116 }
117}
118
119impl<K: Hash + Eq, V: PartialEq, S: BuildHasher> PartialEq for AxHashMap<K, V, S> {
120 fn eq(&self, other: &Self) -> bool {
121 self.0 == other.0
122 }
123}
124
125impl<K: Hash + Eq, V: Eq, S: BuildHasher> Eq for AxHashMap<K, V, S> {}
126
127impl<K, Q, V, S> Index<&Q> for AxHashMap<K, V, S>
128where
129 K: Hash + Eq + core::borrow::Borrow<Q>,
130 Q: Hash + Eq + ?Sized,
131 S: BuildHasher,
132{
133 type Output = V;
134
135 #[inline]
136 fn index(&self, key: &Q) -> &Self::Output {
137 self.0.index(key)
138 }
139}
140
141impl<K: Hash + Eq, V> FromIterator<(K, V)> for AxHashMap<K, V, BuildHasherDefault<AxHasher>> {
144 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
145 let iter = iter.into_iter();
146 let (lower, _) = iter.size_hint();
147 let mut map = Self::with_capacity(lower);
148 map.extend(iter);
149 map
150 }
151}
152
153impl<K: Hash + Eq, V, S: BuildHasher> Extend<(K, V)> for AxHashMap<K, V, S> {
154 #[inline]
155 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
156 self.0.extend(iter);
157 }
158}
159
160impl<'a, K: Hash + Eq + Copy, V: Copy, S: BuildHasher> Extend<(&'a K, &'a V)>
161 for AxHashMap<K, V, S>
162{
163 #[inline]
164 fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
165 self.0.extend(iter);
166 }
167}
168
169impl<K, V, S> IntoIterator for AxHashMap<K, V, S> {
172 type Item = (K, V);
173 type IntoIter = hashbrown::hash_map::IntoIter<K, V>;
174
175 #[inline]
176 fn into_iter(self) -> Self::IntoIter {
177 self.0.into_iter()
178 }
179}
180
181impl<'a, K, V, S> IntoIterator for &'a AxHashMap<K, V, S> {
182 type Item = (&'a K, &'a V);
183 type IntoIter = hashbrown::hash_map::Iter<'a, K, V>;
184
185 #[inline]
186 fn into_iter(self) -> Self::IntoIter {
187 self.0.iter()
188 }
189}
190
191impl<'a, K, V, S> IntoIterator for &'a mut AxHashMap<K, V, S> {
192 type Item = (&'a K, &'a mut V);
193 type IntoIter = hashbrown::hash_map::IterMut<'a, K, V>;
194
195 #[inline]
196 fn into_iter(self) -> Self::IntoIter {
197 self.0.iter_mut()
198 }
199}
200
201impl<K, V, S> From<RawHashMap<K, V, S>> for AxHashMap<K, V, S> {
204 #[inline]
205 fn from(inner: RawHashMap<K, V, S>) -> Self {
206 Self(inner)
207 }
208}
209
210impl<K, V, S> From<AxHashMap<K, V, S>> for RawHashMap<K, V, S> {
211 #[inline]
212 fn from(wrapper: AxHashMap<K, V, S>) -> Self {
213 wrapper.0
214 }
215}
216
217pub struct AxHashSet<T, S = BuildHasherDefault<AxHasher>>(RawHashSet<T, S>);
226
227impl<T> AxHashSet<T, BuildHasherDefault<AxHasher>> {
228 #[inline]
230 pub fn new() -> Self {
231 Self(RawHashSet::with_hasher(BuildHasherDefault::default()))
232 }
233
234 #[inline]
237 pub fn with_capacity(capacity: usize) -> Self {
238 Self(RawHashSet::with_capacity_and_hasher(
239 capacity,
240 BuildHasherDefault::default(),
241 ))
242 }
243}
244
245impl<T, S: BuildHasher> AxHashSet<T, S> {
246 #[inline]
248 pub fn with_hasher(hasher: S) -> Self {
249 Self(RawHashSet::with_hasher(hasher))
250 }
251
252 #[inline]
255 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
256 Self(RawHashSet::with_capacity_and_hasher(capacity, hasher))
257 }
258
259 #[inline]
261 pub fn into_inner(self) -> RawHashSet<T, S> {
262 self.0
263 }
264}
265
266impl<T, S> Deref for AxHashSet<T, S> {
269 type Target = RawHashSet<T, S>;
270
271 #[inline]
272 fn deref(&self) -> &Self::Target {
273 &self.0
274 }
275}
276
277impl<T, S> DerefMut for AxHashSet<T, S> {
278 #[inline]
279 fn deref_mut(&mut self) -> &mut Self::Target {
280 &mut self.0
281 }
282}
283
284impl<T> Default for AxHashSet<T, BuildHasherDefault<AxHasher>> {
287 #[inline]
288 fn default() -> Self {
289 Self::new()
290 }
291}
292
293impl<T: fmt::Debug, S> fmt::Debug for AxHashSet<T, S> {
294 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295 self.0.fmt(f)
296 }
297}
298
299impl<T: Clone, S: Clone> Clone for AxHashSet<T, S> {
300 #[inline]
301 fn clone(&self) -> Self {
302 Self(self.0.clone())
303 }
304}
305
306impl<T: Hash + Eq, S: BuildHasher> PartialEq for AxHashSet<T, S> {
307 fn eq(&self, other: &Self) -> bool {
308 self.0 == other.0
309 }
310}
311
312impl<T: Hash + Eq, S: BuildHasher> Eq for AxHashSet<T, S> {}
313
314impl<T: Hash + Eq> FromIterator<T> for AxHashSet<T, BuildHasherDefault<AxHasher>> {
317 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
318 let iter = iter.into_iter();
319 let (lower, _) = iter.size_hint();
320 let mut set = Self::with_capacity(lower);
321 set.extend(iter);
322 set
323 }
324}
325
326impl<T: Hash + Eq, S: BuildHasher> Extend<T> for AxHashSet<T, S> {
327 #[inline]
328 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
329 self.0.extend(iter);
330 }
331}
332
333impl<'a, T: Hash + Eq + Copy, S: BuildHasher> Extend<&'a T> for AxHashSet<T, S> {
334 #[inline]
335 fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
336 self.0.extend(iter);
337 }
338}
339
340impl<T, S> IntoIterator for AxHashSet<T, S> {
343 type Item = T;
344 type IntoIter = hashbrown::hash_set::IntoIter<T>;
345
346 #[inline]
347 fn into_iter(self) -> Self::IntoIter {
348 self.0.into_iter()
349 }
350}
351
352impl<'a, T, S> IntoIterator for &'a AxHashSet<T, S> {
353 type Item = &'a T;
354 type IntoIter = hashbrown::hash_set::Iter<'a, T>;
355
356 #[inline]
357 fn into_iter(self) -> Self::IntoIter {
358 self.0.iter()
359 }
360}
361
362impl<T, S> From<RawHashSet<T, S>> for AxHashSet<T, S> {
365 #[inline]
366 fn from(inner: RawHashSet<T, S>) -> Self {
367 Self(inner)
368 }
369}
370
371impl<T, S> From<AxHashSet<T, S>> for RawHashSet<T, S> {
372 #[inline]
373 fn from(wrapper: AxHashSet<T, S>) -> Self {
374 wrapper.0
375 }
376}
377
378#[cfg(test)]
381mod tests {
382 use super::*;
383 use core::hash::BuildHasherDefault;
384
385 #[test]
388 fn map_basic_operations() {
389 let mut map: AxHashMap<&str, u32> = AxHashMap::new();
390 assert!(map.is_empty());
391
392 map.insert("one", 1);
393 map.insert("two", 2);
394 map.insert("three", 3);
395
396 assert_eq!(map.len(), 3);
397 assert_eq!(map["one"], 1);
398 assert_eq!(map.get("two"), Some(&2));
399 assert_eq!(map.get("missing"), None);
400
401 map.remove("two");
402 assert_eq!(map.len(), 2);
403 }
404
405 #[test]
406 fn map_with_capacity() {
407 let map: AxHashMap<u32, u32> = AxHashMap::with_capacity(128);
408 assert!(map.capacity() >= 128);
409 }
410
411 #[test]
412 fn map_default() {
413 let map: AxHashMap<u64, u64> = AxHashMap::default();
414 assert!(map.is_empty());
415 }
416
417 #[test]
418 fn map_from_iterator() {
419 let pairs = vec![("a", 1u32), ("b", 2), ("c", 3)];
420 let map: AxHashMap<&str, u32> = pairs.into_iter().collect();
421 assert_eq!(map.len(), 3);
422 assert_eq!(map["b"], 2);
423 }
424
425 #[test]
426 fn map_extend() {
427 let mut map: AxHashMap<u32, u32> = AxHashMap::new();
428 map.extend([(1, 10), (2, 20)]);
429 map.extend([(3, 30)]);
430 assert_eq!(map.len(), 3);
431 assert_eq!(map[&2], 20);
432 }
433
434 #[test]
435 fn map_iter() {
436 let map: AxHashMap<u32, u32> = [(1, 10), (2, 20)].into_iter().collect();
437 let mut sum = 0u32;
438 for (_, v) in &map {
439 sum += v;
440 }
441 assert_eq!(sum, 30);
442 }
443
444 #[test]
445 fn map_into_inner_roundtrip() {
446 let mut map: AxHashMap<&str, i32> = AxHashMap::new();
447 map.insert("x", 99);
448 let raw: RawHashMap<&str, i32, BuildHasherDefault<AxHasher>> = map.into_inner();
449 assert_eq!(raw["x"], 99);
450 let wrapped: AxHashMap<&str, i32> = raw.into();
451 assert_eq!(wrapped["x"], 99);
452 }
453
454 #[test]
455 fn map_seeded_hasher() {
456 let hasher = AxBuildHasher::with_seed(0x1234_5678_9abc_def0);
457 let mut map: AxHashMap<&str, u32, AxBuildHasher> = AxHashMap::with_hasher(hasher);
458 map.insert("seeded", 7);
459 assert_eq!(map["seeded"], 7);
460 }
461
462 #[test]
465 fn alias_hashmap_basic() {
466 let mut map: HashMap<&str, u32> = HashMap::with_hasher(BuildHasherDefault::default());
467 map.insert("hello", 42);
468 assert_eq!(map["hello"], 42);
469 }
470
471 #[test]
472 fn alias_hashmap_collect() {
473 let map: HashMap<&str, u32> = [("a", 1u32), ("b", 2), ("c", 3)]
474 .into_iter()
475 .collect::<RawHashMap<_, _, BuildHasherDefault<AxHasher>>>();
476 assert_eq!(map.len(), 3);
477 }
478
479 #[test]
482 fn set_basic_operations() {
483 let mut set: AxHashSet<u32> = AxHashSet::new();
484 assert!(set.is_empty());
485
486 set.insert(1);
487 set.insert(2);
488 set.insert(2); set.insert(3);
490
491 assert_eq!(set.len(), 3);
492 assert!(set.contains(&1));
493 assert!(!set.contains(&99));
494
495 set.remove(&2);
496 assert_eq!(set.len(), 2);
497 }
498
499 #[test]
500 fn set_with_capacity() {
501 let set: AxHashSet<u64> = AxHashSet::with_capacity(64);
502 assert!(set.capacity() >= 64);
503 }
504
505 #[test]
506 fn set_default() {
507 let set: AxHashSet<u64> = AxHashSet::default();
508 assert!(set.is_empty());
509 }
510
511 #[test]
512 fn set_from_iterator() {
513 let set: AxHashSet<u32> = [1u32, 2, 3, 2, 1].into_iter().collect();
514 assert_eq!(set.len(), 3);
515 }
516
517 #[test]
518 fn set_extend() {
519 let mut set: AxHashSet<u32> = AxHashSet::new();
520 set.extend([1u32, 2, 3]);
521 set.extend([3u32, 4, 5]);
522 assert_eq!(set.len(), 5);
523 }
524
525 #[test]
526 fn set_set_operations() {
527 let a: AxHashSet<u32> = [1, 2, 3].into_iter().collect();
528 let b: AxHashSet<u32> = [2, 3, 4].into_iter().collect();
529
530 let union: AxHashSet<u32> = a.union(&b).copied().collect();
531 assert_eq!(union.len(), 4);
532
533 let inter: AxHashSet<u32> = a.intersection(&b).copied().collect();
534 assert_eq!(inter.len(), 2);
535 }
536
537 #[test]
538 fn set_into_inner_roundtrip() {
539 let mut set: AxHashSet<i32> = AxHashSet::new();
540 set.insert(42);
541 let raw: RawHashSet<i32, BuildHasherDefault<AxHasher>> = set.into_inner();
542 assert!(raw.contains(&42));
543 let wrapped: AxHashSet<i32> = raw.into();
544 assert!(wrapped.contains(&42));
545 }
546
547 #[test]
550 fn alias_hashset_basic() {
551 let mut set: HashSet<u32> = HashSet::with_hasher(BuildHasherDefault::default());
552 set.insert(1);
553 set.insert(2);
554 set.insert(2);
555 assert_eq!(set.len(), 2);
556 }
557}