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