iddqd/id_hash_map/
imp.rs

1use super::{
2    Entry, IdHashItem, IntoIter, Iter, IterMut, OccupiedEntry, RefMut,
3    VacantEntry, tables::IdHashMapTables,
4};
5use crate::{
6    DefaultHashBuilder,
7    errors::DuplicateItem,
8    internal::{ValidateCompact, ValidationError},
9    support::{
10        alloc::{Allocator, Global, global_alloc},
11        borrow::DormantMutRef,
12        item_set::ItemSet,
13        map_hash::MapHash,
14    },
15};
16use alloc::collections::BTreeSet;
17use core::{
18    fmt,
19    hash::{BuildHasher, Hash},
20};
21use equivalent::Equivalent;
22use hashbrown::hash_table;
23
24/// A hash map where the key is part of the value.
25///
26/// The storage mechanism is a fast hash table of integer indexes to items, with
27/// these indexes stored in a hash table. This allows for efficient lookups by
28/// the key and prevents duplicates.
29///
30/// # Examples
31///
32/// ```
33/// # #[cfg(feature = "default-hasher")] {
34/// use iddqd::{IdHashItem, IdHashMap, id_upcast};
35///
36/// // Define a struct with a key.
37/// #[derive(Debug, PartialEq, Eq, Hash)]
38/// struct MyItem {
39///     id: String,
40///     value: u32,
41/// }
42///
43/// // Implement IdHashItem for the struct.
44/// impl IdHashItem for MyItem {
45///     // Keys can borrow from the item.
46///     type Key<'a> = &'a str;
47///
48///     fn key(&self) -> Self::Key<'_> {
49///         &self.id
50///     }
51///
52///     id_upcast!();
53/// }
54///
55/// // Create an IdHashMap and insert items.
56/// let mut map = IdHashMap::new();
57/// map.insert_unique(MyItem { id: "foo".to_string(), value: 42 }).unwrap();
58/// map.insert_unique(MyItem { id: "bar".to_string(), value: 20 }).unwrap();
59///
60/// // Look up items by their keys.
61/// assert_eq!(map.get("foo").unwrap().value, 42);
62/// assert_eq!(map.get("bar").unwrap().value, 20);
63/// assert!(map.get("baz").is_none());
64/// # }
65/// ```
66#[derive(Clone)]
67pub struct IdHashMap<T, S = DefaultHashBuilder, A: Allocator = Global> {
68    pub(super) items: ItemSet<T, A>,
69    tables: IdHashMapTables<S, A>,
70}
71
72impl<T: IdHashItem, S: Default, A: Allocator + Default> Default
73    for IdHashMap<T, S, A>
74{
75    fn default() -> Self {
76        Self {
77            items: ItemSet::with_capacity_in(0, A::default()),
78            tables: IdHashMapTables::default(),
79        }
80    }
81}
82
83#[cfg(feature = "default-hasher")]
84impl<T: IdHashItem> IdHashMap<T> {
85    /// Creates a new, empty `IdHashMap`.
86    ///
87    /// # Examples
88    ///
89    /// ```
90    /// # #[cfg(feature = "default-hasher")] {
91    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
92    ///
93    /// #[derive(Debug, PartialEq, Eq, Hash)]
94    /// struct Item {
95    ///     id: String,
96    ///     value: u32,
97    /// }
98    ///
99    /// impl IdHashItem for Item {
100    ///     type Key<'a> = &'a str;
101    ///     fn key(&self) -> Self::Key<'_> {
102    ///         &self.id
103    ///     }
104    ///     id_upcast!();
105    /// }
106    ///
107    /// let map: IdHashMap<Item> = IdHashMap::new();
108    /// assert!(map.is_empty());
109    /// assert_eq!(map.len(), 0);
110    /// # }
111    /// ```
112    #[inline]
113    pub fn new() -> Self {
114        Self { items: ItemSet::default(), tables: IdHashMapTables::default() }
115    }
116
117    /// Creates a new `IdHashMap` with the given capacity.
118    ///
119    /// # Examples
120    ///
121    /// ```
122    /// # #[cfg(feature = "default-hasher")] {
123    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
124    ///
125    /// #[derive(Debug, PartialEq, Eq, Hash)]
126    /// struct Item {
127    ///     id: String,
128    ///     value: u32,
129    /// }
130    ///
131    /// impl IdHashItem for Item {
132    ///     type Key<'a> = &'a str;
133    ///     fn key(&self) -> Self::Key<'_> {
134    ///         &self.id
135    ///     }
136    ///     id_upcast!();
137    /// }
138    ///
139    /// let map: IdHashMap<Item> = IdHashMap::with_capacity(10);
140    /// assert!(map.capacity() >= 10);
141    /// assert!(map.is_empty());
142    /// # }
143    /// ```
144    pub fn with_capacity(capacity: usize) -> Self {
145        Self {
146            items: ItemSet::with_capacity_in(capacity, global_alloc()),
147            tables: IdHashMapTables::with_capacity_and_hasher_in(
148                capacity,
149                DefaultHashBuilder::default(),
150                global_alloc(),
151            ),
152        }
153    }
154}
155
156impl<T: IdHashItem, S: Clone + BuildHasher> IdHashMap<T, S> {
157    /// Creates a new, empty `IdHashMap` with the given hasher.
158    ///
159    /// # Examples
160    ///
161    /// ```
162    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
163    /// use std::collections::hash_map::RandomState;
164    ///
165    /// #[derive(Debug, PartialEq, Eq, Hash)]
166    /// struct Item {
167    ///     id: String,
168    ///     value: u32,
169    /// }
170    ///
171    /// impl IdHashItem for Item {
172    ///     type Key<'a> = &'a str;
173    ///     fn key(&self) -> Self::Key<'_> {
174    ///         &self.id
175    ///     }
176    ///     id_upcast!();
177    /// }
178    ///
179    /// let hasher = RandomState::new();
180    /// let map: IdHashMap<Item, _> = IdHashMap::with_hasher(hasher);
181    /// assert!(map.is_empty());
182    /// ```
183    pub fn with_hasher(hasher: S) -> Self {
184        Self {
185            items: ItemSet::default(),
186            tables: IdHashMapTables::with_capacity_and_hasher_in(
187                0,
188                hasher,
189                global_alloc(),
190            ),
191        }
192    }
193
194    /// Creates a new `IdHashMap` with the given capacity and hasher.
195    ///
196    /// # Examples
197    ///
198    /// ```
199    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
200    /// use std::collections::hash_map::RandomState;
201    ///
202    /// #[derive(Debug, PartialEq, Eq, Hash)]
203    /// struct Item {
204    ///     id: String,
205    ///     value: u32,
206    /// }
207    ///
208    /// impl IdHashItem for Item {
209    ///     type Key<'a> = &'a str;
210    ///     fn key(&self) -> Self::Key<'_> {
211    ///         &self.id
212    ///     }
213    ///     id_upcast!();
214    /// }
215    ///
216    /// let hasher = RandomState::new();
217    /// let map: IdHashMap<Item, _> =
218    ///     IdHashMap::with_capacity_and_hasher(10, hasher);
219    /// assert!(map.capacity() >= 10);
220    /// assert!(map.is_empty());
221    /// ```
222    pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self {
223        Self {
224            items: ItemSet::with_capacity_in(capacity, global_alloc()),
225            tables: IdHashMapTables::with_capacity_and_hasher_in(
226                capacity,
227                hasher,
228                global_alloc(),
229            ),
230        }
231    }
232}
233
234#[cfg(feature = "default-hasher")]
235impl<T: IdHashItem, A: Clone + Allocator> IdHashMap<T, DefaultHashBuilder, A> {
236    /// Creates a new empty `IdHashMap` using the given allocator.
237    ///
238    /// Requires the `allocator-api2` feature to be enabled.
239    ///
240    /// # Examples
241    ///
242    /// Using the [`bumpalo`](https://docs.rs/bumpalo) allocator:
243    ///
244    /// ```
245    /// # #[cfg(all(feature = "default-hasher", feature = "allocator-api2"))] {
246    /// use iddqd::{IdHashMap, IdHashItem, id_upcast};
247    /// # use iddqd_test_utils::bumpalo;
248    ///
249    /// #[derive(Debug, PartialEq, Eq, Hash)]
250    /// struct Item {
251    ///     id: String,
252    ///     value: u32,
253    /// }
254    ///
255    /// impl IdHashItem for Item {
256    ///     type Key<'a> = &'a str;
257    ///     fn key(&self) -> Self::Key<'_> { &self.id }
258    ///     id_upcast!();
259    /// }
260    ///
261    /// // Define a new allocator.
262    /// let bump = bumpalo::Bump::new();
263    /// // Create a new IdHashMap using the allocator.
264    /// let map: IdHashMap<Item, _, &bumpalo::Bump> = IdHashMap::new_in(&bump);
265    /// assert!(map.is_empty());
266    /// # }
267    /// ```
268    pub fn new_in(alloc: A) -> Self {
269        Self {
270            items: ItemSet::with_capacity_in(0, alloc.clone()),
271            tables: IdHashMapTables::with_capacity_and_hasher_in(
272                0,
273                DefaultHashBuilder::default(),
274                alloc,
275            ),
276        }
277    }
278
279    /// Creates an empty `IdHashMap` with the specified capacity using the given
280    /// allocator.
281    ///
282    /// Requires the `allocator-api2` feature to be enabled.
283    ///
284    /// # Examples
285    ///
286    /// Using the [`bumpalo`](https://docs.rs/bumpalo) allocator:
287    ///
288    /// ```
289    /// # #[cfg(all(feature = "default-hasher", feature = "allocator-api2"))] {
290    /// use iddqd::{IdHashMap, IdHashItem, id_upcast};
291    /// # use iddqd_test_utils::bumpalo;
292    ///
293    /// #[derive(Debug, PartialEq, Eq, Hash)]
294    /// struct Item {
295    ///     id: String,
296    ///     value: u32,
297    /// }
298    ///
299    /// impl IdHashItem for Item {
300    ///     type Key<'a> = &'a str;
301    ///     fn key(&self) -> Self::Key<'_> { &self.id }
302    ///     id_upcast!();
303    /// }
304    ///
305    /// // Define a new allocator.
306    /// let bump = bumpalo::Bump::new();
307    /// // Create a new IdHashMap with capacity using the allocator.
308    /// let map: IdHashMap<Item, _, &bumpalo::Bump> = IdHashMap::with_capacity_in(10, &bump);
309    /// assert!(map.capacity() >= 10);
310    /// assert!(map.is_empty());
311    /// # }
312    /// ```
313    pub fn with_capacity_in(capacity: usize, alloc: A) -> Self {
314        Self {
315            items: ItemSet::with_capacity_in(capacity, alloc.clone()),
316            tables: IdHashMapTables::with_capacity_and_hasher_in(
317                capacity,
318                DefaultHashBuilder::default(),
319                alloc,
320            ),
321        }
322    }
323}
324
325impl<T: IdHashItem, S: Clone + BuildHasher, A: Clone + Allocator>
326    IdHashMap<T, S, A>
327{
328    /// Creates a new, empty `IdHashMap` with the given hasher and allocator.
329    ///
330    /// Requires the `allocator-api2` feature to be enabled.
331    ///
332    /// # Examples
333    ///
334    /// Using the [`bumpalo`](https://docs.rs/bumpalo) allocator:
335    ///
336    /// ```
337    /// # #[cfg(feature = "allocator-api2")] {
338    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
339    /// use std::collections::hash_map::RandomState;
340    /// # use iddqd_test_utils::bumpalo;
341    ///
342    /// #[derive(Debug, PartialEq, Eq, Hash)]
343    /// struct Item {
344    ///     id: String,
345    ///     value: u32,
346    /// }
347    ///
348    /// impl IdHashItem for Item {
349    ///     type Key<'a> = &'a str;
350    ///     fn key(&self) -> Self::Key<'_> {
351    ///         &self.id
352    ///     }
353    ///     id_upcast!();
354    /// }
355    ///
356    /// // Define a new allocator.
357    /// let bump = bumpalo::Bump::new();
358    /// let hasher = RandomState::new();
359    /// // Create a new IdHashMap with hasher using the allocator.
360    /// let map: IdHashMap<Item, _, &bumpalo::Bump> =
361    ///     IdHashMap::with_hasher_in(hasher, &bump);
362    /// assert!(map.is_empty());
363    /// # }
364    /// ```
365    pub fn with_hasher_in(hasher: S, alloc: A) -> Self {
366        Self {
367            items: ItemSet::with_capacity_in(0, alloc.clone()),
368            tables: IdHashMapTables::with_capacity_and_hasher_in(
369                0, hasher, alloc,
370            ),
371        }
372    }
373
374    /// Creates a new, empty `IdHashMap` with the given capacity, hasher, and
375    /// allocator.
376    ///
377    /// Requires the `allocator-api2` feature to be enabled.
378    ///
379    /// # Examples
380    ///
381    /// Using the [`bumpalo`](https://docs.rs/bumpalo) allocator:
382    ///
383    /// ```
384    /// # #[cfg(feature = "allocator-api2")] {
385    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
386    /// use std::collections::hash_map::RandomState;
387    /// # use iddqd_test_utils::bumpalo;
388    ///
389    /// #[derive(Debug, PartialEq, Eq, Hash)]
390    /// struct Item {
391    ///     id: String,
392    ///     value: u32,
393    /// }
394    ///
395    /// impl IdHashItem for Item {
396    ///     type Key<'a> = &'a str;
397    ///     fn key(&self) -> Self::Key<'_> {
398    ///         &self.id
399    ///     }
400    ///     id_upcast!();
401    /// }
402    ///
403    /// // Define a new allocator.
404    /// let bump = bumpalo::Bump::new();
405    /// let hasher = RandomState::new();
406    /// // Create a new IdHashMap with capacity and hasher using the allocator.
407    /// let map: IdHashMap<Item, _, &bumpalo::Bump> =
408    ///     IdHashMap::with_capacity_and_hasher_in(10, hasher, &bump);
409    /// assert!(map.capacity() >= 10);
410    /// assert!(map.is_empty());
411    /// # }
412    /// ```
413    pub fn with_capacity_and_hasher_in(
414        capacity: usize,
415        hasher: S,
416        alloc: A,
417    ) -> Self {
418        Self {
419            items: ItemSet::with_capacity_in(capacity, alloc.clone()),
420            tables: IdHashMapTables::with_capacity_and_hasher_in(
421                capacity, hasher, alloc,
422            ),
423        }
424    }
425}
426
427impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> IdHashMap<T, S, A> {
428    #[cfg(feature = "daft")]
429    pub(crate) fn hasher(&self) -> &S {
430        self.tables.hasher()
431    }
432
433    /// Returns the allocator.
434    ///
435    /// Requires the `allocator-api2` feature to be enabled.
436    ///
437    /// # Examples
438    ///
439    /// Using the [`bumpalo`](https://docs.rs/bumpalo) allocator:
440    ///
441    /// ```
442    /// # #[cfg(all(feature = "default-hasher", feature = "allocator-api2"))] {
443    /// use iddqd::{IdHashMap, IdHashItem, id_upcast};
444    /// # use iddqd_test_utils::bumpalo;
445    ///
446    /// #[derive(Debug, PartialEq, Eq, Hash)]
447    /// struct Item {
448    ///     id: String,
449    ///     value: u32,
450    /// }
451    ///
452    /// impl IdHashItem for Item {
453    ///     type Key<'a> = &'a str;
454    ///     fn key(&self) -> Self::Key<'_> { &self.id }
455    ///     id_upcast!();
456    /// }
457    ///
458    /// // Define a new allocator.
459    /// let bump = bumpalo::Bump::new();
460    /// // Create a new IdHashMap using the allocator.
461    /// let map: IdHashMap<Item, _, &bumpalo::Bump> = IdHashMap::new_in(&bump);
462    /// let _allocator = map.allocator();
463    /// # }
464    /// ```
465    pub fn allocator(&self) -> &A {
466        self.items.allocator()
467    }
468
469    /// Returns the currently allocated capacity of the map.
470    ///
471    /// # Examples
472    ///
473    /// ```
474    /// # #[cfg(feature = "default-hasher")] {
475    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
476    ///
477    /// #[derive(Debug, PartialEq, Eq, Hash)]
478    /// struct Item {
479    ///     id: String,
480    ///     value: u32,
481    /// }
482    ///
483    /// impl IdHashItem for Item {
484    ///     type Key<'a> = &'a str;
485    ///     fn key(&self) -> Self::Key<'_> {
486    ///         &self.id
487    ///     }
488    ///     id_upcast!();
489    /// }
490    ///
491    /// let map: IdHashMap<Item> = IdHashMap::with_capacity(10);
492    /// assert!(map.capacity() >= 10);
493    /// # }
494    /// ```
495    pub fn capacity(&self) -> usize {
496        // items and tables.capacity might theoretically diverge: use
497        // items.capacity.
498        self.items.capacity()
499    }
500
501    /// Returns true if the map is empty.
502    ///
503    /// # Examples
504    ///
505    /// ```
506    /// # #[cfg(feature = "default-hasher")] {
507    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
508    ///
509    /// #[derive(Debug, PartialEq, Eq, Hash)]
510    /// struct Item {
511    ///     id: String,
512    ///     value: u32,
513    /// }
514    ///
515    /// impl IdHashItem for Item {
516    ///     type Key<'a> = &'a str;
517    ///     fn key(&self) -> Self::Key<'_> {
518    ///         &self.id
519    ///     }
520    ///     id_upcast!();
521    /// }
522    ///
523    /// let mut map = IdHashMap::new();
524    /// assert!(map.is_empty());
525    ///
526    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
527    /// assert!(!map.is_empty());
528    /// # }
529    /// ```
530    #[inline]
531    pub fn is_empty(&self) -> bool {
532        self.items.is_empty()
533    }
534
535    /// Returns the number of items in the map.
536    ///
537    /// # Examples
538    ///
539    /// ```
540    /// # #[cfg(feature = "default-hasher")] {
541    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
542    ///
543    /// #[derive(Debug, PartialEq, Eq, Hash)]
544    /// struct Item {
545    ///     id: String,
546    ///     value: u32,
547    /// }
548    ///
549    /// impl IdHashItem for Item {
550    ///     type Key<'a> = &'a str;
551    ///     fn key(&self) -> Self::Key<'_> {
552    ///         &self.id
553    ///     }
554    ///     id_upcast!();
555    /// }
556    ///
557    /// let mut map = IdHashMap::new();
558    /// assert_eq!(map.len(), 0);
559    ///
560    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
561    /// assert_eq!(map.len(), 1);
562    ///
563    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
564    /// assert_eq!(map.len(), 2);
565    /// # }
566    /// ```
567    #[inline]
568    pub fn len(&self) -> usize {
569        self.items.len()
570    }
571
572    /// Iterates over the items in the map.
573    ///
574    /// Similar to [`HashMap`], the iteration order is arbitrary and not
575    /// guaranteed to be stable.
576    ///
577    /// # Examples
578    ///
579    /// ```
580    /// # #[cfg(feature = "default-hasher")] {
581    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
582    ///
583    /// #[derive(Debug, PartialEq, Eq, Hash)]
584    /// struct Item {
585    ///     id: String,
586    ///     value: u32,
587    /// }
588    ///
589    /// impl IdHashItem for Item {
590    ///     type Key<'a> = &'a str;
591    ///     fn key(&self) -> Self::Key<'_> {
592    ///         &self.id
593    ///     }
594    ///     id_upcast!();
595    /// }
596    ///
597    /// let mut map = IdHashMap::new();
598    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
599    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
600    ///
601    /// let mut values: Vec<u32> = map.iter().map(|item| item.value).collect();
602    /// values.sort();
603    /// assert_eq!(values, vec![20, 42]);
604    /// # }
605    /// ```
606    ///
607    /// [`HashMap`]: std::collections::HashMap
608    #[inline]
609    pub fn iter(&self) -> Iter<'_, T> {
610        Iter::new(&self.items)
611    }
612
613    /// Iterates over the items in the map, allowing for mutation.
614    ///
615    /// Similar to [`HashMap`], the iteration order is arbitrary and not
616    /// guaranteed to be stable.
617    ///
618    /// # Examples
619    ///
620    /// ```
621    /// # #[cfg(feature = "default-hasher")] {
622    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
623    ///
624    /// #[derive(Debug, PartialEq, Eq, Hash)]
625    /// struct Item {
626    ///     id: String,
627    ///     value: u32,
628    /// }
629    ///
630    /// impl IdHashItem for Item {
631    ///     type Key<'a> = &'a str;
632    ///     fn key(&self) -> Self::Key<'_> {
633    ///         &self.id
634    ///     }
635    ///     id_upcast!();
636    /// }
637    ///
638    /// let mut map = IdHashMap::new();
639    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
640    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
641    ///
642    /// for mut item in map.iter_mut() {
643    ///     item.value *= 2;
644    /// }
645    ///
646    /// assert_eq!(map.get("foo").unwrap().value, 84);
647    /// assert_eq!(map.get("bar").unwrap().value, 40);
648    /// # }
649    /// ```
650    ///
651    /// [`HashMap`]: std::collections::HashMap
652    #[inline]
653    pub fn iter_mut(&mut self) -> IterMut<'_, T, S, A> {
654        IterMut::new(&self.tables, &mut self.items)
655    }
656
657    /// Checks general invariants of the map.
658    ///
659    /// The code below always upholds these invariants, but it's useful to have
660    /// an explicit check for tests.
661    #[doc(hidden)]
662    pub fn validate(
663        &self,
664        compactness: ValidateCompact,
665    ) -> Result<(), ValidationError>
666    where
667        T: fmt::Debug,
668    {
669        self.items.validate(compactness)?;
670        self.tables.validate(self.len(), compactness)?;
671
672        // Check that the indexes are all correct.
673        for (&ix, item) in self.items.iter() {
674            let key = item.key();
675            let Some(ix1) = self.find_index(&key) else {
676                return Err(ValidationError::general(format!(
677                    "item at index {ix} has no key1 index"
678                )));
679            };
680
681            if ix1 != ix {
682                return Err(ValidationError::General(format!(
683                    "item at index {ix} has mismatched indexes: ix1: {ix1}",
684                )));
685            }
686        }
687
688        Ok(())
689    }
690
691    /// Inserts a value into the map, removing and returning the conflicting
692    /// item, if any.
693    ///
694    /// # Examples
695    ///
696    /// ```
697    /// # #[cfg(feature = "default-hasher")] {
698    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
699    ///
700    /// #[derive(Debug, PartialEq, Eq, Hash)]
701    /// struct Item {
702    ///     id: String,
703    ///     value: u32,
704    /// }
705    ///
706    /// impl IdHashItem for Item {
707    ///     type Key<'a> = &'a str;
708    ///     fn key(&self) -> Self::Key<'_> {
709    ///         &self.id
710    ///     }
711    ///     id_upcast!();
712    /// }
713    ///
714    /// let mut map = IdHashMap::new();
715    ///
716    /// // First insertion returns None
717    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 42 });
718    /// assert!(old.is_none());
719    ///
720    /// // Second insertion with same key returns the old value
721    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 100 });
722    /// assert_eq!(old.unwrap().value, 42);
723    /// assert_eq!(map.get("foo").unwrap().value, 100);
724    /// # }
725    /// ```
726    #[doc(alias = "insert")]
727    pub fn insert_overwrite(&mut self, value: T) -> Option<T> {
728        // Trying to write this function for maximal efficiency can get very
729        // tricky, requiring delicate handling of indexes. We follow a very
730        // simple approach instead:
731        //
732        // 1. Remove items corresponding to the key that is already in the map.
733        // 2. Add the item to the map.
734
735        let duplicate = self.remove(&value.key());
736
737        if self.insert_unique(value).is_err() {
738            // We should never get here, because we just removed all the
739            // duplicates.
740            panic!("insert_unique failed after removing duplicates");
741        }
742
743        duplicate
744    }
745
746    /// Inserts a value into the set, returning an error if any duplicates were
747    /// added.
748    ///
749    /// # Examples
750    ///
751    /// ```
752    /// # #[cfg(feature = "default-hasher")] {
753    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
754    ///
755    /// #[derive(Debug, PartialEq, Eq, Hash)]
756    /// struct Item {
757    ///     id: String,
758    ///     value: u32,
759    /// }
760    ///
761    /// impl IdHashItem for Item {
762    ///     type Key<'a> = &'a str;
763    ///     fn key(&self) -> Self::Key<'_> {
764    ///         &self.id
765    ///     }
766    ///     id_upcast!();
767    /// }
768    ///
769    /// let mut map = IdHashMap::new();
770    ///
771    /// // First insertion succeeds
772    /// assert!(
773    ///     map.insert_unique(Item { id: "foo".to_string(), value: 42 }).is_ok()
774    /// );
775    ///
776    /// // Second insertion with different key succeeds
777    /// assert!(
778    ///     map.insert_unique(Item { id: "bar".to_string(), value: 20 }).is_ok()
779    /// );
780    ///
781    /// // Third insertion with duplicate key fails
782    /// assert!(
783    ///     map.insert_unique(Item { id: "foo".to_string(), value: 100 }).is_err()
784    /// );
785    /// # }
786    /// ```
787    pub fn insert_unique(
788        &mut self,
789        value: T,
790    ) -> Result<(), DuplicateItem<T, &T>> {
791        let _ = self.insert_unique_impl(value)?;
792        Ok(())
793    }
794
795    /// Returns true if the map contains the given key.
796    ///
797    /// # Examples
798    ///
799    /// ```
800    /// # #[cfg(feature = "default-hasher")] {
801    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
802    ///
803    /// #[derive(Debug, PartialEq, Eq, Hash)]
804    /// struct Item {
805    ///     id: String,
806    ///     value: u32,
807    /// }
808    ///
809    /// impl IdHashItem for Item {
810    ///     type Key<'a> = &'a str;
811    ///     fn key(&self) -> Self::Key<'_> {
812    ///         &self.id
813    ///     }
814    ///     id_upcast!();
815    /// }
816    ///
817    /// let mut map = IdHashMap::new();
818    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
819    ///
820    /// assert!(map.contains_key("foo"));
821    /// assert!(!map.contains_key("bar"));
822    /// # }
823    /// ```
824    pub fn contains_key<'a, Q>(&'a self, key1: &Q) -> bool
825    where
826        Q: ?Sized + Hash + Equivalent<T::Key<'a>>,
827    {
828        self.find_index(key1).is_some()
829    }
830
831    /// Gets a reference to the value associated with the given key.
832    ///
833    /// # Examples
834    ///
835    /// ```
836    /// # #[cfg(feature = "default-hasher")] {
837    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
838    ///
839    /// #[derive(Debug, PartialEq, Eq, Hash)]
840    /// struct Item {
841    ///     id: String,
842    ///     value: u32,
843    /// }
844    ///
845    /// impl IdHashItem for Item {
846    ///     type Key<'a> = &'a str;
847    ///     fn key(&self) -> Self::Key<'_> {
848    ///         &self.id
849    ///     }
850    ///     id_upcast!();
851    /// }
852    ///
853    /// let mut map = IdHashMap::new();
854    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
855    ///
856    /// assert_eq!(map.get("foo").unwrap().value, 42);
857    /// assert!(map.get("bar").is_none());
858    /// # }
859    /// ```
860    pub fn get<'a, Q>(&'a self, key: &Q) -> Option<&'a T>
861    where
862        Q: ?Sized + Hash + Equivalent<T::Key<'a>>,
863    {
864        self.find_index(key).map(|ix| &self.items[ix])
865    }
866
867    /// Gets a mutable reference to the value associated with the given key.
868    ///
869    /// # Examples
870    ///
871    /// ```
872    /// # #[cfg(feature = "default-hasher")] {
873    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
874    ///
875    /// #[derive(Debug, PartialEq, Eq, Hash)]
876    /// struct Item {
877    ///     id: String,
878    ///     value: u32,
879    /// }
880    ///
881    /// impl IdHashItem for Item {
882    ///     type Key<'a> = &'a str;
883    ///     fn key(&self) -> Self::Key<'_> {
884    ///         &self.id
885    ///     }
886    ///     id_upcast!();
887    /// }
888    ///
889    /// let mut map = IdHashMap::new();
890    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
891    ///
892    /// if let Some(mut item) = map.get_mut("foo") {
893    ///     item.value = 100;
894    /// }
895    ///
896    /// assert_eq!(map.get("foo").unwrap().value, 100);
897    /// assert!(map.get_mut("bar").is_none());
898    /// # }
899    /// ```
900    pub fn get_mut<'a, Q>(&'a mut self, key: &Q) -> Option<RefMut<'a, T, S>>
901    where
902        Q: ?Sized + Hash + Equivalent<T::Key<'a>>,
903    {
904        let (dormant_map, index) = {
905            let (map, dormant_map) = DormantMutRef::new(self);
906            let index = map.find_index(key)?;
907            (dormant_map, index)
908        };
909
910        // SAFETY: `map` is not used after this point.
911        let awakened_map = unsafe { dormant_map.awaken() };
912        let item = &mut awakened_map.items[index];
913        let hashes = awakened_map.tables.make_hash(item);
914        Some(RefMut::new(hashes, item))
915    }
916
917    /// Removes an item from the map by its key.
918    ///
919    /// # Examples
920    ///
921    /// ```
922    /// # #[cfg(feature = "default-hasher")] {
923    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
924    ///
925    /// #[derive(Debug, PartialEq, Eq, Hash)]
926    /// struct Item {
927    ///     id: String,
928    ///     value: u32,
929    /// }
930    ///
931    /// impl IdHashItem for Item {
932    ///     type Key<'a> = &'a str;
933    ///     fn key(&self) -> Self::Key<'_> {
934    ///         &self.id
935    ///     }
936    ///     id_upcast!();
937    /// }
938    ///
939    /// let mut map = IdHashMap::new();
940    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
941    ///
942    /// let removed = map.remove("foo");
943    /// assert_eq!(removed.unwrap().value, 42);
944    /// assert!(map.is_empty());
945    ///
946    /// // Removing non-existent key returns None
947    /// assert!(map.remove("bar").is_none());
948    /// # }
949    /// ```
950    pub fn remove<'a, Q>(&'a mut self, key: &Q) -> Option<T>
951    where
952        Q: ?Sized + Hash + Equivalent<T::Key<'a>>,
953    {
954        let (dormant_map, remove_index) = {
955            let (map, dormant_map) = DormantMutRef::new(self);
956            let remove_index = map.find_index(key)?;
957            (dormant_map, remove_index)
958        };
959
960        // SAFETY: `map` is not used after this point.
961        let awakened_map = unsafe { dormant_map.awaken() };
962
963        let value = awakened_map
964            .items
965            .remove(remove_index)
966            .expect("items missing key1 that was just retrieved");
967
968        // Remove the value from the tables.
969        let Ok(item1) =
970            awakened_map.tables.key_to_item.find_entry(&value.key(), |index| {
971                if index == remove_index {
972                    value.key()
973                } else {
974                    awakened_map.items[index].key()
975                }
976            })
977        else {
978            // The item was not found.
979            panic!("we just looked this item up");
980        };
981
982        item1.remove();
983
984        Some(value)
985    }
986
987    /// Retrieves an entry by its key.
988    ///
989    /// Due to borrow checker limitations, this always accepts an owned key
990    /// rather than a borrowed form of it.
991    ///
992    /// # Examples
993    ///
994    /// ```
995    /// # #[cfg(feature = "default-hasher")] {
996    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
997    ///
998    /// #[derive(Debug, PartialEq, Eq, Hash)]
999    /// struct Item {
1000    ///     id: String,
1001    ///     value: u32,
1002    /// }
1003    ///
1004    /// impl IdHashItem for Item {
1005    ///     type Key<'a> = &'a str;
1006    ///     fn key(&self) -> Self::Key<'_> {
1007    ///         &self.id
1008    ///     }
1009    ///     id_upcast!();
1010    /// }
1011    ///
1012    /// let mut map = IdHashMap::new();
1013    ///
1014    /// // Use entry API for conditional insertion
1015    /// map.entry("foo").or_insert(Item { id: "foo".to_string(), value: 42 });
1016    /// map.entry("bar").or_insert(Item { id: "bar".to_string(), value: 20 });
1017    ///
1018    /// assert_eq!(map.len(), 2);
1019    /// # }
1020    /// ```
1021    pub fn entry<'a>(&'a mut self, key: T::Key<'_>) -> Entry<'a, T, S, A> {
1022        // Why does this always take an owned key? Well, it would seem like we
1023        // should be able to pass in any Q that is equivalent. That results in
1024        // *this* code compiling fine, but callers have trouble using it because
1025        // the borrow checker believes the keys are borrowed for the full 'a
1026        // rather than a shorter lifetime.
1027        //
1028        // By accepting owned keys, we can use the upcast functions to convert
1029        // them to a shorter lifetime (so this function accepts T::Key<'_>
1030        // rather than T::Key<'a>).
1031        //
1032        // Really, the solution here is to allow GATs to require covariant
1033        // parameters. If that were allowed, the borrow checker should be able
1034        // to figure out that keys don't need to be borrowed for the full 'a,
1035        // just for some shorter lifetime.
1036        let (map, dormant_map) = DormantMutRef::new(self);
1037        let key = T::upcast_key(key);
1038        {
1039            // index is explicitly typed to show that it has a trivial Drop impl
1040            // that doesn't capture anything from map.
1041            let index: Option<usize> = map
1042                .tables
1043                .key_to_item
1044                .find_index(&key, |index| map.items[index].key());
1045            if let Some(index) = index {
1046                drop(key);
1047                return Entry::Occupied(
1048                    // SAFETY: `map` is not used after this point.
1049                    unsafe { OccupiedEntry::new(dormant_map, index) },
1050                );
1051            }
1052        }
1053        let hash = map.make_key_hash(&key);
1054        Entry::Vacant(
1055            // SAFETY: `map` is not used after this point.
1056            unsafe { VacantEntry::new(dormant_map, hash) },
1057        )
1058    }
1059
1060    fn find_index<'a, Q>(&'a self, k: &Q) -> Option<usize>
1061    where
1062        Q: Hash + Equivalent<T::Key<'a>> + ?Sized,
1063    {
1064        self.tables.key_to_item.find_index(k, |index| self.items[index].key())
1065    }
1066
1067    fn make_hash(&self, item: &T) -> MapHash<S> {
1068        self.tables.make_hash(item)
1069    }
1070
1071    fn make_key_hash(&self, key: &T::Key<'_>) -> MapHash<S> {
1072        self.tables.make_key_hash::<T>(key)
1073    }
1074
1075    pub(super) fn get_by_index(&self, index: usize) -> Option<&T> {
1076        self.items.get(index)
1077    }
1078
1079    pub(super) fn get_by_index_mut(
1080        &mut self,
1081        index: usize,
1082    ) -> Option<RefMut<'_, T, S>> {
1083        let hashes = self.make_hash(&self.items[index]);
1084        let item = &mut self.items[index];
1085        Some(RefMut::new(hashes, item))
1086    }
1087
1088    pub(super) fn insert_unique_impl(
1089        &mut self,
1090        value: T,
1091    ) -> Result<usize, DuplicateItem<T, &T>> {
1092        let mut duplicates = BTreeSet::new();
1093
1094        // Check for duplicates *before* inserting the new item, because we
1095        // don't want to partially insert the new item and then have to roll
1096        // back.
1097        let key = value.key();
1098
1099        let entry = match self
1100            .tables
1101            .key_to_item
1102            .entry(key, |index| self.items[index].key())
1103        {
1104            hash_table::Entry::Occupied(slot) => {
1105                duplicates.insert(*slot.get());
1106                None
1107            }
1108            hash_table::Entry::Vacant(slot) => Some(slot),
1109        };
1110
1111        if !duplicates.is_empty() {
1112            return Err(DuplicateItem::__internal_new(
1113                value,
1114                duplicates.iter().map(|ix| &self.items[*ix]).collect(),
1115            ));
1116        }
1117
1118        let next_index = self.items.insert_at_next_index(value);
1119        entry.unwrap().insert(next_index);
1120
1121        Ok(next_index)
1122    }
1123
1124    pub(super) fn remove_by_index(&mut self, remove_index: usize) -> Option<T> {
1125        let value = self.items.remove(remove_index)?;
1126
1127        // Remove the value from the tables.
1128        let Ok(item) =
1129            self.tables.key_to_item.find_entry(&value.key(), |index| {
1130                if index == remove_index {
1131                    value.key()
1132                } else {
1133                    self.items[index].key()
1134                }
1135            })
1136        else {
1137            // The item was not found.
1138            panic!("we just looked this item up");
1139        };
1140
1141        item.remove();
1142
1143        Some(value)
1144    }
1145
1146    pub(super) fn replace_at_index(&mut self, index: usize, value: T) -> T {
1147        // We check the key before removing it, to avoid leaving the map in an
1148        // inconsistent state.
1149        let old_key =
1150            self.get_by_index(index).expect("index is known to be valid").key();
1151        if T::upcast_key(old_key) != value.key() {
1152            panic!(
1153                "must insert a value with \
1154                 the same key used to create the entry"
1155            );
1156        }
1157
1158        // Now that we know the key is the same, we can replace the value
1159        // directly without needing to tweak any tables.
1160        self.items.replace(index, value)
1161    }
1162}
1163
1164impl<'a, T, S: Clone + BuildHasher, A: Allocator> fmt::Debug
1165    for IdHashMap<T, S, A>
1166where
1167    T: IdHashItem + fmt::Debug,
1168    T::Key<'a>: fmt::Debug,
1169    T: 'a,
1170{
1171    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1172        let mut map = f.debug_map();
1173
1174        for item in self.iter() {
1175            let key = item.key();
1176
1177            // SAFETY:
1178            //
1179            // * Lifetime extension: for a type T and two lifetime params 'a and
1180            //   'b, T<'a> and T<'b> aren't guaranteed to have the same layout,
1181            //   but (a) that is true today and (b) it would be shocking and
1182            //   break half the Rust ecosystem if that were to change in the
1183            //   future.
1184            // * We only use key within the scope of this block before immediately
1185            //   dropping it. In particular, map.entry calls key.fmt() without
1186            //   holding a reference to it.
1187            let key: T::Key<'a> =
1188                unsafe { core::mem::transmute::<T::Key<'_>, T::Key<'a>>(key) };
1189
1190            map.entry(&key, item);
1191        }
1192        map.finish()
1193    }
1194}
1195
1196impl<T: IdHashItem + PartialEq, S: Clone + BuildHasher, A: Allocator> PartialEq
1197    for IdHashMap<T, S, A>
1198{
1199    fn eq(&self, other: &Self) -> bool {
1200        // Implementing PartialEq for IdHashMap is tricky because IdHashMap is
1201        // not semantically like an IndexMap: two maps are equivalent even if
1202        // their items are in a different order. In other words, any permutation
1203        // of items is equivalent.
1204        //
1205        // We also can't sort the items because they're not necessarily Ord.
1206        //
1207        // So we write a custom equality check that checks that each key in one
1208        // map points to the same item as in the other map.
1209
1210        if self.items.len() != other.items.len() {
1211            return false;
1212        }
1213
1214        // Walk over all the items in the first map and check that they point to
1215        // the same item in the second map.
1216        for item in self.items.values() {
1217            let k1 = item.key();
1218
1219            // Check that the indexes are the same in the other map.
1220            let Some(other_ix) = other.find_index(&k1) else {
1221                return false;
1222            };
1223
1224            // Check that the other map's item is the same as this map's
1225            // item. (This is what we use the `PartialEq` bound on T for.)
1226            //
1227            // Because we've checked that other_ix is Some, we know that it is
1228            // valid and points to the expected item.
1229            let other_item = &other.items[other_ix];
1230            if item != other_item {
1231                return false;
1232            }
1233        }
1234
1235        true
1236    }
1237}
1238
1239// The Eq bound on T ensures that the TriHashMap forms an equivalence class.
1240impl<T: IdHashItem + Eq, S: Clone + BuildHasher, A: Allocator> Eq
1241    for IdHashMap<T, S, A>
1242{
1243}
1244
1245/// The `Extend` implementation overwrites duplicates. In the future, there will
1246/// also be an `extend_unique` method that will return an error.
1247///
1248/// # Examples
1249///
1250/// ```
1251/// # #[cfg(feature = "default-hasher")] {
1252/// use iddqd::{IdHashItem, IdHashMap, id_upcast};
1253///
1254/// #[derive(Debug, PartialEq, Eq, Hash)]
1255/// struct Item {
1256///     id: String,
1257///     value: u32,
1258/// }
1259///
1260/// impl IdHashItem for Item {
1261///     type Key<'a> = &'a str;
1262///     fn key(&self) -> Self::Key<'_> {
1263///         &self.id
1264///     }
1265///     id_upcast!();
1266/// }
1267///
1268/// let mut map = IdHashMap::new();
1269/// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
1270///
1271/// let new_items = vec![
1272///     Item { id: "foo".to_string(), value: 100 }, // overwrites existing
1273///     Item { id: "bar".to_string(), value: 20 },  // new item
1274/// ];
1275///
1276/// map.extend(new_items);
1277/// assert_eq!(map.len(), 2);
1278/// assert_eq!(map.get("foo").unwrap().value, 100); // overwritten
1279/// assert_eq!(map.get("bar").unwrap().value, 20); // new
1280///
1281/// # }
1282/// ```
1283impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> Extend<T>
1284    for IdHashMap<T, S, A>
1285{
1286    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1287        for item in iter {
1288            self.insert_overwrite(item);
1289        }
1290    }
1291}
1292
1293impl<'a, T: IdHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator
1294    for &'a IdHashMap<T, S, A>
1295{
1296    type Item = &'a T;
1297    type IntoIter = Iter<'a, T>;
1298
1299    /// Creates an iterator over references to the items in the map.
1300    ///
1301    /// # Examples
1302    ///
1303    /// ```
1304    /// # #[cfg(feature = "default-hasher")] {
1305    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
1306    ///
1307    /// #[derive(Debug, PartialEq, Eq, Hash)]
1308    /// struct Item {
1309    ///     id: String,
1310    ///     value: u32,
1311    /// }
1312    ///
1313    /// impl IdHashItem for Item {
1314    ///     type Key<'a> = &'a str;
1315    ///     fn key(&self) -> Self::Key<'_> {
1316    ///         &self.id
1317    ///     }
1318    ///     id_upcast!();
1319    /// }
1320    ///
1321    /// let mut map = IdHashMap::new();
1322    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
1323    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
1324    ///
1325    /// let mut values: Vec<u32> =
1326    ///     (&map).into_iter().map(|item| item.value).collect();
1327    /// values.sort();
1328    /// assert_eq!(values, vec![20, 42]);
1329    /// # }
1330    /// ```
1331    #[inline]
1332    fn into_iter(self) -> Self::IntoIter {
1333        self.iter()
1334    }
1335}
1336
1337impl<'a, T: IdHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator
1338    for &'a mut IdHashMap<T, S, A>
1339{
1340    type Item = RefMut<'a, T, S>;
1341    type IntoIter = IterMut<'a, T, S, A>;
1342
1343    /// Creates an iterator over mutable references to the items in the map.
1344    ///
1345    /// # Examples
1346    ///
1347    /// ```
1348    /// # #[cfg(feature = "default-hasher")] {
1349    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
1350    ///
1351    /// #[derive(Debug, PartialEq, Eq, Hash)]
1352    /// struct Item {
1353    ///     id: String,
1354    ///     value: u32,
1355    /// }
1356    ///
1357    /// impl IdHashItem for Item {
1358    ///     type Key<'a> = &'a str;
1359    ///     fn key(&self) -> Self::Key<'_> {
1360    ///         &self.id
1361    ///     }
1362    ///     id_upcast!();
1363    /// }
1364    ///
1365    /// let mut map = IdHashMap::new();
1366    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
1367    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
1368    ///
1369    /// for mut item in &mut map {
1370    ///     item.value *= 2;
1371    /// }
1372    ///
1373    /// assert_eq!(map.get("foo").unwrap().value, 84);
1374    /// assert_eq!(map.get("bar").unwrap().value, 40);
1375    /// # }
1376    /// ```
1377    #[inline]
1378    fn into_iter(self) -> Self::IntoIter {
1379        self.iter_mut()
1380    }
1381}
1382
1383impl<T: IdHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator
1384    for IdHashMap<T, S, A>
1385{
1386    type Item = T;
1387    type IntoIter = IntoIter<T, A>;
1388
1389    /// Consumes the map and creates an iterator over the owned items.
1390    ///
1391    /// # Examples
1392    ///
1393    /// ```
1394    /// # #[cfg(feature = "default-hasher")] {
1395    /// use iddqd::{IdHashItem, IdHashMap, id_upcast};
1396    ///
1397    /// #[derive(Debug, PartialEq, Eq, Hash)]
1398    /// struct Item {
1399    ///     id: String,
1400    ///     value: u32,
1401    /// }
1402    ///
1403    /// impl IdHashItem for Item {
1404    ///     type Key<'a> = &'a str;
1405    ///     fn key(&self) -> Self::Key<'_> {
1406    ///         &self.id
1407    ///     }
1408    ///     id_upcast!();
1409    /// }
1410    ///
1411    /// let mut map = IdHashMap::new();
1412    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
1413    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
1414    ///
1415    /// let mut values: Vec<u32> = map.into_iter().map(|item| item.value).collect();
1416    /// values.sort();
1417    /// assert_eq!(values, vec![20, 42]);
1418    /// # }
1419    /// ```
1420    #[inline]
1421    fn into_iter(self) -> Self::IntoIter {
1422        IntoIter::new(self.items)
1423    }
1424}
1425
1426/// The `FromIterator` implementation for `IdHashMap` overwrites duplicate
1427/// items.
1428///
1429/// # Examples
1430///
1431/// ```
1432/// # #[cfg(feature = "default-hasher")] {
1433/// use iddqd::{IdHashItem, IdHashMap, id_upcast};
1434///
1435/// #[derive(Debug, PartialEq, Eq, Hash)]
1436/// struct Item {
1437///     id: String,
1438///     value: u32,
1439/// }
1440///
1441/// impl IdHashItem for Item {
1442///     type Key<'a> = &'a str;
1443///     fn key(&self) -> Self::Key<'_> {
1444///         &self.id
1445///     }
1446///     id_upcast!();
1447/// }
1448///
1449/// let items = vec![
1450///     Item { id: "foo".to_string(), value: 42 },
1451///     Item { id: "bar".to_string(), value: 20 },
1452///     Item { id: "foo".to_string(), value: 100 }, // duplicate key, overwrites
1453/// ];
1454///
1455/// let map: IdHashMap<Item> = items.into_iter().collect();
1456/// assert_eq!(map.len(), 2);
1457/// assert_eq!(map.get("foo").unwrap().value, 100); // last value wins
1458/// assert_eq!(map.get("bar").unwrap().value, 20);
1459/// # }
1460/// ```
1461impl<T: IdHashItem, S: Default + Clone + BuildHasher, A: Allocator + Default>
1462    FromIterator<T> for IdHashMap<T, S, A>
1463{
1464    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1465        let mut map = IdHashMap::default();
1466        for item in iter {
1467            map.insert_overwrite(item);
1468        }
1469        map
1470    }
1471}