1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3
4#[cfg(not(feature = "std"))]
5extern crate alloc;
6
7use core::fmt;
8use core::hash::{BuildHasher, BuildHasherDefault, Hash};
9use core::ops::{Deref, DerefMut, Index};
10
11pub use axhash_core::{AxBuildHasher, AxHasher};
16
17pub use indexmap::IndexMap as RawIndexMap;
19
20pub use indexmap::IndexSet as RawIndexSet;
22
23pub use indexmap::map::Entry as MapEntry;
25pub use indexmap::map::OccupiedEntry as MapOccupiedEntry;
26pub use indexmap::map::VacantEntry as MapVacantEntry;
27
28pub type IndexMap<K, V> = RawIndexMap<K, V, BuildHasherDefault<AxHasher>>;
39
40pub type IndexSet<T> = RawIndexSet<T, BuildHasherDefault<AxHasher>>;
44
45pub struct AxIndexMap<K, V, S = BuildHasherDefault<AxHasher>>(RawIndexMap<K, V, S>);
51
52impl<K, V> AxIndexMap<K, V, BuildHasherDefault<AxHasher>> {
53 #[inline(always)]
57 pub fn new() -> Self {
58 Self(RawIndexMap::with_hasher(BuildHasherDefault::default()))
59 }
60
61 #[inline(always)]
64 pub fn with_capacity(capacity: usize) -> Self {
65 Self(RawIndexMap::with_capacity_and_hasher(
66 capacity,
67 BuildHasherDefault::default(),
68 ))
69 }
70}
71
72impl<K, V, S: BuildHasher> AxIndexMap<K, V, S> {
73 #[inline(always)]
78 pub fn with_hasher(hasher: S) -> Self {
79 Self(RawIndexMap::with_hasher(hasher))
80 }
81
82 #[inline(always)]
85 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
86 Self(RawIndexMap::with_capacity_and_hasher(capacity, hasher))
87 }
88
89 #[inline(always)]
91 pub fn into_inner(self) -> RawIndexMap<K, V, S> {
92 self.0
93 }
94}
95
96impl<K, V, S> Deref for AxIndexMap<K, V, S> {
99 type Target = RawIndexMap<K, V, S>;
100
101 #[inline]
102 fn deref(&self) -> &Self::Target {
103 &self.0
104 }
105}
106
107impl<K, V, S> DerefMut for AxIndexMap<K, V, S> {
108 #[inline]
109 fn deref_mut(&mut self) -> &mut Self::Target {
110 &mut self.0
111 }
112}
113
114impl<K, V> Default for AxIndexMap<K, V, BuildHasherDefault<AxHasher>> {
117 #[inline]
118 fn default() -> Self {
119 Self::new()
120 }
121}
122
123impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for AxIndexMap<K, V, S> {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 self.0.fmt(f)
126 }
127}
128
129impl<K: Clone, V: Clone, S: Clone> Clone for AxIndexMap<K, V, S> {
130 #[inline]
131 fn clone(&self) -> Self {
132 Self(self.0.clone())
133 }
134}
135
136impl<K: Hash + Eq, V: PartialEq, S: BuildHasher> PartialEq for AxIndexMap<K, V, S> {
137 fn eq(&self, other: &Self) -> bool {
138 self.0 == other.0
139 }
140}
141
142impl<K: Hash + Eq, V: Eq, S: BuildHasher> Eq for AxIndexMap<K, V, S> {}
143
144impl<K, Q, V, S> Index<&Q> for AxIndexMap<K, V, S>
145where
146 K: Hash + Eq + core::borrow::Borrow<Q>,
147 Q: Hash + Eq + ?Sized,
148 S: BuildHasher,
149{
150 type Output = V;
151
152 #[inline]
153 fn index(&self, key: &Q) -> &Self::Output {
154 self.0.index(key)
155 }
156}
157
158impl<K: Hash + Eq, V> FromIterator<(K, V)> for AxIndexMap<K, V, BuildHasherDefault<AxHasher>> {
161 fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
162 let iter = iter.into_iter();
163 let (lower, _) = iter.size_hint();
164 let mut map = Self::with_capacity(lower);
165 map.extend(iter);
166 map
167 }
168}
169
170impl<K: Hash + Eq, V, S: BuildHasher> Extend<(K, V)> for AxIndexMap<K, V, S> {
171 #[inline]
172 fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
173 self.0.extend(iter);
174 }
175}
176
177impl<K, V, S> IntoIterator for AxIndexMap<K, V, S> {
180 type Item = (K, V);
181 type IntoIter = indexmap::map::IntoIter<K, V>;
182
183 #[inline]
184 fn into_iter(self) -> Self::IntoIter {
185 self.0.into_iter()
186 }
187}
188
189impl<'a, K, V, S> IntoIterator for &'a AxIndexMap<K, V, S> {
190 type Item = (&'a K, &'a V);
191 type IntoIter = indexmap::map::Iter<'a, K, V>;
192
193 #[inline]
194 fn into_iter(self) -> Self::IntoIter {
195 self.0.iter()
196 }
197}
198
199impl<'a, K, V, S> IntoIterator for &'a mut AxIndexMap<K, V, S> {
200 type Item = (&'a K, &'a mut V);
201 type IntoIter = indexmap::map::IterMut<'a, K, V>;
202
203 #[inline]
204 fn into_iter(self) -> Self::IntoIter {
205 self.0.iter_mut()
206 }
207}
208
209impl<K, V, S> From<RawIndexMap<K, V, S>> for AxIndexMap<K, V, S> {
212 #[inline]
213 fn from(inner: RawIndexMap<K, V, S>) -> Self {
214 Self(inner)
215 }
216}
217
218impl<K, V, S> From<AxIndexMap<K, V, S>> for RawIndexMap<K, V, S> {
219 #[inline]
220 fn from(wrapper: AxIndexMap<K, V, S>) -> Self {
221 wrapper.0
222 }
223}
224
225pub struct AxIndexSet<T, S = BuildHasherDefault<AxHasher>>(RawIndexSet<T, S>);
236
237impl<T> AxIndexSet<T, BuildHasherDefault<AxHasher>> {
238 #[inline(always)]
240 pub fn new() -> Self {
241 Self(RawIndexSet::with_hasher(BuildHasherDefault::default()))
242 }
243
244 #[inline(always)]
247 pub fn with_capacity(capacity: usize) -> Self {
248 Self(RawIndexSet::with_capacity_and_hasher(
249 capacity,
250 BuildHasherDefault::default(),
251 ))
252 }
253}
254
255impl<T, S: BuildHasher> AxIndexSet<T, S> {
256 #[inline(always)]
258 pub fn with_hasher(hasher: S) -> Self {
259 Self(RawIndexSet::with_hasher(hasher))
260 }
261
262 #[inline(always)]
265 pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
266 Self(RawIndexSet::with_capacity_and_hasher(capacity, hasher))
267 }
268
269 #[inline(always)]
271 pub fn into_inner(self) -> RawIndexSet<T, S> {
272 self.0
273 }
274}
275
276impl<T, S> Deref for AxIndexSet<T, S> {
279 type Target = RawIndexSet<T, S>;
280
281 #[inline]
282 fn deref(&self) -> &Self::Target {
283 &self.0
284 }
285}
286
287impl<T, S> DerefMut for AxIndexSet<T, S> {
288 #[inline]
289 fn deref_mut(&mut self) -> &mut Self::Target {
290 &mut self.0
291 }
292}
293
294impl<T> Default for AxIndexSet<T, BuildHasherDefault<AxHasher>> {
297 #[inline]
298 fn default() -> Self {
299 Self::new()
300 }
301}
302
303impl<T: fmt::Debug, S> fmt::Debug for AxIndexSet<T, S> {
304 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305 self.0.fmt(f)
306 }
307}
308
309impl<T: Clone, S: Clone> Clone for AxIndexSet<T, S> {
310 #[inline]
311 fn clone(&self) -> Self {
312 Self(self.0.clone())
313 }
314}
315
316impl<T: Hash + Eq, S: BuildHasher> PartialEq for AxIndexSet<T, S> {
317 fn eq(&self, other: &Self) -> bool {
318 self.0 == other.0
319 }
320}
321
322impl<T: Hash + Eq, S: BuildHasher> Eq for AxIndexSet<T, S> {}
323
324impl<T: Hash + Eq> FromIterator<T> for AxIndexSet<T, BuildHasherDefault<AxHasher>> {
327 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
328 let iter = iter.into_iter();
329 let (lower, _) = iter.size_hint();
330 let mut set = Self::with_capacity(lower);
331 set.extend(iter);
332 set
333 }
334}
335
336impl<T: Hash + Eq, S: BuildHasher> Extend<T> for AxIndexSet<T, S> {
337 #[inline]
338 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
339 self.0.extend(iter);
340 }
341}
342
343impl<T, S> IntoIterator for AxIndexSet<T, S> {
346 type Item = T;
347 type IntoIter = indexmap::set::IntoIter<T>;
348
349 #[inline]
350 fn into_iter(self) -> Self::IntoIter {
351 self.0.into_iter()
352 }
353}
354
355impl<'a, T, S> IntoIterator for &'a AxIndexSet<T, S> {
356 type Item = &'a T;
357 type IntoIter = indexmap::set::Iter<'a, T>;
358
359 #[inline]
360 fn into_iter(self) -> Self::IntoIter {
361 self.0.iter()
362 }
363}
364
365impl<T, S> From<RawIndexSet<T, S>> for AxIndexSet<T, S> {
368 #[inline]
369 fn from(inner: RawIndexSet<T, S>) -> Self {
370 Self(inner)
371 }
372}
373
374impl<T, S> From<AxIndexSet<T, S>> for RawIndexSet<T, S> {
375 #[inline]
376 fn from(wrapper: AxIndexSet<T, S>) -> Self {
377 wrapper.0
378 }
379}
380
381#[inline(always)]
388pub fn new_map<K, V>() -> AxIndexMap<K, V> {
389 AxIndexMap::new()
390}
391
392#[inline(always)]
394pub fn map_with_capacity<K, V>(capacity: usize) -> AxIndexMap<K, V> {
395 AxIndexMap::with_capacity(capacity)
396}
397
398#[inline(always)]
400pub fn new_set<T>() -> AxIndexSet<T> {
401 AxIndexSet::new()
402}
403
404#[inline(always)]
406pub fn set_with_capacity<T>(capacity: usize) -> AxIndexSet<T> {
407 AxIndexSet::with_capacity(capacity)
408}
409
410#[cfg(test)]
413mod tests {
414 use super::*;
415 use core::hash::BuildHasherDefault;
416
417 #[test]
420 fn map_constructors() {
421 let m1: AxIndexMap<&str, u32> = AxIndexMap::default();
422 let m2: AxIndexMap<&str, u32> = AxIndexMap::new();
423 let m3: AxIndexMap<&str, u32> = new_map();
424 let m4: AxIndexMap<&str, u32> = AxIndexMap::with_hasher(BuildHasherDefault::default());
425 assert!(m1.is_empty() && m2.is_empty() && m3.is_empty() && m4.is_empty());
426 }
427
428 #[test]
429 fn map_with_capacity_constructors() {
430 let m1: AxIndexMap<u32, u32> = AxIndexMap::with_capacity(64);
431 let m2: AxIndexMap<u32, u32> = map_with_capacity(64);
432 assert!(m1.capacity() >= 64 && m2.capacity() >= 64);
433 }
434
435 #[test]
436 fn map_seeded_hasher() {
437 let mut map: AxIndexMap<&str, i32, AxBuildHasher> =
438 AxIndexMap::with_hasher(AxBuildHasher::with_seed(0xc0ffee_deadbeef));
439 map.insert("seeded", -1);
440 assert_eq!(map["seeded"], -1);
441 }
442
443 #[test]
444 fn map_insertion_order_preserved() {
445 let mut map: AxIndexMap<&str, u32> = AxIndexMap::new();
446 let words = ["delta", "alpha", "charlie", "bravo"];
447 for (i, w) in words.iter().enumerate() {
448 map.insert(w, i as u32);
449 }
450 assert_eq!(map.keys().copied().collect::<Vec<_>>(), words);
451 }
452
453 #[test]
454 fn map_index_based_access() {
455 let mut map: AxIndexMap<&str, u32> = AxIndexMap::new();
456 map.insert("first", 1);
457 map.insert("second", 2);
458 map.insert("third", 3);
459 assert_eq!(map.get_index(0), Some((&"first", &1)));
460 assert_eq!(map.get_index(2), Some((&"third", &3)));
461 assert_eq!(map.get_index(3), None);
462 }
463
464 #[test]
465 fn map_entry_api() {
466 let mut map: AxIndexMap<&str, u32> = AxIndexMap::new();
467 for _ in 0..3 {
468 map.entry("counter").and_modify(|n| *n += 1).or_insert(0);
469 }
470 assert_eq!(map["counter"], 2);
471 }
472
473 #[test]
474 fn map_from_iterator() {
475 let map: AxIndexMap<&str, u32> = [("a", 1u32), ("b", 2), ("c", 3)].into_iter().collect();
476 assert_eq!(map.len(), 3);
477 assert_eq!(map.get_index(0), Some((&"a", &1)));
478 }
479
480 #[test]
481 fn map_extend() {
482 let mut map: AxIndexMap<u32, u32> = AxIndexMap::new();
483 map.extend([(1, 10), (2, 20), (3, 30)]);
484 assert_eq!(map.len(), 3);
485 assert_eq!(map[&2], 20);
486 }
487
488 #[test]
489 fn map_retain() {
490 let mut map: AxIndexMap<u32, u32> = (0u32..10).map(|i| (i, i * i)).collect();
491 map.retain(|_, v| *v > 25);
492 assert!(map.values().all(|&v| v > 25));
493 }
494
495 #[test]
496 fn map_sort_keys() {
497 let mut map: AxIndexMap<&str, u32> = AxIndexMap::new();
498 map.insert("banana", 2);
499 map.insert("apple", 1);
500 map.insert("cherry", 3);
501 map.sort_keys();
502 assert_eq!(
503 map.keys().copied().collect::<Vec<_>>(),
504 ["apple", "banana", "cherry"]
505 );
506 }
507
508 #[test]
509 fn map_swap_remove() {
510 let mut map: AxIndexMap<u32, u32> = (0u32..5).map(|i| (i, i)).collect();
511 map.swap_remove(&2);
512 assert_eq!(map.len(), 4);
513 assert!(!map.contains_key(&2));
514 }
515
516 #[test]
517 fn map_into_inner_roundtrip() {
518 let mut raw: RawIndexMap<&str, i32, BuildHasherDefault<AxHasher>> =
519 RawIndexMap::with_hasher(BuildHasherDefault::default());
520 raw.insert("x", 99);
521 let ax: AxIndexMap<&str, i32> = raw.into();
522 assert_eq!(ax["x"], 99);
523 let raw: RawIndexMap<&str, i32, BuildHasherDefault<AxHasher>> = ax.into();
524 assert_eq!(raw["x"], 99);
525 }
526
527 #[test]
530 fn alias_indexmap_basic() {
531 let mut map: IndexMap<&str, u32> = RawIndexMap::with_hasher(BuildHasherDefault::default());
532 map.insert("hello", 42);
533 assert_eq!(map["hello"], 42);
534 map.insert("world", 7);
536 assert_eq!(map.get_index(0), Some((&"hello", &42)));
537 }
538
539 #[test]
540 fn alias_indexmap_collect() {
541 let map: IndexMap<&str, u32> = [("a", 1u32), ("b", 2), ("c", 3)]
542 .into_iter()
543 .collect::<RawIndexMap<_, _, BuildHasherDefault<AxHasher>>>();
544 assert_eq!(map.len(), 3);
545 }
546
547 #[test]
550 fn set_constructors() {
551 let s1: AxIndexSet<u32> = AxIndexSet::default();
552 let s2: AxIndexSet<u32> = AxIndexSet::new();
553 let s3: AxIndexSet<u32> = new_set();
554 let s4: AxIndexSet<u32> = AxIndexSet::with_hasher(BuildHasherDefault::default());
555 assert!(s1.is_empty() && s2.is_empty() && s3.is_empty() && s4.is_empty());
556 }
557
558 #[test]
559 fn set_with_capacity_constructors() {
560 let s1: AxIndexSet<u64> = AxIndexSet::with_capacity(128);
561 let s2: AxIndexSet<u64> = set_with_capacity(128);
562 assert!(s1.capacity() >= 128 && s2.capacity() >= 128);
563 }
564
565 #[test]
566 fn set_insertion_order_and_dedup() {
567 let mut set: AxIndexSet<u32> = AxIndexSet::new();
568 for n in [5, 3, 1, 3, 5, 2, 4, 2] {
569 set.insert(n);
570 }
571 assert_eq!(set.iter().copied().collect::<Vec<_>>(), [5, 3, 1, 2, 4]);
572 }
573
574 #[test]
575 fn set_index_based_access() {
576 let set: AxIndexSet<&str> = ["x", "y", "z"].into_iter().collect();
577 assert_eq!(set.get_index(0), Some(&"x"));
578 assert_eq!(set.get_index(2), Some(&"z"));
579 }
580
581 #[test]
582 fn set_operations() {
583 let a: AxIndexSet<u32> = [1, 2, 3, 4].into_iter().collect();
584 let b: AxIndexSet<u32> = [3, 4, 5, 6].into_iter().collect();
585 assert_eq!(a.union(&b).count(), 6);
586 assert_eq!(a.intersection(&b).count(), 2);
587 assert_eq!(a.difference(&b).count(), 2);
588 }
589
590 #[test]
591 fn set_from_iterator_dedup() {
592 let set: AxIndexSet<i32> = [1, 2, 3, 2, 1, 4].into_iter().collect();
593 assert_eq!(set.len(), 4);
594 }
595
596 #[test]
597 fn set_extend() {
598 let mut set: AxIndexSet<u32> = AxIndexSet::new();
599 set.extend([1u32, 2, 3]);
600 set.extend([3u32, 4, 5]);
601 assert_eq!(set.len(), 5);
602 }
603
604 #[test]
605 fn set_sort() {
606 let mut set: AxIndexSet<u32> = [5, 3, 1, 4, 2].into_iter().collect();
607 set.sort();
608 assert_eq!(set.iter().copied().collect::<Vec<_>>(), [1, 2, 3, 4, 5]);
609 }
610
611 #[test]
612 fn set_into_inner_roundtrip() {
613 let mut raw: RawIndexSet<u64, BuildHasherDefault<AxHasher>> =
614 RawIndexSet::with_hasher(BuildHasherDefault::default());
615 raw.insert(42u64);
616 let ax: AxIndexSet<u64> = raw.into();
617 assert!(ax.contains(&42));
618 let raw: RawIndexSet<u64, BuildHasherDefault<AxHasher>> = ax.into();
619 assert!(raw.contains(&42));
620 }
621
622 #[test]
625 fn alias_indexset_basic() {
626 let mut set: IndexSet<u32> = RawIndexSet::with_hasher(BuildHasherDefault::default());
627 set.insert(1);
628 set.insert(2);
629 set.insert(2);
630 assert_eq!(set.len(), 2);
631 assert_eq!(set.get_index(0), Some(&1));
632 }
633}