[go: up one dir, main page]

imbl/hash/
map.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5//! An unordered map.
6//!
7//! An immutable hash map using [hash array mapped tries][1].
8//!
9//! Most operations on this map are O(log<sub>x</sub> n) for a
10//! suitably high *x* that it should be nearly O(1) for most maps.
11//! Because of this, it's a great choice for a generic map as long as
12//! you don't mind that keys will need to implement
13//! [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq].
14//!
15//! Map entries will have a predictable order based on the hasher
16//! being used. Unless otherwise specified, this will be the standard
17//! [`RandomState`][std::collections::hash_map::RandomState] hasher.
18//!
19//! [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
20//! [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
21//! [std::hash::Hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html
22//! [std::collections::hash_map::RandomState]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
23
24use std::borrow::Borrow;
25use std::collections;
26use std::collections::hash_map::RandomState;
27use std::fmt::{Debug, Error, Formatter};
28use std::hash::{BuildHasher, Hash};
29use std::iter::{FromIterator, FusedIterator, Sum};
30use std::mem;
31use std::ops::{Add, Index, IndexMut};
32
33use archery::{SharedPointer, SharedPointerKind};
34
35use crate::nodes::hamt::{
36    hash_key, Drain as NodeDrain, HashBits, HashValue, Iter as NodeIter, IterMut as NodeIterMut,
37    Node,
38};
39use crate::shared_ptr::DefaultSharedPtr;
40
41/// Construct a hash map from a sequence of key/value pairs.
42///
43/// # Examples
44///
45/// ```
46/// # #[macro_use] extern crate imbl;
47/// # use imbl::HashMap;
48/// # fn main() {
49/// assert_eq!(
50///   hashmap!{
51///     1 => 11,
52///     2 => 22,
53///     3 => 33
54///   },
55///   HashMap::from(vec![(1, 11), (2, 22), (3, 33)])
56/// );
57/// # }
58/// ```
59#[macro_export]
60macro_rules! hashmap {
61    () => { $crate::hashmap::HashMap::new() };
62
63    ( $( $key:expr => $value:expr ),* ) => {{
64        let mut map = $crate::hashmap::HashMap::new();
65        $({
66            map.insert($key, $value);
67        })*;
68        map
69    }};
70
71    ( $( $key:expr => $value:expr ,)* ) => {{
72        let mut map = $crate::hashmap::HashMap::new();
73        $({
74            map.insert($key, $value);
75        })*;
76        map
77    }};
78}
79
80/// Type alias for [`GenericHashMap`] that uses [`std::hash::RandomState`] as the default hasher and [`DefaultSharedPtr`] as the pointer type.
81///
82/// [GenericHashMap]: ./struct.GenericHashMap.html
83/// [`std::hash::RandomState`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.RandomState.html
84/// [DefaultSharedPtr]: ../shared_ptr/type.DefaultSharedPtr.html
85pub type HashMap<K, V> = GenericHashMap<K, V, RandomState, DefaultSharedPtr>;
86
87/// An unordered map.
88///
89/// An immutable hash map using [hash array mapped tries] [1].
90///
91/// Most operations on this map are O(log<sub>x</sub> n) for a
92/// suitably high *x* that it should be nearly O(1) for most maps.
93/// Because of this, it's a great choice for a generic map as long as
94/// you don't mind that keys will need to implement
95/// [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq].
96///
97/// Map entries will have a predictable order based on the hasher
98/// being used. Unless otherwise specified, this will be the standard
99/// [`RandomState`][std::collections::hash_map::RandomState] hasher.
100///
101/// [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
102/// [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
103/// [std::hash::Hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html
104/// [std::collections::hash_map::RandomState]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
105
106pub struct GenericHashMap<K, V, S, P: SharedPointerKind> {
107    size: usize,
108    root: Option<SharedPointer<Node<(K, V), P>, P>>,
109    hasher: S,
110}
111
112impl<K, V> HashValue for (K, V)
113where
114    K: Eq,
115{
116    type Key = K;
117
118    fn extract_key(&self) -> &Self::Key {
119        &self.0
120    }
121
122    fn ptr_eq(&self, _other: &Self) -> bool {
123        false
124    }
125}
126
127impl<K, V, P> GenericHashMap<K, V, RandomState, P>
128where
129    K: Hash + Eq + Clone,
130    V: Clone,
131    P: SharedPointerKind,
132{
133    /// Construct a hash map with a single mapping.
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// # #[macro_use] extern crate imbl;
139    /// # use imbl::HashMap;
140    /// let map = HashMap::unit(123, "onetwothree");
141    /// assert_eq!(
142    ///   map.get(&123),
143    ///   Some(&"onetwothree")
144    /// );
145    /// ```
146    #[inline]
147    #[must_use]
148    pub fn unit(k: K, v: V) -> GenericHashMap<K, V, RandomState, P> {
149        GenericHashMap::new().update(k, v)
150    }
151}
152
153impl<K, V, S, P: SharedPointerKind> GenericHashMap<K, V, S, P> {
154    /// Construct an empty hash map.
155    #[inline]
156    #[must_use]
157    pub fn new() -> Self
158    where
159        S: Default,
160    {
161        Self::default()
162    }
163
164    /// Test whether a hash map is empty.
165    ///
166    /// Time: O(1)
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// # #[macro_use] extern crate imbl;
172    /// # use imbl::hashmap::HashMap;
173    /// assert!(
174    ///   !hashmap!{1 => 2}.is_empty()
175    /// );
176    /// assert!(
177    ///   HashMap::<i32, i32>::new().is_empty()
178    /// );
179    /// ```
180    #[inline]
181    #[must_use]
182    pub fn is_empty(&self) -> bool {
183        self.len() == 0
184    }
185
186    /// Get the size of a hash map.
187    ///
188    /// Time: O(1)
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// # #[macro_use] extern crate imbl;
194    /// # use imbl::hashmap::HashMap;
195    /// assert_eq!(3, hashmap!{
196    ///   1 => 11,
197    ///   2 => 22,
198    ///   3 => 33
199    /// }.len());
200    /// ```
201    #[inline]
202    #[must_use]
203    pub fn len(&self) -> usize {
204        self.size
205    }
206
207    /// Test whether two maps refer to the same content in memory.
208    ///
209    /// This is true if the two sides are references to the same map,
210    /// or if the two maps refer to the same root node.
211    ///
212    /// This would return true if you're comparing a map to itself, or
213    /// if you're comparing a map to a fresh clone of itself.
214    ///
215    /// Time: O(1)
216    pub fn ptr_eq(&self, other: &Self) -> bool {
217        match (&self.root, &other.root) {
218            (Some(a), Some(b)) => SharedPointer::ptr_eq(a, b),
219            (None, None) => true,
220            _ => false,
221        }
222    }
223
224    /// Construct an empty hash map using the provided hasher.
225    #[inline]
226    #[must_use]
227    pub fn with_hasher(hasher: S) -> Self {
228        GenericHashMap {
229            size: 0,
230            hasher,
231            root: None,
232        }
233    }
234
235    /// Get a reference to the map's [`BuildHasher`][BuildHasher].
236    ///
237    /// [BuildHasher]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
238    #[must_use]
239    pub fn hasher(&self) -> &S {
240        &self.hasher
241    }
242
243    /// Construct an empty hash map using the same hasher as the
244    /// current hash map.
245    #[inline]
246    #[must_use]
247    pub fn new_from<K1, V1>(&self) -> GenericHashMap<K1, V1, S, P>
248    where
249        K1: Hash + Eq + Clone,
250        V1: Clone,
251        S: Clone,
252    {
253        GenericHashMap {
254            size: 0,
255            root: None,
256            hasher: self.hasher.clone(),
257        }
258    }
259
260    /// Get an iterator over the key/value pairs of a hash map.
261    ///
262    /// Please note that the order is consistent between maps using
263    /// the same hasher, but no other ordering guarantee is offered.
264    /// Items will not come out in insertion order or sort order.
265    /// They will, however, come out in the same order every time for
266    /// the same map.
267    #[inline]
268    #[must_use]
269    pub fn iter(&self) -> Iter<'_, K, V, P> {
270        Iter {
271            it: NodeIter::new(self.root.as_deref(), self.size),
272        }
273    }
274
275    /// Get an iterator over a hash map's keys.
276    ///
277    /// Please note that the order is consistent between maps using
278    /// the same hasher, but no other ordering guarantee is offered.
279    /// Items will not come out in insertion order or sort order.
280    /// They will, however, come out in the same order every time for
281    /// the same map.
282    #[inline]
283    #[must_use]
284    pub fn keys(&self) -> Keys<'_, K, V, P> {
285        Keys {
286            it: NodeIter::new(self.root.as_deref(), self.size),
287        }
288    }
289
290    /// Get an iterator over a hash map's values.
291    ///
292    /// Please note that the order is consistent between maps using
293    /// the same hasher, but no other ordering guarantee is offered.
294    /// Items will not come out in insertion order or sort order.
295    /// They will, however, come out in the same order every time for
296    /// the same map.
297    #[inline]
298    #[must_use]
299    pub fn values(&self) -> Values<'_, K, V, P> {
300        Values {
301            it: NodeIter::new(self.root.as_deref(), self.size),
302        }
303    }
304
305    /// Discard all elements from the map.
306    ///
307    /// This leaves you with an empty map, and all elements that
308    /// were previously inside it are dropped.
309    ///
310    /// Time: O(n)
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// # #[macro_use] extern crate imbl;
316    /// # use imbl::HashMap;
317    /// let mut map = hashmap![1=>1, 2=>2, 3=>3];
318    /// map.clear();
319    /// assert!(map.is_empty());
320    /// ```
321    pub fn clear(&mut self) {
322        self.root = None;
323        self.size = 0;
324    }
325
326    /// Print a summary of the HashMap structure showing per-level statistics.
327    /// This includes the number of nodes at each level and the distribution of child types.
328    #[cfg(test)]
329    pub fn print_structure_summary(&self) {
330        use crate::nodes::hamt::Entry as NodeEntry;
331        use std::collections::VecDeque;
332
333        println!("HashMap Structure Summary:");
334
335        #[derive(Default, Debug)]
336        struct LevelStats {
337            node_count: usize,
338            value_count: usize,
339            collision_count: usize,
340            collision_entry_sum: usize,
341            child_node_count: usize,
342            small_node_count: usize,
343            small_node_entry_sum: usize,
344            total_entries: usize,
345        }
346
347        if self.root.is_none() {
348            println!("  Empty HashMap (no root node)");
349            println!("  Total entries: 0");
350            return;
351        }
352
353        let mut level_stats: Vec<LevelStats> = Vec::new();
354        let mut queue: VecDeque<(usize, SharedPointer<Node<(K, V), P>, P>)> = VecDeque::new();
355
356        // Start with root node at level 0
357        if let Some(ref root) = self.root {
358            queue.push_back((0, root.clone()));
359        }
360
361        // BFS traversal to collect statistics
362        while let Some((level, node)) = queue.pop_front() {
363            // Ensure we have stats for this level
364            while level_stats.len() <= level {
365                level_stats.push(LevelStats::default());
366            }
367
368            let stats = &mut level_stats[level];
369            stats.node_count += 1;
370
371            // Analyze this node's entries
372            node.analyze_structure(|entry| {
373                stats.total_entries += 1;
374                match entry {
375                    NodeEntry::Value(_, _) => stats.value_count += 1,
376                    NodeEntry::Collision(_coll) => {
377                        stats.collision_count += 1;
378                        // stats.collision_entry_sum += coll.len();
379                    }
380                    NodeEntry::Node(child_node) => {
381                        stats.child_node_count += 1;
382                        queue.push_back((level + 1, child_node.clone()));
383                    }
384                    NodeEntry::SmallNode(small_node) => {
385                        stats.small_node_count += 1;
386                        stats.small_node_entry_sum += small_node.len();
387                    }
388                }
389            })
390        }
391
392        // Print the summary
393        println!(
394            "  Hash level size (bits): {}",
395            crate::config::HASH_LEVEL_SIZE
396        );
397        println!(
398            "  Branching factor: {}",
399            2_usize.pow(crate::config::HASH_LEVEL_SIZE as u32)
400        );
401        println!("  Total entries: {}", self.size);
402        println!("  Tree depth: {} levels", level_stats.len());
403        println!();
404
405        for (level, stats) in level_stats.iter().enumerate() {
406            println!("  Level {}:", level);
407            println!("    Nodes: {}", stats.node_count);
408
409            if stats.total_entries > 0 {
410                let avg_entries = stats.total_entries as f64 / stats.node_count as f64;
411                println!("    Average entries per node: {:.2}", avg_entries);
412
413                println!("    Entry types:");
414                println!(
415                    "      Values: {} ({:.1}%)",
416                    stats.value_count,
417                    (stats.value_count as f64 / stats.total_entries as f64) * 100.0
418                );
419                println!(
420                    "      Collisions: {} (avg len: {:.1}) ({:.1}%)",
421                    stats.collision_count,
422                    if stats.collision_count > 0 {
423                        stats.collision_entry_sum as f64 / stats.collision_count as f64
424                    } else {
425                        0.0
426                    },
427                    (stats.collision_count as f64 / stats.total_entries as f64) * 100.0
428                );
429                println!(
430                    "      Child nodes: {} ({:.1}%)",
431                    stats.child_node_count,
432                    (stats.child_node_count as f64 / stats.total_entries as f64) * 100.0
433                );
434                println!(
435                    "      Small nodes: {} ({:.1}%)",
436                    stats.small_node_count,
437                    (stats.small_node_count as f64 / stats.total_entries as f64) * 100.0
438                );
439                if stats.small_node_count > 0 {
440                    println!(
441                        "        → Avg entries per small node: {:.1}",
442                        stats.small_node_entry_sum as f64 / stats.small_node_count as f64
443                    );
444                }
445            }
446            println!();
447        }
448    }
449}
450
451impl<K, V, S, P> GenericHashMap<K, V, S, P>
452where
453    K: Hash + Eq,
454    S: BuildHasher + Clone,
455    P: SharedPointerKind,
456{
457    fn test_eq<S2: BuildHasher + Clone, P2: SharedPointerKind>(
458        &self,
459        other: &GenericHashMap<K, V, S2, P2>,
460    ) -> bool
461    where
462        V: PartialEq,
463    {
464        if self.len() != other.len() {
465            return false;
466        }
467        let mut seen = collections::HashSet::new();
468        for (key, value) in self.iter() {
469            if Some(value) != other.get(key) {
470                return false;
471            }
472            seen.insert(key);
473        }
474        for key in other.keys() {
475            if !seen.contains(&key) {
476                return false;
477            }
478        }
479        true
480    }
481
482    /// Get the value for a key from a hash map.
483    ///
484    /// Time: O(log n)
485    ///
486    /// # Examples
487    ///
488    /// ```
489    /// # #[macro_use] extern crate imbl;
490    /// # use imbl::hashmap::HashMap;
491    /// let map = hashmap!{123 => "lol"};
492    /// assert_eq!(
493    ///   map.get(&123),
494    ///   Some(&"lol")
495    /// );
496    /// ```
497    #[must_use]
498    pub fn get<BK>(&self, key: &BK) -> Option<&V>
499    where
500        BK: Hash + Eq + ?Sized,
501        K: Borrow<BK>,
502    {
503        if let Some(root) = &self.root {
504            root.get(hash_key(&self.hasher, key), 0, key)
505                .map(|(_, v)| v)
506        } else {
507            None
508        }
509    }
510
511    /// Get the key/value pair for a key from a hash map.
512    ///
513    /// Time: O(log n)
514    ///
515    /// # Examples
516    ///
517    /// ```
518    /// # #[macro_use] extern crate imbl;
519    /// # use imbl::hashmap::HashMap;
520    /// let map = hashmap!{123 => "lol"};
521    /// assert_eq!(
522    ///   map.get_key_value(&123),
523    ///   Some((&123, &"lol"))
524    /// );
525    /// ```
526    #[must_use]
527    pub fn get_key_value<BK>(&self, key: &BK) -> Option<(&K, &V)>
528    where
529        BK: Hash + Eq + ?Sized,
530        K: Borrow<BK>,
531    {
532        if let Some(root) = &self.root {
533            root.get(hash_key(&self.hasher, key), 0, key)
534                .map(|(k, v)| (k, v))
535        } else {
536            None
537        }
538    }
539
540    /// Test for the presence of a key in a hash map.
541    ///
542    /// Time: O(log n)
543    ///
544    /// # Examples
545    ///
546    /// ```
547    /// # #[macro_use] extern crate imbl;
548    /// # use imbl::hashmap::HashMap;
549    /// let map = hashmap!{123 => "lol"};
550    /// assert!(
551    ///   map.contains_key(&123)
552    /// );
553    /// assert!(
554    ///   !map.contains_key(&321)
555    /// );
556    /// ```
557    #[inline]
558    #[must_use]
559    pub fn contains_key<BK>(&self, k: &BK) -> bool
560    where
561        BK: Hash + Eq + ?Sized,
562        K: Borrow<BK>,
563    {
564        self.get(k).is_some()
565    }
566
567    /// Test whether a map is a submap of another map, meaning that
568    /// all keys in our map must also be in the other map, with the
569    /// same values.
570    ///
571    /// Use the provided function to decide whether values are equal.
572    ///
573    /// Time: O(n log n)
574    #[must_use]
575    pub fn is_submap_by<B, RM, F, P2: SharedPointerKind>(&self, other: RM, mut cmp: F) -> bool
576    where
577        F: FnMut(&V, &B) -> bool,
578        RM: Borrow<GenericHashMap<K, B, S, P2>>,
579    {
580        self.iter()
581            .all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false))
582    }
583
584    /// Test whether a map is a proper submap of another map, meaning
585    /// that all keys in our map must also be in the other map, with
586    /// the same values. To be a proper submap, ours must also contain
587    /// fewer keys than the other map.
588    ///
589    /// Use the provided function to decide whether values are equal.
590    ///
591    /// Time: O(n log n)
592    #[must_use]
593    pub fn is_proper_submap_by<B, RM, F, P2: SharedPointerKind>(&self, other: RM, cmp: F) -> bool
594    where
595        F: FnMut(&V, &B) -> bool,
596        RM: Borrow<GenericHashMap<K, B, S, P2>>,
597    {
598        self.len() != other.borrow().len() && self.is_submap_by(other, cmp)
599    }
600
601    /// Test whether a map is a submap of another map, meaning that
602    /// all keys in our map must also be in the other map, with the
603    /// same values.
604    ///
605    /// Time: O(n log n)
606    ///
607    /// # Examples
608    ///
609    /// ```
610    /// # #[macro_use] extern crate imbl;
611    /// # use imbl::hashmap::HashMap;
612    /// let map1 = hashmap!{1 => 1, 2 => 2};
613    /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3};
614    /// assert!(map1.is_submap(map2));
615    /// ```
616    #[inline]
617    #[must_use]
618    pub fn is_submap<RM>(&self, other: RM) -> bool
619    where
620        V: PartialEq,
621        RM: Borrow<Self>,
622    {
623        self.is_submap_by(other.borrow(), PartialEq::eq)
624    }
625
626    /// Test whether a map is a proper submap of another map, meaning
627    /// that all keys in our map must also be in the other map, with
628    /// the same values. To be a proper submap, ours must also contain
629    /// fewer keys than the other map.
630    ///
631    /// Time: O(n log n)
632    ///
633    /// # Examples
634    ///
635    /// ```
636    /// # #[macro_use] extern crate imbl;
637    /// # use imbl::hashmap::HashMap;
638    /// let map1 = hashmap!{1 => 1, 2 => 2};
639    /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3};
640    /// assert!(map1.is_proper_submap(map2));
641    ///
642    /// let map3 = hashmap!{1 => 1, 2 => 2};
643    /// let map4 = hashmap!{1 => 1, 2 => 2};
644    /// assert!(!map3.is_proper_submap(map4));
645    /// ```
646    #[inline]
647    #[must_use]
648    pub fn is_proper_submap<RM>(&self, other: RM) -> bool
649    where
650        V: PartialEq,
651        RM: Borrow<Self>,
652    {
653        self.is_proper_submap_by(other.borrow(), PartialEq::eq)
654    }
655}
656
657impl<K, V, S, P> GenericHashMap<K, V, S, P>
658where
659    K: Hash + Eq + Clone,
660    V: Clone,
661    S: BuildHasher + Clone,
662    P: SharedPointerKind,
663{
664    /// Get a mutable iterator over the values of a hash map.
665    ///
666    /// Please note that the order is consistent between maps using
667    /// the same hasher, but no other ordering guarantee is offered.
668    /// Items will not come out in insertion order or sort order.
669    /// They will, however, come out in the same order every time for
670    /// the same map.
671    #[inline]
672    #[must_use]
673    pub fn iter_mut(&mut self) -> IterMut<'_, K, V, P> {
674        let root = self.root.as_mut().map(|r| SharedPointer::make_mut(r));
675        IterMut {
676            it: NodeIterMut::new(root, self.size),
677        }
678    }
679
680    /// Get a mutable reference to the value for a key from a hash
681    /// map.
682    ///
683    /// Time: O(log n)
684    ///
685    /// # Examples
686    ///
687    /// ```
688    /// # #[macro_use] extern crate imbl;
689    /// # use imbl::hashmap::HashMap;
690    /// let mut map = hashmap!{123 => "lol"};
691    /// if let Some(value) = map.get_mut(&123) {
692    ///     *value = "omg";
693    /// }
694    /// assert_eq!(
695    ///   map.get(&123),
696    ///   Some(&"omg")
697    /// );
698    /// ```
699    #[must_use]
700    pub fn get_mut<BK>(&mut self, key: &BK) -> Option<&mut V>
701    where
702        BK: Hash + Eq + ?Sized,
703        K: Borrow<BK>,
704    {
705        self.get_key_value_mut(key).map(|(_, v)| v)
706    }
707
708    /// Get the key/value pair for a key from a hash map, returning a mutable reference to the value.
709    ///
710    /// Time: O(log n)
711    ///
712    /// # Examples
713    ///
714    /// ```
715    /// # #[macro_use] extern crate imbl;
716    /// # use imbl::hashmap::HashMap;
717    /// let mut map = hashmap!{123 => "lol"};
718    /// assert_eq!(
719    ///   map.get_key_value_mut(&123),
720    ///   Some((&123, &mut "lol"))
721    /// );
722    /// ```
723    #[must_use]
724    pub fn get_key_value_mut<BK>(&mut self, key: &BK) -> Option<(&K, &mut V)>
725    where
726        BK: Hash + Eq + ?Sized,
727        K: Borrow<BK>,
728    {
729        let Some(root) = self.root.as_mut() else {
730            return None;
731        };
732        match SharedPointer::make_mut(root).get_mut(hash_key(&self.hasher, key), 0, key) {
733            None => None,
734            Some((key, value)) => Some((key, value)),
735        }
736    }
737
738    /// Insert a key/value mapping into a map.
739    ///
740    /// If the map already has a mapping for the given key, the
741    /// previous value is overwritten.
742    ///
743    /// Time: O(log n)
744    ///
745    /// # Examples
746    ///
747    /// ```
748    /// # #[macro_use] extern crate imbl;
749    /// # use imbl::hashmap::HashMap;
750    /// let mut map = hashmap!{};
751    /// map.insert(123, "123");
752    /// map.insert(456, "456");
753    /// assert_eq!(
754    ///   map,
755    ///   hashmap!{123 => "123", 456 => "456"}
756    /// );
757    /// ```
758    #[inline]
759    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
760        let hash = hash_key(&self.hasher, &k);
761        let root = SharedPointer::make_mut(self.root.get_or_insert_with(SharedPointer::default));
762        let result = root.insert(hash, 0, (k, v));
763        if result.is_none() {
764            self.size += 1;
765        }
766        result.map(|(_, v)| v)
767    }
768
769    /// Remove a key/value pair from a map, if it exists, and return
770    /// the removed value.
771    ///
772    /// This is a copy-on-write operation, so that the parts of the
773    /// set's structure which are shared with other sets will be
774    /// safely copied before mutating.
775    ///
776    /// Time: O(log n)
777    ///
778    /// # Examples
779    ///
780    /// ```
781    /// # #[macro_use] extern crate imbl;
782    /// # use imbl::hashmap::HashMap;
783    /// let mut map = hashmap!{123 => "123", 456 => "456"};
784    /// assert_eq!(Some("123"), map.remove(&123));
785    /// assert_eq!(Some("456"), map.remove(&456));
786    /// assert_eq!(None, map.remove(&789));
787    /// assert!(map.is_empty());
788    /// ```
789    pub fn remove<BK>(&mut self, k: &BK) -> Option<V>
790    where
791        BK: Hash + Eq + ?Sized,
792        K: Borrow<BK>,
793    {
794        self.remove_with_key(k).map(|(_, v)| v)
795    }
796
797    /// Remove a key/value pair from a map, if it exists, and return
798    /// the removed key and value.
799    ///
800    /// Time: O(log n)
801    ///
802    /// # Examples
803    ///
804    /// ```
805    /// # #[macro_use] extern crate imbl;
806    /// # use imbl::hashmap::HashMap;
807    /// let mut map = hashmap!{123 => "123", 456 => "456"};
808    /// assert_eq!(Some((123, "123")), map.remove_with_key(&123));
809    /// assert_eq!(Some((456, "456")), map.remove_with_key(&456));
810    /// assert_eq!(None, map.remove_with_key(&789));
811    /// assert!(map.is_empty());
812    /// ```
813    pub fn remove_with_key<BK>(&mut self, k: &BK) -> Option<(K, V)>
814    where
815        BK: Hash + Eq + ?Sized,
816        K: Borrow<BK>,
817    {
818        let Some(root) = &mut self.root else {
819            return None;
820        };
821        let result = SharedPointer::make_mut(root).remove(hash_key(&self.hasher, k), 0, k);
822        if result.is_some() {
823            self.size -= 1;
824        }
825        result
826    }
827
828    /// Get the [`Entry`][Entry] for a key in the map for in-place manipulation.
829    ///
830    /// Time: O(log n)
831    ///
832    /// [Entry]: enum.Entry.html
833    #[must_use]
834    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, P> {
835        let hash = hash_key(&self.hasher, &key);
836        if self
837            .root
838            .as_ref()
839            .and_then(|r| r.get(hash, 0, &key))
840            .is_some()
841        {
842            Entry::Occupied(OccupiedEntry {
843                map: self,
844                hash,
845                key,
846            })
847        } else {
848            Entry::Vacant(VacantEntry {
849                map: self,
850                hash,
851                key,
852            })
853        }
854    }
855
856    /// Construct a new hash map by inserting a key/value mapping into a map.
857    ///
858    /// If the map already has a mapping for the given key, the previous value
859    /// is overwritten.
860    ///
861    /// Time: O(log n)
862    ///
863    /// # Examples
864    ///
865    /// ```
866    /// # #[macro_use] extern crate imbl;
867    /// # use imbl::hashmap::HashMap;
868    /// let map = hashmap!{};
869    /// assert_eq!(
870    ///   map.update(123, "123"),
871    ///   hashmap!{123 => "123"}
872    /// );
873    /// ```
874    #[inline]
875    #[must_use]
876    pub fn update(&self, k: K, v: V) -> Self {
877        let mut out = self.clone();
878        out.insert(k, v);
879        out
880    }
881
882    /// Construct a new hash map by inserting a key/value mapping into
883    /// a map.
884    ///
885    /// If the map already has a mapping for the given key, we call
886    /// the provided function with the old value and the new value,
887    /// and insert the result as the new value.
888    ///
889    /// Time: O(log n)
890    #[must_use]
891    pub fn update_with<F>(&self, k: K, v: V, f: F) -> Self
892    where
893        F: FnOnce(V, V) -> V,
894    {
895        match self.extract_with_key(&k) {
896            None => self.update(k, v),
897            Some((_, v2, m)) => m.update(k, f(v2, v)),
898        }
899    }
900
901    /// Construct a new map by inserting a key/value mapping into a
902    /// map.
903    ///
904    /// If the map already has a mapping for the given key, we call
905    /// the provided function with the key, the old value and the new
906    /// value, and insert the result as the new value.
907    ///
908    /// Time: O(log n)
909    #[must_use]
910    pub fn update_with_key<F>(&self, k: K, v: V, f: F) -> Self
911    where
912        F: FnOnce(&K, V, V) -> V,
913    {
914        match self.extract_with_key(&k) {
915            None => self.update(k, v),
916            Some((_, v2, m)) => {
917                let out_v = f(&k, v2, v);
918                m.update(k, out_v)
919            }
920        }
921    }
922
923    /// Construct a new map by inserting a key/value mapping into a
924    /// map, returning the old value for the key as well as the new
925    /// map.
926    ///
927    /// If the map already has a mapping for the given key, we call
928    /// the provided function with the key, the old value and the new
929    /// value, and insert the result as the new value.
930    ///
931    /// Time: O(log n)
932    #[must_use]
933    pub fn update_lookup_with_key<F>(&self, k: K, v: V, f: F) -> (Option<V>, Self)
934    where
935        F: FnOnce(&K, &V, V) -> V,
936    {
937        match self.extract_with_key(&k) {
938            None => (None, self.update(k, v)),
939            Some((_, v2, m)) => {
940                let out_v = f(&k, &v2, v);
941                (Some(v2), m.update(k, out_v))
942            }
943        }
944    }
945
946    /// Update the value for a given key by calling a function with
947    /// the current value and overwriting it with the function's
948    /// return value.
949    ///
950    /// The function gets an [`Option<V>`][std::option::Option] and
951    /// returns the same, so that it can decide to delete a mapping
952    /// instead of updating the value, and decide what to do if the
953    /// key isn't in the map.
954    ///
955    /// Time: O(log n)
956    ///
957    /// [std::option::Option]: https://doc.rust-lang.org/std/option/enum.Option.html
958    #[must_use]
959    pub fn alter<F>(&self, f: F, k: K) -> Self
960    where
961        F: FnOnce(Option<V>) -> Option<V>,
962    {
963        let pop = self.extract_with_key(&k);
964        match (f(pop.as_ref().map(|(_, v, _)| v.clone())), pop) {
965            (None, None) => self.clone(),
966            (Some(v), None) => self.update(k, v),
967            (None, Some((_, _, m))) => m,
968            (Some(v), Some((_, _, m))) => m.update(k, v),
969        }
970    }
971
972    /// Construct a new map without the given key.
973    ///
974    /// Construct a map that's a copy of the current map, absent the
975    /// mapping for `key` if it's present.
976    ///
977    /// Time: O(log n)
978    #[must_use]
979    pub fn without<BK>(&self, k: &BK) -> Self
980    where
981        BK: Hash + Eq + ?Sized,
982        K: Borrow<BK>,
983    {
984        match self.extract_with_key(k) {
985            None => self.clone(),
986            Some((_, _, map)) => map,
987        }
988    }
989
990    /// Filter out values from a map which don't satisfy a predicate.
991    ///
992    /// This is slightly more efficient than filtering using an
993    /// iterator, in that it doesn't need to rehash the retained
994    /// values, but it still needs to reconstruct the entire tree
995    /// structure of the map.
996    ///
997    /// Time: O(n log n)
998    ///
999    /// # Examples
1000    ///
1001    /// ```
1002    /// # #[macro_use] extern crate imbl;
1003    /// # use imbl::HashMap;
1004    /// let mut map = hashmap!{1 => 1, 2 => 2, 3 => 3};
1005    /// map.retain(|k, v| *k > 1);
1006    /// let expected = hashmap!{2 => 2, 3 => 3};
1007    /// assert_eq!(expected, map);
1008    /// ```
1009    pub fn retain<F>(&mut self, mut f: F)
1010    where
1011        F: FnMut(&K, &V) -> bool,
1012    {
1013        let Some(root) = &mut self.root else {
1014            return;
1015        };
1016        let old_root = root.clone();
1017        let root = SharedPointer::make_mut(root);
1018        for ((key, value), hash) in NodeIter::new(Some(&old_root), self.size) {
1019            if !f(key, value) && root.remove(hash, 0, key).is_some() {
1020                self.size -= 1;
1021            }
1022        }
1023    }
1024
1025    /// Remove a key/value pair from a map, if it exists, and return
1026    /// the removed value as well as the updated map.
1027    ///
1028    /// Time: O(log n)
1029    #[must_use]
1030    pub fn extract<BK>(&self, k: &BK) -> Option<(V, Self)>
1031    where
1032        BK: Hash + Eq + ?Sized,
1033        K: Borrow<BK>,
1034    {
1035        self.extract_with_key(k).map(|(_, v, m)| (v, m))
1036    }
1037
1038    /// Remove a key/value pair from a map, if it exists, and return
1039    /// the removed key and value as well as the updated list.
1040    ///
1041    /// Time: O(log n)
1042    #[must_use]
1043    pub fn extract_with_key<BK>(&self, k: &BK) -> Option<(K, V, Self)>
1044    where
1045        BK: Hash + Eq + ?Sized,
1046        K: Borrow<BK>,
1047    {
1048        let mut out = self.clone();
1049        out.remove_with_key(k).map(|(k, v)| (k, v, out))
1050    }
1051
1052    /// Construct the union of two maps, keeping the values in the
1053    /// current map when keys exist in both maps.
1054    ///
1055    /// Time: O(n log n)
1056    ///
1057    /// # Examples
1058    ///
1059    /// ```
1060    /// # #[macro_use] extern crate imbl;
1061    /// # use imbl::hashmap::HashMap;
1062    /// let map1 = hashmap!{1 => 1, 3 => 3};
1063    /// let map2 = hashmap!{2 => 2, 3 => 4};
1064    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 3};
1065    /// assert_eq!(expected, map1.union(map2));
1066    /// ```
1067    #[must_use]
1068    pub fn union(self, other: Self) -> Self {
1069        let (mut to_mutate, to_consume, use_to_consume) = if self.len() >= other.len() {
1070            (self, other, false)
1071        } else {
1072            (other, self, true)
1073        };
1074        for (k, v) in to_consume {
1075            match to_mutate.entry(k) {
1076                Entry::Occupied(mut e) if use_to_consume => {
1077                    e.insert(v);
1078                }
1079                Entry::Vacant(e) => {
1080                    e.insert(v);
1081                }
1082                _ => {}
1083            }
1084        }
1085        to_mutate
1086    }
1087
1088    /// Construct the union of two maps, using a function to decide
1089    /// what to do with the value when a key is in both maps.
1090    ///
1091    /// The function is called when a value exists in both maps, and
1092    /// receives the value from the current map as its first argument,
1093    /// and the value from the other map as the second. It should
1094    /// return the value to be inserted in the resulting map.
1095    ///
1096    /// Time: O(n log n)
1097    #[inline]
1098    #[must_use]
1099    pub fn union_with<F>(self, other: Self, mut f: F) -> Self
1100    where
1101        F: FnMut(V, V) -> V,
1102    {
1103        self.union_with_key(other, |_, v1, v2| f(v1, v2))
1104    }
1105
1106    /// Construct the union of two maps, using a function to decide
1107    /// what to do with the value when a key is in both maps.
1108    ///
1109    /// The function is called when a value exists in both maps, and
1110    /// receives a reference to the key as its first argument, the
1111    /// value from the current map as the second argument, and the
1112    /// value from the other map as the third argument. It should
1113    /// return the value to be inserted in the resulting map.
1114    ///
1115    /// Time: O(n log n)
1116    ///
1117    /// # Examples
1118    ///
1119    /// ```
1120    /// # #[macro_use] extern crate imbl;
1121    /// # use imbl::hashmap::HashMap;
1122    /// let map1 = hashmap!{1 => 1, 3 => 4};
1123    /// let map2 = hashmap!{2 => 2, 3 => 5};
1124    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1125    /// assert_eq!(expected, map1.union_with_key(
1126    ///     map2,
1127    ///     |key, left, right| left + right
1128    /// ));
1129    /// ```
1130    #[must_use]
1131    pub fn union_with_key<F>(self, other: Self, mut f: F) -> Self
1132    where
1133        F: FnMut(&K, V, V) -> V,
1134    {
1135        if self.len() >= other.len() {
1136            self.union_with_key_inner(other, f)
1137        } else {
1138            other.union_with_key_inner(self, |key, other_value, self_value| {
1139                f(key, self_value, other_value)
1140            })
1141        }
1142    }
1143
1144    fn union_with_key_inner<F>(mut self, other: Self, mut f: F) -> Self
1145    where
1146        F: FnMut(&K, V, V) -> V,
1147    {
1148        for (key, right_value) in other {
1149            match self.remove(&key) {
1150                None => {
1151                    self.insert(key, right_value);
1152                }
1153                Some(left_value) => {
1154                    let final_value = f(&key, left_value, right_value);
1155                    self.insert(key, final_value);
1156                }
1157            }
1158        }
1159        self
1160    }
1161
1162    /// Construct the union of a sequence of maps, selecting the value
1163    /// of the leftmost when a key appears in more than one map.
1164    ///
1165    /// Time: O(n log n)
1166    ///
1167    /// # Examples
1168    ///
1169    /// ```
1170    /// # #[macro_use] extern crate imbl;
1171    /// # use imbl::hashmap::HashMap;
1172    /// let map1 = hashmap!{1 => 1, 3 => 3};
1173    /// let map2 = hashmap!{2 => 2};
1174    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 3};
1175    /// assert_eq!(expected, HashMap::unions(vec![map1, map2]));
1176    /// ```
1177    #[must_use]
1178    pub fn unions<I>(i: I) -> Self
1179    where
1180        S: Default,
1181        I: IntoIterator<Item = Self>,
1182    {
1183        i.into_iter().fold(Self::default(), Self::union)
1184    }
1185
1186    /// Construct the union of a sequence of maps, using a function to
1187    /// decide what to do with the value when a key is in more than
1188    /// one map.
1189    ///
1190    /// The function is called when a value exists in multiple maps,
1191    /// and receives the value from the current map as its first
1192    /// argument, and the value from the next map as the second. It
1193    /// should return the value to be inserted in the resulting map.
1194    ///
1195    /// Time: O(n log n)
1196    #[must_use]
1197    pub fn unions_with<I, F>(i: I, f: F) -> Self
1198    where
1199        S: Default,
1200        I: IntoIterator<Item = Self>,
1201        F: Fn(V, V) -> V,
1202    {
1203        i.into_iter()
1204            .fold(Self::default(), |a, b| a.union_with(b, &f))
1205    }
1206
1207    /// Construct the union of a sequence of maps, using a function to
1208    /// decide what to do with the value when a key is in more than
1209    /// one map.
1210    ///
1211    /// The function is called when a value exists in multiple maps,
1212    /// and receives a reference to the key as its first argument, the
1213    /// value from the current map as the second argument, and the
1214    /// value from the next map as the third argument. It should
1215    /// return the value to be inserted in the resulting map.
1216    ///
1217    /// Time: O(n log n)
1218    #[must_use]
1219    pub fn unions_with_key<I, F>(i: I, f: F) -> Self
1220    where
1221        S: Default,
1222        I: IntoIterator<Item = Self>,
1223        F: Fn(&K, V, V) -> V,
1224    {
1225        i.into_iter()
1226            .fold(Self::default(), |a, b| a.union_with_key(b, &f))
1227    }
1228
1229    /// Construct the symmetric difference between two maps by discarding keys
1230    /// which occur in both maps.
1231    ///
1232    /// This is an alias for the
1233    /// [`symmetric_difference`][symmetric_difference] method.
1234    ///
1235    /// Time: O(n log n)
1236    ///
1237    /// # Examples
1238    ///
1239    /// ```
1240    /// # #[macro_use] extern crate imbl;
1241    /// # use imbl::hashmap::HashMap;
1242    /// let map1 = hashmap!{1 => 1, 3 => 4};
1243    /// let map2 = hashmap!{2 => 2, 3 => 5};
1244    /// let expected = hashmap!{1 => 1, 2 => 2};
1245    /// assert_eq!(expected, map1.difference(map2));
1246    /// ```
1247    ///
1248    /// [symmetric_difference]: #method.symmetric_difference
1249    #[deprecated(
1250        since = "2.0.1",
1251        note = "to avoid conflicting behaviors between std and imbl, the `difference` alias for `symmetric_difference` will be removed."
1252    )]
1253    #[inline]
1254    #[must_use]
1255    pub fn difference(self, other: Self) -> Self {
1256        self.symmetric_difference(other)
1257    }
1258
1259    /// Construct the symmetric difference between two maps by discarding keys
1260    /// which occur in both maps.
1261    ///
1262    /// Time: O(n log n)
1263    ///
1264    /// # Examples
1265    ///
1266    /// ```
1267    /// # #[macro_use] extern crate imbl;
1268    /// # use imbl::hashmap::HashMap;
1269    /// let map1 = hashmap!{1 => 1, 3 => 4};
1270    /// let map2 = hashmap!{2 => 2, 3 => 5};
1271    /// let expected = hashmap!{1 => 1, 2 => 2};
1272    /// assert_eq!(expected, map1.symmetric_difference(map2));
1273    /// ```
1274    #[inline]
1275    #[must_use]
1276    pub fn symmetric_difference(self, other: Self) -> Self {
1277        self.symmetric_difference_with_key(other, |_, _, _| None)
1278    }
1279
1280    /// Construct the symmetric difference between two maps by using a function
1281    /// to decide what to do if a key occurs in both.
1282    ///
1283    /// This is an alias for the
1284    /// [`symmetric_difference_with`][symmetric_difference_with] method.
1285    ///
1286    /// Time: O(n log n)
1287    ///
1288    /// [symmetric_difference_with]: #method.symmetric_difference_with
1289    #[deprecated(
1290        since = "2.0.1",
1291        note = "to avoid conflicting behaviors between std and imbl, the `difference_with` alias for `symmetric_difference_with` will be removed."
1292    )]
1293    #[inline]
1294    #[must_use]
1295    pub fn difference_with<F>(self, other: Self, f: F) -> Self
1296    where
1297        F: FnMut(V, V) -> Option<V>,
1298    {
1299        self.symmetric_difference_with(other, f)
1300    }
1301
1302    /// Construct the symmetric difference between two maps by using a function
1303    /// to decide what to do if a key occurs in both.
1304    ///
1305    /// Time: O(n log n)
1306    #[inline]
1307    #[must_use]
1308    pub fn symmetric_difference_with<F>(self, other: Self, mut f: F) -> Self
1309    where
1310        F: FnMut(V, V) -> Option<V>,
1311    {
1312        self.symmetric_difference_with_key(other, |_, a, b| f(a, b))
1313    }
1314
1315    /// Construct the symmetric difference between two maps by using a function
1316    /// to decide what to do if a key occurs in both. The function
1317    /// receives the key as well as both values.
1318    ///
1319    /// This is an alias for the
1320    /// [`symmetric_difference_with`_key][symmetric_difference_with_key]
1321    /// method.
1322    ///
1323    /// Time: O(n log n)
1324    ///
1325    /// # Examples
1326    ///
1327    /// ```
1328    /// # #[macro_use] extern crate imbl;
1329    /// # use imbl::hashmap::HashMap;
1330    /// let map1 = hashmap!{1 => 1, 3 => 4};
1331    /// let map2 = hashmap!{2 => 2, 3 => 5};
1332    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1333    /// assert_eq!(expected, map1.difference_with_key(
1334    ///     map2,
1335    ///     |key, left, right| Some(left + right)
1336    /// ));
1337    /// ```
1338    ///
1339    /// [symmetric_difference_with_key]: #method.symmetric_difference_with_key
1340    #[deprecated(
1341        since = "2.0.1",
1342        note = "to avoid conflicting behaviors between std and imbl, the `difference_with_key` alias for `symmetric_difference_with_key` will be removed."
1343    )]
1344    #[must_use]
1345    pub fn difference_with_key<F>(self, other: Self, f: F) -> Self
1346    where
1347        F: FnMut(&K, V, V) -> Option<V>,
1348    {
1349        self.symmetric_difference_with_key(other, f)
1350    }
1351
1352    /// Construct the symmetric difference between two maps by using a function
1353    /// to decide what to do if a key occurs in both. The function
1354    /// receives the key as well as both values.
1355    ///
1356    /// Time: O(n log n)
1357    ///
1358    /// # Examples
1359    ///
1360    /// ```
1361    /// # #[macro_use] extern crate imbl;
1362    /// # use imbl::hashmap::HashMap;
1363    /// let map1 = hashmap!{1 => 1, 3 => 4};
1364    /// let map2 = hashmap!{2 => 2, 3 => 5};
1365    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1366    /// assert_eq!(expected, map1.symmetric_difference_with_key(
1367    ///     map2,
1368    ///     |key, left, right| Some(left + right)
1369    /// ));
1370    /// ```
1371    #[must_use]
1372    pub fn symmetric_difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
1373    where
1374        F: FnMut(&K, V, V) -> Option<V>,
1375    {
1376        let mut out = self.new_from();
1377        for (key, right_value) in other {
1378            match self.remove(&key) {
1379                None => {
1380                    out.insert(key, right_value);
1381                }
1382                Some(left_value) => {
1383                    if let Some(final_value) = f(&key, left_value, right_value) {
1384                        out.insert(key, final_value);
1385                    }
1386                }
1387            }
1388        }
1389        out.union(self)
1390    }
1391
1392    /// Construct the relative complement between two maps by discarding keys
1393    /// which occur in `other`.
1394    ///
1395    /// Time: O(m log n) where m is the size of the other map
1396    ///
1397    /// # Examples
1398    ///
1399    /// ```
1400    /// # #[macro_use] extern crate imbl;
1401    /// # use imbl::hashmap::HashMap;
1402    /// let map1 = hashmap!{1 => 1, 3 => 4};
1403    /// let map2 = hashmap!{2 => 2, 3 => 5};
1404    /// let expected = hashmap!{1 => 1};
1405    /// assert_eq!(expected, map1.relative_complement(map2));
1406    /// ```
1407    #[inline]
1408    #[must_use]
1409    pub fn relative_complement(mut self, other: Self) -> Self {
1410        for (key, _) in other {
1411            let _ = self.remove(&key);
1412        }
1413        self
1414    }
1415
1416    /// Construct the intersection of two maps, keeping the values
1417    /// from the current map.
1418    ///
1419    /// Time: O(n log n)
1420    ///
1421    /// # Examples
1422    ///
1423    /// ```
1424    /// # #[macro_use] extern crate imbl;
1425    /// # use imbl::hashmap::HashMap;
1426    /// let map1 = hashmap!{1 => 1, 2 => 2};
1427    /// let map2 = hashmap!{2 => 3, 3 => 4};
1428    /// let expected = hashmap!{2 => 2};
1429    /// assert_eq!(expected, map1.intersection(map2));
1430    /// ```
1431    #[inline]
1432    #[must_use]
1433    pub fn intersection(self, other: Self) -> Self {
1434        self.intersection_with_key(other, |_, v, _| v)
1435    }
1436
1437    /// Construct the intersection of two maps, calling a function
1438    /// with both values for each key and using the result as the
1439    /// value for the key.
1440    ///
1441    /// Time: O(n log n)
1442    #[inline]
1443    #[must_use]
1444    pub fn intersection_with<B, C, F>(
1445        self,
1446        other: GenericHashMap<K, B, S, P>,
1447        mut f: F,
1448    ) -> GenericHashMap<K, C, S, P>
1449    where
1450        B: Clone,
1451        C: Clone,
1452        F: FnMut(V, B) -> C,
1453    {
1454        self.intersection_with_key(other, |_, v1, v2| f(v1, v2))
1455    }
1456
1457    /// Construct the intersection of two maps, calling a function
1458    /// with the key and both values for each key and using the result
1459    /// as the value for the key.
1460    ///
1461    /// Time: O(n log n)
1462    ///
1463    /// # Examples
1464    ///
1465    /// ```
1466    /// # #[macro_use] extern crate imbl;
1467    /// # use imbl::hashmap::HashMap;
1468    /// let map1 = hashmap!{1 => 1, 2 => 2};
1469    /// let map2 = hashmap!{2 => 3, 3 => 4};
1470    /// let expected = hashmap!{2 => 5};
1471    /// assert_eq!(expected, map1.intersection_with_key(
1472    ///     map2,
1473    ///     |key, left, right| left + right
1474    /// ));
1475    /// ```
1476    #[must_use]
1477    pub fn intersection_with_key<B, C, F>(
1478        mut self,
1479        other: GenericHashMap<K, B, S, P>,
1480        mut f: F,
1481    ) -> GenericHashMap<K, C, S, P>
1482    where
1483        B: Clone,
1484        C: Clone,
1485        F: FnMut(&K, V, B) -> C,
1486    {
1487        let mut out = self.new_from();
1488        for (key, right_value) in other {
1489            match self.remove(&key) {
1490                None => (),
1491                Some(left_value) => {
1492                    let result = f(&key, left_value, right_value);
1493                    out.insert(key, result);
1494                }
1495            }
1496        }
1497        out
1498    }
1499}
1500
1501// Entries
1502
1503/// A handle for a key and its associated value.
1504///
1505/// ## Performance Note
1506///
1507/// When using an `Entry`, the key is only ever hashed once, when you
1508/// create the `Entry`. Operations on an `Entry` will never trigger a
1509/// rehash, where eg. a `contains_key(key)` followed by an
1510/// `insert(key, default_value)` (the equivalent of
1511/// `Entry::or_insert()`) would need to hash the key once for the
1512/// `contains_key` and again for the `insert`. The operations
1513/// generally perform similarly otherwise.
1514pub enum Entry<'a, K, V, S, P>
1515where
1516    K: Hash + Eq + Clone,
1517    V: Clone,
1518    S: BuildHasher + Clone,
1519    P: SharedPointerKind,
1520{
1521    /// An entry which exists in the map.
1522    Occupied(OccupiedEntry<'a, K, V, S, P>),
1523    /// An entry which doesn't exist in the map.
1524    Vacant(VacantEntry<'a, K, V, S, P>),
1525}
1526
1527impl<'a, K, V, S, P> Entry<'a, K, V, S, P>
1528where
1529    K: 'a + Hash + Eq + Clone,
1530    V: 'a + Clone,
1531    S: 'a + BuildHasher + Clone,
1532    P: SharedPointerKind,
1533{
1534    /// Insert the default value provided if there was no value
1535    /// already, and return a mutable reference to the value.
1536    pub fn or_insert(self, default: V) -> &'a mut V {
1537        self.or_insert_with(|| default)
1538    }
1539
1540    /// Insert the default value from the provided function if there
1541    /// was no value already, and return a mutable reference to the
1542    /// value.
1543    pub fn or_insert_with<F>(self, default: F) -> &'a mut V
1544    where
1545        F: FnOnce() -> V,
1546    {
1547        match self {
1548            Entry::Occupied(entry) => entry.into_mut(),
1549            Entry::Vacant(entry) => entry.insert(default()),
1550        }
1551    }
1552
1553    /// Insert a default value if there was no value already, and
1554    /// return a mutable reference to the value.
1555    pub fn or_default(self) -> &'a mut V
1556    where
1557        V: Default,
1558    {
1559        #[allow(clippy::unwrap_or_default)]
1560        self.or_insert_with(Default::default)
1561    }
1562
1563    /// Get the key for this entry.
1564    #[must_use]
1565    pub fn key(&self) -> &K {
1566        match self {
1567            Entry::Occupied(entry) => entry.key(),
1568            Entry::Vacant(entry) => entry.key(),
1569        }
1570    }
1571
1572    /// Call the provided function to modify the value if the value
1573    /// exists.
1574    #[must_use]
1575    pub fn and_modify<F>(mut self, f: F) -> Self
1576    where
1577        F: FnOnce(&mut V),
1578    {
1579        match &mut self {
1580            Entry::Occupied(ref mut entry) => f(entry.get_mut()),
1581            Entry::Vacant(_) => (),
1582        }
1583        self
1584    }
1585}
1586
1587/// An entry for a mapping that already exists in the map.
1588pub struct OccupiedEntry<'a, K, V, S, P>
1589where
1590    K: Hash + Eq + Clone,
1591    V: Clone,
1592    S: BuildHasher + Clone,
1593    P: SharedPointerKind,
1594{
1595    map: &'a mut GenericHashMap<K, V, S, P>,
1596    hash: HashBits,
1597    key: K,
1598}
1599
1600impl<'a, K, V, S, P> OccupiedEntry<'a, K, V, S, P>
1601where
1602    K: 'a + Hash + Eq + Clone,
1603    V: 'a + Clone,
1604    S: 'a + BuildHasher + Clone,
1605    P: SharedPointerKind,
1606{
1607    /// Get the key for this entry.
1608    #[must_use]
1609    pub fn key(&self) -> &K {
1610        &self.key
1611    }
1612
1613    /// Remove this entry from the map and return the removed mapping.
1614    pub fn remove_entry(self) -> (K, V) {
1615        // unwrap: occupied entries can only be created for non-empty maps
1616        let root = SharedPointer::make_mut(self.map.root.as_mut().unwrap());
1617        let result = root.remove(self.hash, 0, &self.key);
1618        self.map.size -= 1;
1619        result.unwrap()
1620    }
1621
1622    /// Get the current value.
1623    #[must_use]
1624    pub fn get(&self) -> &V {
1625        // unwrap: occupied entries can only be created for non-empty maps
1626        &self
1627            .map
1628            .root
1629            .as_ref()
1630            .unwrap()
1631            .get(self.hash, 0, &self.key)
1632            .unwrap()
1633            .1
1634    }
1635
1636    /// Get a mutable reference to the current value.
1637    #[must_use]
1638    pub fn get_mut(&mut self) -> &mut V {
1639        // unwrap: occupied entries can only be created for non-empty maps
1640        let root = SharedPointer::make_mut(self.map.root.as_mut().unwrap());
1641        &mut root.get_mut(self.hash, 0, &self.key).unwrap().1
1642    }
1643
1644    /// Convert this entry into a mutable reference.
1645    #[must_use]
1646    pub fn into_mut(self) -> &'a mut V {
1647        // unwrap: occupied entries can only be created for non-empty maps
1648        let root = SharedPointer::make_mut(self.map.root.as_mut().unwrap());
1649        &mut root.get_mut(self.hash, 0, &self.key).unwrap().1
1650    }
1651
1652    /// Overwrite the current value.
1653    pub fn insert(&mut self, value: V) -> V {
1654        mem::replace(self.get_mut(), value)
1655    }
1656
1657    /// Remove this entry from the map and return the removed value.
1658    pub fn remove(self) -> V {
1659        self.remove_entry().1
1660    }
1661}
1662
1663/// An entry for a mapping that does not already exist in the map.
1664pub struct VacantEntry<'a, K, V, S, P>
1665where
1666    K: Hash + Eq + Clone,
1667    V: Clone,
1668    S: BuildHasher + Clone,
1669    P: SharedPointerKind,
1670{
1671    map: &'a mut GenericHashMap<K, V, S, P>,
1672    hash: HashBits,
1673    key: K,
1674}
1675
1676impl<'a, K, V, S, P> VacantEntry<'a, K, V, S, P>
1677where
1678    K: 'a + Hash + Eq + Clone,
1679    V: 'a + Clone,
1680    S: 'a + BuildHasher + Clone,
1681    P: SharedPointerKind,
1682{
1683    /// Get the key for this entry.
1684    #[must_use]
1685    pub fn key(&self) -> &K {
1686        &self.key
1687    }
1688
1689    /// Convert this entry into its key.
1690    #[must_use]
1691    pub fn into_key(self) -> K {
1692        self.key
1693    }
1694
1695    /// Insert a value into this entry.
1696    pub fn insert(self, value: V) -> &'a mut V {
1697        let root =
1698            SharedPointer::make_mut(self.map.root.get_or_insert_with(SharedPointer::default));
1699        if root
1700            .insert(self.hash, 0, (self.key.clone(), value))
1701            .is_none()
1702        {
1703            self.map.size += 1;
1704        }
1705        // TODO it's unfortunate that we need to look up the key again
1706        // here to get the mut ref.
1707        &mut root.get_mut(self.hash, 0, &self.key).unwrap().1
1708    }
1709}
1710
1711// Core traits
1712
1713impl<K, V, S, P> Clone for GenericHashMap<K, V, S, P>
1714where
1715    K: Clone,
1716    V: Clone,
1717    S: Clone,
1718    P: SharedPointerKind,
1719{
1720    /// Clone a map.
1721    ///
1722    /// Time: O(1)
1723    #[inline]
1724    fn clone(&self) -> Self {
1725        GenericHashMap {
1726            root: self.root.clone(),
1727            size: self.size,
1728            hasher: self.hasher.clone(),
1729        }
1730    }
1731}
1732
1733impl<K, V, S1, S2, P1, P2> PartialEq<GenericHashMap<K, V, S2, P2>> for GenericHashMap<K, V, S1, P1>
1734where
1735    K: Hash + Eq,
1736    V: PartialEq,
1737    S1: BuildHasher + Clone,
1738    S2: BuildHasher + Clone,
1739    P1: SharedPointerKind,
1740    P2: SharedPointerKind,
1741{
1742    fn eq(&self, other: &GenericHashMap<K, V, S2, P2>) -> bool {
1743        self.test_eq(other)
1744    }
1745}
1746
1747impl<K, V, S, P> Eq for GenericHashMap<K, V, S, P>
1748where
1749    K: Hash + Eq,
1750    V: Eq,
1751    S: BuildHasher + Clone,
1752    P: SharedPointerKind,
1753{
1754}
1755
1756impl<K, V, S, P> Default for GenericHashMap<K, V, S, P>
1757where
1758    S: Default,
1759    P: SharedPointerKind,
1760{
1761    #[inline]
1762    fn default() -> Self {
1763        GenericHashMap {
1764            size: 0,
1765            root: None,
1766            hasher: Default::default(),
1767        }
1768    }
1769}
1770
1771impl<K, V, S, P> Add for GenericHashMap<K, V, S, P>
1772where
1773    K: Hash + Eq + Clone,
1774    V: Clone,
1775    S: BuildHasher + Clone,
1776    P: SharedPointerKind,
1777{
1778    type Output = GenericHashMap<K, V, S, P>;
1779
1780    fn add(self, other: Self) -> Self::Output {
1781        self.union(other)
1782    }
1783}
1784
1785impl<'a, K, V, S, P> Add for &'a GenericHashMap<K, V, S, P>
1786where
1787    K: Hash + Eq + Clone,
1788    V: Clone,
1789    S: BuildHasher + Clone,
1790    P: SharedPointerKind,
1791{
1792    type Output = GenericHashMap<K, V, S, P>;
1793
1794    fn add(self, other: Self) -> Self::Output {
1795        self.clone().union(other.clone())
1796    }
1797}
1798
1799impl<K, V, S, P> Sum for GenericHashMap<K, V, S, P>
1800where
1801    K: Hash + Eq + Clone,
1802    V: Clone,
1803    S: BuildHasher + Default + Clone,
1804    P: SharedPointerKind,
1805{
1806    fn sum<I>(it: I) -> Self
1807    where
1808        I: Iterator<Item = Self>,
1809    {
1810        it.fold(Self::default(), |a, b| a + b)
1811    }
1812}
1813
1814impl<K, V, S, RK, RV, P> Extend<(RK, RV)> for GenericHashMap<K, V, S, P>
1815where
1816    K: Hash + Eq + Clone + From<RK>,
1817    V: Clone + From<RV>,
1818    S: BuildHasher + Clone,
1819    P: SharedPointerKind,
1820{
1821    fn extend<I>(&mut self, iter: I)
1822    where
1823        I: IntoIterator<Item = (RK, RV)>,
1824    {
1825        for (key, value) in iter {
1826            self.insert(From::from(key), From::from(value));
1827        }
1828    }
1829}
1830
1831impl<'a, BK, K, V, S, P> Index<&'a BK> for GenericHashMap<K, V, S, P>
1832where
1833    BK: Hash + Eq + ?Sized,
1834    K: Hash + Eq + Borrow<BK>,
1835    S: BuildHasher + Clone,
1836    P: SharedPointerKind,
1837{
1838    type Output = V;
1839
1840    fn index(&self, key: &BK) -> &Self::Output {
1841        match self.get(key) {
1842            None => panic!("HashMap::index: invalid key"),
1843            Some(value) => value,
1844        }
1845    }
1846}
1847
1848impl<'a, BK, K, V, S, P> IndexMut<&'a BK> for GenericHashMap<K, V, S, P>
1849where
1850    BK: Hash + Eq + ?Sized,
1851    K: Hash + Eq + Clone + Borrow<BK>,
1852    V: Clone,
1853    S: BuildHasher + Clone,
1854    P: SharedPointerKind,
1855{
1856    fn index_mut(&mut self, key: &BK) -> &mut Self::Output {
1857        match self.get_mut(key) {
1858            None => panic!("HashMap::index_mut: invalid key"),
1859            Some(value) => value,
1860        }
1861    }
1862}
1863
1864impl<K, V, S, P> Debug for GenericHashMap<K, V, S, P>
1865where
1866    K: Debug,
1867    V: Debug,
1868    P: SharedPointerKind,
1869{
1870    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1871        let mut d = f.debug_map();
1872        for (k, v) in self {
1873            d.entry(k, v);
1874        }
1875        d.finish()
1876    }
1877}
1878
1879// // Iterators
1880
1881/// An iterator over the elements of a map.
1882pub struct Iter<'a, K, V, P: SharedPointerKind> {
1883    it: NodeIter<'a, (K, V), P>,
1884}
1885
1886// We impl Clone instead of deriving it, because we want Clone even if K and V aren't.
1887impl<'a, K, V, P: SharedPointerKind> Clone for Iter<'a, K, V, P> {
1888    fn clone(&self) -> Self {
1889        Iter {
1890            it: self.it.clone(),
1891        }
1892    }
1893}
1894
1895impl<'a, K, V, P: SharedPointerKind> Iterator for Iter<'a, K, V, P> {
1896    type Item = (&'a K, &'a V);
1897
1898    fn next(&mut self) -> Option<Self::Item> {
1899        self.it.next().map(|((k, v), _)| (k, v))
1900    }
1901
1902    fn size_hint(&self) -> (usize, Option<usize>) {
1903        self.it.size_hint()
1904    }
1905}
1906
1907impl<'a, K, V, P: SharedPointerKind> ExactSizeIterator for Iter<'a, K, V, P> {}
1908
1909impl<'a, K, V, P: SharedPointerKind> FusedIterator for Iter<'a, K, V, P> {}
1910
1911/// A mutable iterator over the elements of a map.
1912pub struct IterMut<'a, K, V, P>
1913where
1914    K: Clone,
1915    V: Clone,
1916    P: SharedPointerKind,
1917{
1918    it: NodeIterMut<'a, (K, V), P>,
1919}
1920
1921impl<'a, K, V, P> Iterator for IterMut<'a, K, V, P>
1922where
1923    K: Clone,
1924    V: Clone,
1925    P: SharedPointerKind,
1926{
1927    type Item = (&'a K, &'a mut V);
1928
1929    fn next(&mut self) -> Option<Self::Item> {
1930        self.it.next().map(|((k, v), _)| (&*k, v))
1931    }
1932
1933    fn size_hint(&self) -> (usize, Option<usize>) {
1934        self.it.size_hint()
1935    }
1936}
1937
1938impl<'a, K, V, P> ExactSizeIterator for IterMut<'a, K, V, P>
1939where
1940    K: Clone,
1941    V: Clone,
1942    P: SharedPointerKind,
1943{
1944}
1945
1946impl<'a, K, V, P> FusedIterator for IterMut<'a, K, V, P>
1947where
1948    K: Clone,
1949    V: Clone,
1950    P: SharedPointerKind,
1951{
1952}
1953
1954/// A consuming iterator over the elements of a map.
1955pub struct ConsumingIter<A: HashValue, P: SharedPointerKind> {
1956    it: NodeDrain<A, P>,
1957}
1958
1959impl<A, P: SharedPointerKind> Iterator for ConsumingIter<A, P>
1960where
1961    A: HashValue + Clone,
1962{
1963    type Item = A;
1964
1965    fn next(&mut self) -> Option<Self::Item> {
1966        self.it.next().map(|(p, _)| p)
1967    }
1968
1969    fn size_hint(&self) -> (usize, Option<usize>) {
1970        self.it.size_hint()
1971    }
1972}
1973
1974impl<A, P> ExactSizeIterator for ConsumingIter<A, P>
1975where
1976    A: HashValue + Clone,
1977    P: SharedPointerKind,
1978{
1979}
1980
1981impl<A, P> FusedIterator for ConsumingIter<A, P>
1982where
1983    A: HashValue + Clone,
1984    P: SharedPointerKind,
1985{
1986}
1987
1988/// An iterator over the keys of a map.
1989pub struct Keys<'a, K, V, P: SharedPointerKind> {
1990    it: NodeIter<'a, (K, V), P>,
1991}
1992
1993impl<'a, K, V, P: SharedPointerKind> Iterator for Keys<'a, K, V, P> {
1994    type Item = &'a K;
1995
1996    fn next(&mut self) -> Option<Self::Item> {
1997        self.it.next().map(|((k, _), _)| k)
1998    }
1999
2000    fn size_hint(&self) -> (usize, Option<usize>) {
2001        self.it.size_hint()
2002    }
2003}
2004
2005impl<'a, K, V, P: SharedPointerKind> ExactSizeIterator for Keys<'a, K, V, P> {}
2006
2007impl<'a, K, V, P: SharedPointerKind> FusedIterator for Keys<'a, K, V, P> {}
2008
2009/// An iterator over the values of a map.
2010pub struct Values<'a, K, V, P: SharedPointerKind> {
2011    it: NodeIter<'a, (K, V), P>,
2012}
2013
2014impl<'a, K, V, P: SharedPointerKind> Iterator for Values<'a, K, V, P> {
2015    type Item = &'a V;
2016
2017    fn next(&mut self) -> Option<Self::Item> {
2018        self.it.next().map(|((_, v), _)| v)
2019    }
2020
2021    fn size_hint(&self) -> (usize, Option<usize>) {
2022        self.it.size_hint()
2023    }
2024}
2025
2026impl<'a, K, V, P: SharedPointerKind> ExactSizeIterator for Values<'a, K, V, P> {}
2027
2028impl<'a, K, V, P: SharedPointerKind> FusedIterator for Values<'a, K, V, P> {}
2029
2030impl<'a, K, V, S, P: SharedPointerKind> IntoIterator for &'a GenericHashMap<K, V, S, P> {
2031    type Item = (&'a K, &'a V);
2032    type IntoIter = Iter<'a, K, V, P>;
2033
2034    #[inline]
2035    fn into_iter(self) -> Self::IntoIter {
2036        self.iter()
2037    }
2038}
2039
2040impl<K, V, S, P> IntoIterator for GenericHashMap<K, V, S, P>
2041where
2042    K: Hash + Eq + Clone,
2043    V: Clone,
2044    S: BuildHasher + Clone,
2045    P: SharedPointerKind,
2046{
2047    type Item = (K, V);
2048    type IntoIter = ConsumingIter<(K, V), P>;
2049
2050    #[inline]
2051    fn into_iter(self) -> Self::IntoIter {
2052        ConsumingIter {
2053            it: NodeDrain::new(self.root, self.size),
2054        }
2055    }
2056}
2057
2058// Conversions
2059
2060impl<K, V, S, P> FromIterator<(K, V)> for GenericHashMap<K, V, S, P>
2061where
2062    K: Hash + Eq + Clone,
2063    V: Clone,
2064    S: BuildHasher + Default + Clone,
2065    P: SharedPointerKind,
2066{
2067    fn from_iter<T>(i: T) -> Self
2068    where
2069        T: IntoIterator<Item = (K, V)>,
2070    {
2071        let mut map = Self::default();
2072        for (k, v) in i {
2073            map.insert(k, v);
2074        }
2075        map
2076    }
2077}
2078
2079impl<K, V, S, P: SharedPointerKind> AsRef<GenericHashMap<K, V, S, P>>
2080    for GenericHashMap<K, V, S, P>
2081{
2082    #[inline]
2083    fn as_ref(&self) -> &Self {
2084        self
2085    }
2086}
2087
2088impl<'m, 'k, 'v, K, V, OK, OV, SA, SB, P1, P2> From<&'m GenericHashMap<&'k K, &'v V, SA, P1>>
2089    for GenericHashMap<OK, OV, SB, P2>
2090where
2091    K: Hash + Eq + ToOwned<Owned = OK> + ?Sized,
2092    V: ToOwned<Owned = OV> + ?Sized,
2093    OK: Hash + Eq + Clone + Borrow<K>,
2094    OV: Borrow<V> + Clone,
2095    SA: BuildHasher + Clone,
2096    SB: BuildHasher + Default + Clone,
2097    P1: SharedPointerKind,
2098    P2: SharedPointerKind,
2099{
2100    fn from(m: &GenericHashMap<&K, &V, SA, P1>) -> Self {
2101        m.iter()
2102            .map(|(k, v)| ((*k).to_owned(), (*v).to_owned()))
2103            .collect()
2104    }
2105}
2106
2107impl<'a, K, V, S, P> From<&'a [(K, V)]> for GenericHashMap<K, V, S, P>
2108where
2109    K: Hash + Eq + Clone,
2110    V: Clone,
2111    S: BuildHasher + Default + Clone,
2112    P: SharedPointerKind,
2113{
2114    fn from(m: &'a [(K, V)]) -> Self {
2115        m.iter().cloned().collect()
2116    }
2117}
2118
2119impl<K, V, S, P> From<Vec<(K, V)>> for GenericHashMap<K, V, S, P>
2120where
2121    K: Hash + Eq + Clone,
2122    V: Clone,
2123    S: BuildHasher + Default + Clone,
2124    P: SharedPointerKind,
2125{
2126    fn from(m: Vec<(K, V)>) -> Self {
2127        m.into_iter().collect()
2128    }
2129}
2130
2131impl<'a, K, V, S, P> From<&'a Vec<(K, V)>> for GenericHashMap<K, V, S, P>
2132where
2133    K: Hash + Eq + Clone,
2134    V: Clone,
2135    S: BuildHasher + Default + Clone,
2136    P: SharedPointerKind,
2137{
2138    fn from(m: &'a Vec<(K, V)>) -> Self {
2139        m.iter().cloned().collect()
2140    }
2141}
2142
2143impl<K, V, S1, S2, P> From<collections::HashMap<K, V, S2>> for GenericHashMap<K, V, S1, P>
2144where
2145    K: Hash + Eq + Clone,
2146    V: Clone,
2147    S1: BuildHasher + Default + Clone,
2148    S2: BuildHasher,
2149    P: SharedPointerKind,
2150{
2151    fn from(m: collections::HashMap<K, V, S2>) -> Self {
2152        m.into_iter().collect()
2153    }
2154}
2155
2156impl<'a, K, V, S1, S2, P> From<&'a collections::HashMap<K, V, S2>> for GenericHashMap<K, V, S1, P>
2157where
2158    K: Hash + Eq + Clone,
2159    V: Clone,
2160    S1: BuildHasher + Default + Clone,
2161    S2: BuildHasher,
2162    P: SharedPointerKind,
2163{
2164    fn from(m: &'a collections::HashMap<K, V, S2>) -> Self {
2165        m.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
2166    }
2167}
2168
2169impl<K, V, S, P> From<collections::BTreeMap<K, V>> for GenericHashMap<K, V, S, P>
2170where
2171    K: Hash + Eq + Clone,
2172    V: Clone,
2173    S: BuildHasher + Default + Clone,
2174    P: SharedPointerKind,
2175{
2176    fn from(m: collections::BTreeMap<K, V>) -> Self {
2177        m.into_iter().collect()
2178    }
2179}
2180
2181impl<'a, K, V, S, P> From<&'a collections::BTreeMap<K, V>> for GenericHashMap<K, V, S, P>
2182where
2183    K: Hash + Eq + Clone,
2184    V: Clone,
2185    S: BuildHasher + Default + Clone,
2186    P: SharedPointerKind,
2187{
2188    fn from(m: &'a collections::BTreeMap<K, V>) -> Self {
2189        m.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
2190    }
2191}
2192
2193// impl<K: Ord + Hash + Eq, V, S> From<OrdMap<K, V>> for HashMap<K, V, S>
2194// where
2195//     S: BuildHasher + Default,
2196// {
2197//     fn from(m: OrdMap<K, V>) -> Self {
2198//         m.into_iter().collect()
2199//     }
2200// }
2201
2202// impl<'a, K: Ord + Hash + Eq, V, S> From<&'a OrdMap<K, V>> for HashMap<K, V, S>
2203// where
2204//     S: BuildHasher + Default,
2205// {
2206//     fn from(m: &'a OrdMap<K, V>) -> Self {
2207//         m.into_iter().collect()
2208//     }
2209// }
2210
2211// Proptest
2212#[cfg(any(test, feature = "proptest"))]
2213#[doc(hidden)]
2214pub mod proptest {
2215    #[deprecated(
2216        since = "14.3.0",
2217        note = "proptest strategies have moved to imbl::proptest"
2218    )]
2219    pub use crate::proptest::hash_map;
2220}
2221
2222// Tests
2223
2224#[cfg(test)]
2225mod test {
2226    use super::*;
2227    use crate::test::LolHasher;
2228    #[rustfmt::skip]
2229    use ::proptest::{collection, num::{i16, usize}, proptest};
2230    use static_assertions::{assert_impl_all, assert_not_impl_any};
2231    use std::hash::BuildHasherDefault;
2232
2233    assert_impl_all!(HashMap<i32, i32>: Send, Sync);
2234    assert_not_impl_any!(HashMap<i32, *const i32>: Send, Sync);
2235    assert_not_impl_any!(HashMap<*const i32, i32>: Send, Sync);
2236    assert_covariant!(HashMap<T, i32> in T);
2237    assert_covariant!(HashMap<i32, T> in T);
2238
2239    #[test]
2240    fn safe_mutation() {
2241        let v1: HashMap<usize, usize> = GenericHashMap::from_iter((0..131_072).map(|i| (i, i)));
2242        let mut v2 = v1.clone();
2243        v2.insert(131_000, 23);
2244        assert_eq!(Some(&23), v2.get(&131_000));
2245        assert_eq!(Some(&131_000), v1.get(&131_000));
2246    }
2247
2248    #[test]
2249    fn index_operator() {
2250        let mut map: HashMap<usize, usize> = hashmap![1 => 2, 3 => 4, 5 => 6];
2251        assert_eq!(4, map[&3]);
2252        map[&3] = 8;
2253        let target_map: HashMap<usize, usize> = hashmap![1 => 2, 3 => 8, 5 => 6];
2254        assert_eq!(target_map, map);
2255    }
2256
2257    #[test]
2258    fn proper_formatting() {
2259        let map: HashMap<usize, usize> = hashmap![1 => 2];
2260        assert_eq!("{1: 2}", format!("{:?}", map));
2261
2262        assert_eq!("{}", format!("{:?}", HashMap::<(), ()>::new()));
2263    }
2264
2265    #[test]
2266    fn remove_failing() {
2267        let pairs = [(1469, 0), (-67, 0)];
2268        let mut m: collections::HashMap<i16, i16, _> =
2269            collections::HashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2270        for (k, v) in &pairs {
2271            m.insert(*k, *v);
2272        }
2273        let mut map: GenericHashMap<i16, i16, _, DefaultSharedPtr> =
2274            GenericHashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2275        for (k, v) in &m {
2276            map = map.update(*k, *v);
2277        }
2278        for k in m.keys() {
2279            let l = map.len();
2280            assert_eq!(m.get(k).cloned(), map.get(k).cloned());
2281            map = map.without(k);
2282            assert_eq!(None, map.get(k));
2283            assert_eq!(l - 1, map.len());
2284        }
2285    }
2286
2287    #[test]
2288    fn match_string_keys_with_string_slices() {
2289        let tmp_map: HashMap<&str, &i32> = hashmap! { "foo" => &1, "bar" => &2, "baz" => &3 };
2290        let mut map: HashMap<String, i32> = From::from(&tmp_map);
2291        assert_eq!(Some(&1), map.get("foo"));
2292        map = map.without("foo");
2293        assert_eq!(Some(3), map.remove("baz"));
2294        map["bar"] = 8;
2295        assert_eq!(8, map["bar"]);
2296    }
2297
2298    #[test]
2299    fn macro_allows_trailing_comma() {
2300        let map1: HashMap<&str, i32> = hashmap! {"x" => 1, "y" => 2};
2301        let map2: HashMap<&str, i32> = hashmap! {
2302            "x" => 1,
2303            "y" => 2,
2304        };
2305        assert_eq!(map1, map2);
2306    }
2307
2308    #[test]
2309    fn remove_top_level_collisions() {
2310        let pairs = vec![9, 2569, 27145];
2311        let mut map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> =
2312            Default::default();
2313        for k in pairs.clone() {
2314            map.insert(k, k);
2315        }
2316        assert_eq!(pairs.len(), map.len());
2317        let keys: Vec<_> = map.keys().cloned().collect();
2318        for k in keys {
2319            let l = map.len();
2320            assert_eq!(Some(&k), map.get(&k));
2321            map.remove(&k);
2322            assert_eq!(None, map.get(&k));
2323            assert_eq!(l - 1, map.len());
2324        }
2325    }
2326
2327    #[test]
2328    fn entry_api() {
2329        let mut map: HashMap<&str, i32> = hashmap! {"bar" => 5};
2330        map.entry("foo").and_modify(|v| *v += 5).or_insert(1);
2331        assert_eq!(1, map[&"foo"]);
2332        map.entry("foo").and_modify(|v| *v += 5).or_insert(1);
2333        assert_eq!(6, map[&"foo"]);
2334        map.entry("bar").and_modify(|v| *v += 5).or_insert(1);
2335        assert_eq!(10, map[&"bar"]);
2336        assert_eq!(
2337            10,
2338            match map.entry("bar") {
2339                Entry::Occupied(entry) => entry.remove(),
2340                _ => panic!(),
2341            }
2342        );
2343        assert!(!map.contains_key(&"bar"));
2344    }
2345
2346    #[test]
2347    fn refpool_crash() {
2348        let _map = HashMap::<u128, usize>::new();
2349    }
2350
2351    #[test]
2352    fn large_map() {
2353        let mut map = HashMap::<_, _>::new();
2354        let size = 32769;
2355        for i in 0..size {
2356            map.insert(i, i);
2357        }
2358        assert_eq!(size, map.len());
2359        for i in 0..size {
2360            assert_eq!(Some(&i), map.get(&i));
2361        }
2362    }
2363
2364    struct PanicOnClone;
2365
2366    impl Clone for PanicOnClone {
2367        fn clone(&self) -> Self {
2368            panic!("PanicOnClone::clone called")
2369        }
2370    }
2371
2372    #[test]
2373    fn into_iter_no_clone() {
2374        let mut map = HashMap::new();
2375        for i in 0..10_000 {
2376            map.insert(i, PanicOnClone);
2377        }
2378        let _ = map.into_iter().collect::<Vec<_>>();
2379    }
2380
2381    #[test]
2382    fn iter_mut_no_clone() {
2383        let mut map = HashMap::new();
2384        for i in 0..10_000 {
2385            map.insert(i, PanicOnClone);
2386        }
2387        let _ = map.iter_mut().collect::<Vec<_>>();
2388    }
2389
2390    #[test]
2391    fn iter_no_clone() {
2392        let mut map = HashMap::new();
2393        for i in 0..10_000 {
2394            map.insert(i, PanicOnClone);
2395        }
2396        let _ = map.iter().collect::<Vec<_>>();
2397    }
2398
2399    proptest! {
2400        #[test]
2401        fn update_and_length(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2402            let mut map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> = Default::default();
2403            for (index, (k, v)) in m.iter().enumerate() {
2404                map = map.update(*k, *v);
2405                assert_eq!(Some(v), map.get(k));
2406                assert_eq!(index + 1, map.len());
2407            }
2408        }
2409
2410        #[test]
2411        fn from_iterator(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2412            let map: HashMap<i16, i16> =
2413                FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2414            assert_eq!(m.len(), map.len());
2415        }
2416
2417        #[test]
2418        fn iterate_over(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2419            let map: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2420            assert_eq!(m.len(), map.iter().count());
2421        }
2422
2423        #[test]
2424        fn equality(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2425            let map1: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2426            let map2: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2427            assert_eq!(map1, map2);
2428        }
2429
2430        #[test]
2431        fn lookup(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2432            let map: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2433            for (k, v) in m {
2434                assert_eq!(Some(*v), map.get(k).cloned(), "{k} not found in map {map:?}");
2435            }
2436        }
2437
2438        #[test]
2439        fn without(ref pairs in collection::vec((i16::ANY, i16::ANY), 0..100)) {
2440            let mut m: collections::HashMap<i16, i16, _> =
2441                collections::HashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2442            for (k, v) in pairs {
2443                m.insert(*k, *v);
2444            }
2445            let mut map: GenericHashMap<i16, i16, _, DefaultSharedPtr> = GenericHashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2446            for (k, v) in &m {
2447                map = map.update(*k, *v);
2448            }
2449            for k in m.keys() {
2450                let l = map.len();
2451                assert_eq!(m.get(k).cloned(), map.get(k).cloned());
2452                map = map.without(k);
2453                assert_eq!(None, map.get(k));
2454                assert_eq!(l - 1, map.len());
2455            }
2456        }
2457
2458        #[test]
2459        fn insert(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2460            let mut mut_map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> = Default::default();
2461            let mut map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> = Default::default();
2462            for (count, (k, v)) in m.iter().enumerate() {
2463                map = map.update(*k, *v);
2464                mut_map.insert(*k, *v);
2465                assert_eq!(count + 1, map.len());
2466                assert_eq!(count + 1, mut_map.len());
2467            }
2468            for (k, v) in m {
2469                assert_eq!(Some(v), map.get(&k));
2470                assert_eq!(Some(v), mut_map.get(&k));
2471            }
2472            assert_eq!(map, mut_map);
2473        }
2474
2475        #[test]
2476        fn remove(ref pairs in collection::vec((i16::ANY, i16::ANY), 0..100)) {
2477            let mut m: collections::HashMap<i16, i16, _> =
2478                collections::HashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2479            for (k, v) in pairs {
2480                m.insert(*k, *v);
2481            }
2482            let mut map: GenericHashMap<i16, i16, _, DefaultSharedPtr> = GenericHashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2483            for (k, v) in &m {
2484                map.insert(*k, *v);
2485            }
2486            for k in m.keys() {
2487                let l = map.len();
2488                assert_eq!(m.get(k).cloned(), map.get(k).cloned());
2489                map.remove(k);
2490                assert_eq!(None, map.get(k));
2491                assert_eq!(l - 1, map.len());
2492            }
2493        }
2494
2495        #[test]
2496        fn delete_and_reinsert(
2497            ref input in collection::hash_map(i16::ANY, i16::ANY, 1..1000),
2498            index_rand in usize::ANY
2499        ) {
2500            let index = *input.keys().nth(index_rand % input.len()).unwrap();
2501            let map1: HashMap<_, _> = HashMap::from_iter(input.clone());
2502            let (val, map2) = map1.extract(&index).unwrap();
2503            let map3 = map2.update(index, val);
2504            for key in map2.keys() {
2505                assert!(*key != index);
2506            }
2507            assert_eq!(map1.len(), map2.len() + 1);
2508            assert_eq!(map1, map3);
2509        }
2510
2511        #[test]
2512        fn proptest_works(ref m in proptest::hash_map(0..9999, ".*", 10..100)) {
2513            assert!(m.len() < 100);
2514            assert!(m.len() >= 10);
2515        }
2516
2517        #[test]
2518        fn exact_size_iterator(ref m in proptest::hash_map(i16::ANY, i16::ANY, 0..100)) {
2519            let mut should_be = m.len();
2520            let mut it = m.iter();
2521            loop {
2522                assert_eq!(should_be, it.len());
2523                match it.next() {
2524                    None => break,
2525                    Some(_) => should_be -= 1,
2526                }
2527            }
2528            assert_eq!(0, it.len());
2529        }
2530
2531        #[test]
2532        fn union(ref m1 in collection::hash_map(i16::ANY, i16::ANY, 0..100),
2533                 ref m2 in collection::hash_map(i16::ANY, i16::ANY, 0..100)) {
2534            let map1: HashMap<i16, i16> = FromIterator::from_iter(m1.iter().map(|(k, v)| (*k, *v)));
2535            let map2: HashMap<i16, i16> = FromIterator::from_iter(m2.iter().map(|(k, v)| (*k, *v)));
2536            let union_map = map1.union(map2);
2537
2538            for k in m1.keys() {
2539                assert!(union_map.contains_key(k));
2540            }
2541
2542            for k in m2.keys() {
2543                assert!(union_map.contains_key(k));
2544            }
2545
2546            for (k, v) in union_map.iter() {
2547                assert_eq!(v, m1.get(k).or_else(|| m2.get(k)).unwrap());
2548            }
2549        }
2550    }
2551
2552    #[test]
2553    fn test_structure_summary() {
2554        // Test with different sizes of HashMaps
2555        let sizes = vec![10, 100, 1_000, 10_000, 100_000];
2556
2557        for size in sizes {
2558            println!("\n=== Testing with {} entries ===", size);
2559
2560            let mut map = HashMap::new();
2561
2562            // Insert entries
2563            for i in 0..size {
2564                // dbg!(i);
2565                map.insert(i, i * 2);
2566            }
2567
2568            // Print structure summary
2569            map.print_structure_summary();
2570        }
2571    }
2572}