ritelinked/
map.rs

1use crate::DefaultHashBuilder;
2use crate::TryReserveError;
3
4use alloc::boxed::Box;
5use core::{
6    borrow::Borrow,
7    cmp::Ordering,
8    fmt,
9    hash::{BuildHasher, Hash, Hasher},
10    iter::FromIterator,
11    marker::PhantomData,
12    mem::{self, MaybeUninit},
13    ops::{Index, IndexMut},
14    ptr::{self, NonNull},
15};
16
17#[cfg(not(feature = "amortized"))]
18use hashbrown::{hash_map, HashMap};
19
20#[cfg(feature = "amortized")]
21use griddle::{hash_map, HashMap};
22
23/// A version of `HashMap` that has a user controllable order for its entries.
24///
25/// It achieves this by keeping its entries in an internal linked list and using a `HashMap` to
26/// point at nodes in this linked list.
27///
28/// The order of entries defaults to "insertion order", but the user can also modify the order of
29/// existing entries by manually moving them to the front or back.
30///
31/// There are two kinds of methods that modify the order of the internal list:
32///
33/// * Methods that have names like `to_front` and `to_back` will unsurprisingly move an existing
34///   entry to the front or back
35/// * Methods that have the word `insert` will insert a new entry ot the back of the list, and if
36///   that method might replace an entry, that method will *also move that existing entry to the
37///   back*.
38pub struct LinkedHashMap<K, V, S = DefaultHashBuilder> {
39    map: HashMap<NonNull<Node<K, V>>, (), NullHasher>,
40    // We need to keep any custom hash builder outside of the HashMap so we can access it alongside
41    // the entry API without mutable aliasing.
42    hash_builder: S,
43    // Circular linked list of nodes.  If `values` is non-null, it will point to a "guard node"
44    // which will never have an initialized key or value, `values.prev` will contain the last key /
45    // value in the list, `values.next` will contain the first key / value in the list.
46    values: Option<NonNull<Node<K, V>>>,
47    // *Singly* linked list of free nodes.  The `prev` pointers in the free list should be assumed
48    // invalid.
49    free: Option<NonNull<Node<K, V>>>,
50}
51
52#[cfg(feature = "ahash")]
53impl<K, V> LinkedHashMap<K, V, DefaultHashBuilder> {
54    #[cfg_attr(feature = "inline-more", inline)]
55    pub fn new() -> Self {
56        Self::default()
57    }
58
59    #[cfg_attr(feature = "inline-more", inline)]
60    pub fn with_capacity(capacity: usize) -> Self {
61        Self::with_capacity_and_hasher(capacity, DefaultHashBuilder::default())
62    }
63}
64
65impl<K, V, S> LinkedHashMap<K, V, S> {
66    #[cfg_attr(feature = "inline-more", inline)]
67    pub fn with_hasher(hash_builder: S) -> Self {
68        Self {
69            hash_builder,
70            map: HashMap::with_hasher(NullHasher),
71            values: None,
72            free: None,
73        }
74    }
75
76    #[cfg_attr(feature = "inline-more", inline)]
77    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
78        Self {
79            hash_builder,
80            map: HashMap::with_capacity_and_hasher(capacity, NullHasher),
81            values: None,
82            free: None,
83        }
84    }
85
86    #[cfg_attr(feature = "inline-more", inline)]
87    pub fn reserve(&mut self, additional: usize) {
88        self.map.reserve(additional);
89    }
90
91    #[cfg_attr(feature = "inline-more", inline)]
92    pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
93        self.map.try_reserve(additional)
94    }
95
96    #[cfg_attr(feature = "inline-more", inline)]
97    pub fn shrink_to_fit(&mut self) {
98        self.map.shrink_to_fit();
99        unsafe { drop_free_nodes(self.free) };
100        self.free = None;
101    }
102
103    #[cfg_attr(feature = "inline-more", inline)]
104    pub fn len(&self) -> usize {
105        self.map.len()
106    }
107
108    #[cfg_attr(feature = "inline-more", inline)]
109    pub fn is_empty(&self) -> bool {
110        self.len() == 0
111    }
112
113    #[cfg_attr(feature = "inline-more", inline)]
114    pub fn clear(&mut self) {
115        self.map.clear();
116        if let Some(mut values) = self.values {
117            unsafe {
118                drop_value_nodes(values);
119                values.as_mut().links.value = ValueLinks {
120                    prev: values,
121                    next: values,
122                };
123            }
124        }
125    }
126
127    #[cfg_attr(feature = "inline-more", inline)]
128    pub fn iter(&self) -> Iter<K, V> {
129        let (head, tail) = if let Some(values) = self.values {
130            unsafe {
131                let ValueLinks { next, prev } = values.as_ref().links.value;
132                (next.as_ptr(), prev.as_ptr())
133            }
134        } else {
135            (ptr::null_mut(), ptr::null_mut())
136        };
137
138        Iter {
139            head,
140            tail,
141            remaining: self.len(),
142            marker: PhantomData,
143        }
144    }
145
146    #[cfg_attr(feature = "inline-more", inline)]
147    pub fn iter_mut(&mut self) -> IterMut<K, V> {
148        let (head, tail) = if let Some(values) = self.values {
149            unsafe {
150                let ValueLinks { next, prev } = values.as_ref().links.value;
151                (Some(next), Some(prev))
152            }
153        } else {
154            (None, None)
155        };
156
157        IterMut {
158            head,
159            tail,
160            remaining: self.len(),
161            marker: PhantomData,
162        }
163    }
164
165    #[cfg_attr(feature = "inline-more", inline)]
166    pub fn drain(&mut self) -> Drain<'_, K, V> {
167        unsafe {
168            let (head, tail) = if let Some(mut values) = self.values {
169                let ValueLinks { next, prev } = values.as_ref().links.value;
170                values.as_mut().links.value = ValueLinks {
171                    next: values,
172                    prev: values,
173                };
174                (Some(next), Some(prev))
175            } else {
176                (None, None)
177            };
178            let len = self.len();
179
180            self.map.clear();
181
182            Drain {
183                free: (&mut self.free).into(),
184                head,
185                tail,
186                remaining: len,
187                marker: PhantomData,
188            }
189        }
190    }
191
192    #[cfg_attr(feature = "inline-more", inline)]
193    pub fn keys(&self) -> Keys<K, V> {
194        Keys { inner: self.iter() }
195    }
196
197    #[cfg_attr(feature = "inline-more", inline)]
198    pub fn values(&self) -> Values<K, V> {
199        Values { inner: self.iter() }
200    }
201
202    #[cfg_attr(feature = "inline-more", inline)]
203    pub fn values_mut(&mut self) -> ValuesMut<K, V> {
204        ValuesMut {
205            inner: self.iter_mut(),
206        }
207    }
208
209    #[cfg_attr(feature = "inline-more", inline)]
210    pub fn front(&self) -> Option<(&K, &V)> {
211        if self.is_empty() {
212            return None;
213        }
214        unsafe {
215            let front = (*self.values.as_ptr()).links.value.next.as_ptr();
216            let (key, value) = (*front).entry_ref();
217            Some((key, value))
218        }
219    }
220
221    #[cfg_attr(feature = "inline-more", inline)]
222    pub fn back(&self) -> Option<(&K, &V)> {
223        if self.is_empty() {
224            return None;
225        }
226        unsafe {
227            let back = &*(*self.values.as_ptr()).links.value.prev.as_ptr();
228            let (key, value) = (*back).entry_ref();
229            Some((key, value))
230        }
231    }
232
233    #[cfg_attr(feature = "inline-more", inline)]
234    pub fn hasher(&self) -> &S {
235        &self.hash_builder
236    }
237
238    #[cfg_attr(feature = "inline-more", inline)]
239    pub fn capacity(&self) -> usize {
240        self.map.capacity()
241    }
242}
243
244impl<K, V, S> LinkedHashMap<K, V, S>
245where
246    K: Eq + Hash,
247    S: BuildHasher,
248{
249    #[cfg_attr(feature = "inline-more", inline)]
250    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S> {
251        match self.raw_entry_mut().from_key(&key) {
252            RawEntryMut::Occupied(occupied) => Entry::Occupied(OccupiedEntry {
253                key,
254                raw_entry: occupied,
255            }),
256            RawEntryMut::Vacant(vacant) => Entry::Vacant(VacantEntry {
257                key,
258                raw_entry: vacant,
259            }),
260        }
261    }
262
263    #[inline]
264    pub fn get<Q>(&self, k: &Q) -> Option<&V>
265    where
266        K: Borrow<Q>,
267        Q: Hash + Eq + ?Sized,
268    {
269        self.raw_entry().from_key(k).map(|(_, v)| v)
270    }
271
272    #[inline]
273    pub fn get_key_value<Q>(&self, k: &Q) -> Option<(&K, &V)>
274    where
275        K: Borrow<Q>,
276        Q: Hash + Eq + ?Sized,
277    {
278        self.raw_entry().from_key(k)
279    }
280
281    #[cfg_attr(feature = "inline-more", inline)]
282    pub fn contains_key<Q>(&self, k: &Q) -> bool
283    where
284        K: Borrow<Q>,
285        Q: Hash + Eq + ?Sized,
286    {
287        self.get(k).is_some()
288    }
289
290    #[cfg_attr(feature = "inline-more", inline)]
291    pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
292    where
293        K: Borrow<Q>,
294        Q: Hash + Eq + ?Sized,
295    {
296        match self.raw_entry_mut().from_key(k) {
297            RawEntryMut::Occupied(occupied) => Some(occupied.into_mut()),
298            RawEntryMut::Vacant(_) => None,
299        }
300    }
301
302    #[cfg_attr(feature = "inline-more", inline)]
303    pub fn get_refresh<Q>(&mut self, k: &Q) -> Option<&mut V>
304    where
305        K: Borrow<Q>,
306        Q: Hash + Eq + ?Sized,
307    {
308        match self.raw_entry_mut().from_key(k) {
309            RawEntryMut::Occupied(mut occupied) => {
310                occupied.to_back();
311                Some(occupied.into_mut())
312            }
313            RawEntryMut::Vacant(_) => None,
314        }
315    }
316
317    /// Inserts the given key / value pair at the *back* of the internal linked list.
318    ///
319    /// Returns the previously set value, if one existed prior to this call.  After this call,
320    /// calling `LinkedHashMap::back` will return a reference to this key / value pair.
321    #[cfg_attr(feature = "inline-more", inline)]
322    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
323        match self.raw_entry_mut().from_key(&k) {
324            RawEntryMut::Occupied(mut occupied) => {
325                occupied.to_back();
326                Some(occupied.replace_value(v))
327            }
328            RawEntryMut::Vacant(vacant) => {
329                vacant.insert(k, v);
330                None
331            }
332        }
333    }
334
335    /// If the given key is not in this map, inserts the key / value pair at the *back* of the
336    /// internal linked list and returns `None`, otherwise, replaces the existing value with the
337    /// given value *without* moving the entry in the internal linked list and returns the previous
338    /// value.
339    #[cfg_attr(feature = "inline-more", inline)]
340    pub fn replace(&mut self, k: K, v: V) -> Option<V> {
341        match self.raw_entry_mut().from_key(&k) {
342            RawEntryMut::Occupied(mut occupied) => Some(occupied.replace_value(v)),
343            RawEntryMut::Vacant(vacant) => {
344                vacant.insert(k, v);
345                None
346            }
347        }
348    }
349
350    #[cfg_attr(feature = "inline-more", inline)]
351    pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
352    where
353        K: Borrow<Q>,
354        Q: Hash + Eq + ?Sized,
355    {
356        match self.raw_entry_mut().from_key(k) {
357            RawEntryMut::Occupied(occupied) => Some(occupied.remove()),
358            RawEntryMut::Vacant(_) => None,
359        }
360    }
361
362    #[cfg_attr(feature = "inline-more", inline)]
363    pub fn remove_entry<Q>(&mut self, k: &Q) -> Option<(K, V)>
364    where
365        K: Borrow<Q>,
366        Q: Hash + Eq + ?Sized,
367    {
368        match self.raw_entry_mut().from_key(k) {
369            RawEntryMut::Occupied(occupied) => Some(occupied.remove_entry()),
370            RawEntryMut::Vacant(_) => None,
371        }
372    }
373
374    #[cfg_attr(feature = "inline-more", inline)]
375    pub fn retain<F>(&mut self, mut f: F)
376    where
377        F: FnMut(&K, &mut V) -> bool,
378    {
379        // We do not drop the key and value when a value is filtered from the map during the call to
380        // `retain`.  We need to be very careful not to have a live `HashMap` entry pointing to
381        // either a dangling `Node` or a `Node` with dropped keys / values.  Since the key and value
382        // types may panic on drop, they may short-circuit the entry in the map actually being
383        // removed.  Instead, we push the removed nodes onto the free list eagerly, then try and
384        // drop the keys and values for any newly freed nodes *after* `HashMap::retain` has
385        // completely finished.
386        struct DropFilteredValues<'a, K, V> {
387            free: &'a mut Option<NonNull<Node<K, V>>>,
388            cur_free: Option<NonNull<Node<K, V>>>,
389        }
390
391        impl<'a, K, V> DropFilteredValues<'a, K, V> {
392            #[inline]
393            fn drop_later(&mut self, node: NonNull<Node<K, V>>) {
394                unsafe {
395                    detach_node(node);
396                    push_free(&mut self.cur_free, node);
397                }
398            }
399        }
400
401        impl<'a, K, V> Drop for DropFilteredValues<'a, K, V> {
402            fn drop(&mut self) {
403                unsafe {
404                    let end_free = self.cur_free;
405                    while self.cur_free != *self.free {
406                        let cur_free = self.cur_free.as_ptr();
407                        (*cur_free).take_entry();
408                        self.cur_free = (*cur_free).links.free.next;
409                    }
410                    *self.free = end_free;
411                }
412            }
413        }
414
415        let free = self.free;
416        let mut drop_filtered_values = DropFilteredValues {
417            free: &mut self.free,
418            cur_free: free,
419        };
420
421        if let Some(values) = self.values {
422            unsafe {
423                let mut cur = values.as_ref().links.value.next;
424                while cur != values {
425                    let next = cur.as_ref().links.value.next;
426                    let (k, v) = (*cur.as_ptr()).entry_mut();
427                    if !f(k, v) {
428                        let hash = hash_key(&self.hash_builder, k);
429                        match self
430                            .map
431                            .raw_entry_mut()
432                            .from_hash(hash, |o| (*o).as_ref().key_ref().eq(k))
433                        {
434                            hash_map::RawEntryMut::Occupied(entry) => {
435                                entry.remove();
436                                drop_filtered_values.drop_later(cur);
437                            }
438                            hash_map::RawEntryMut::Vacant(_) => unreachable!(),
439                        }
440                    }
441                    cur = next;
442                }
443            }
444        }
445    }
446
447    #[cfg_attr(feature = "inline-more", inline)]
448    pub fn pop_front(&mut self) -> Option<(K, V)> {
449        if self.is_empty() {
450            return None;
451        }
452        unsafe {
453            let front = (*self.values.as_ptr()).links.value.next;
454            match self.map.raw_entry_mut().from_hash(
455                hash_key(&self.hash_builder, front.as_ref().key_ref()),
456                |k| (*k).as_ref().key_ref().eq(front.as_ref().key_ref()),
457            ) {
458                hash_map::RawEntryMut::Occupied(occupied) => {
459                    Some(remove_node(&mut self.free, occupied.remove_entry().0))
460                }
461                hash_map::RawEntryMut::Vacant(_) => None,
462            }
463        }
464    }
465
466    #[cfg_attr(feature = "inline-more", inline)]
467    pub fn pop_back(&mut self) -> Option<(K, V)> {
468        if self.is_empty() {
469            return None;
470        }
471        unsafe {
472            let back = (*self.values.as_ptr()).links.value.prev;
473            match self
474                .map
475                .raw_entry_mut()
476                .from_hash(hash_key(&self.hash_builder, back.as_ref().key_ref()), |k| {
477                    (*k).as_ref().key_ref().eq(back.as_ref().key_ref())
478                }) {
479                hash_map::RawEntryMut::Occupied(occupied) => {
480                    Some(remove_node(&mut self.free, occupied.remove_entry().0))
481                }
482                hash_map::RawEntryMut::Vacant(_) => None,
483            }
484        }
485    }
486
487    /// If an entry with this key exists, move it to the front of the list and return a reference to
488    /// the value.
489    #[cfg_attr(feature = "inline-more", inline)]
490    #[allow(clippy::wrong_self_convention)]
491    pub fn to_front<Q>(&mut self, k: &Q) -> Option<&mut V>
492    where
493        K: Borrow<Q>,
494        Q: Hash + Eq + ?Sized,
495    {
496        match self.raw_entry_mut().from_key(k) {
497            RawEntryMut::Occupied(mut occupied) => {
498                occupied.to_front();
499                Some(occupied.into_mut())
500            }
501            RawEntryMut::Vacant(_) => None,
502        }
503    }
504
505    /// If an entry with this key exists, move it to the back of the list and return a reference to
506    /// the value.
507    #[cfg_attr(feature = "inline-more", inline)]
508    #[allow(clippy::wrong_self_convention)]
509    pub fn to_back<Q>(&mut self, k: &Q) -> Option<&mut V>
510    where
511        K: Borrow<Q>,
512        Q: Hash + Eq + ?Sized,
513    {
514        match self.raw_entry_mut().from_key(k) {
515            RawEntryMut::Occupied(mut occupied) => {
516                occupied.to_back();
517                Some(occupied.into_mut())
518            }
519            RawEntryMut::Vacant(_) => None,
520        }
521    }
522}
523
524impl<K, V, S> LinkedHashMap<K, V, S>
525where
526    S: BuildHasher,
527{
528    #[cfg_attr(feature = "inline-more", inline)]
529    pub fn raw_entry(&self) -> RawEntryBuilder<'_, K, V, S> {
530        RawEntryBuilder {
531            hash_builder: &self.hash_builder,
532            entry: self.map.raw_entry(),
533        }
534    }
535
536    #[cfg_attr(feature = "inline-more", inline)]
537    pub fn raw_entry_mut(&mut self) -> RawEntryBuilderMut<'_, K, V, S> {
538        RawEntryBuilderMut {
539            hash_builder: &self.hash_builder,
540            values: &mut self.values,
541            free: &mut self.free,
542            entry: self.map.raw_entry_mut(),
543        }
544    }
545}
546
547impl<K, V, S> Default for LinkedHashMap<K, V, S>
548where
549    S: Default,
550{
551    #[cfg_attr(feature = "inline-more", inline)]
552    fn default() -> Self {
553        Self::with_hasher(S::default())
554    }
555}
556
557impl<K: Hash + Eq, V, S: BuildHasher + Default> FromIterator<(K, V)> for LinkedHashMap<K, V, S> {
558    #[cfg_attr(feature = "inline-more", inline)]
559    fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
560        let iter = iter.into_iter();
561        let mut map = Self::with_capacity_and_hasher(iter.size_hint().0, S::default());
562        map.extend(iter);
563        map
564    }
565}
566
567impl<K, V, S> fmt::Debug for LinkedHashMap<K, V, S>
568where
569    K: fmt::Debug,
570    V: fmt::Debug,
571{
572    #[cfg_attr(feature = "inline-more", inline)]
573    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
574        f.debug_map().entries(self).finish()
575    }
576}
577
578impl<K: Hash + Eq, V: PartialEq, S: BuildHasher> PartialEq for LinkedHashMap<K, V, S> {
579    #[cfg_attr(feature = "inline-more", inline)]
580    fn eq(&self, other: &Self) -> bool {
581        self.len() == other.len() && self.iter().eq(other)
582    }
583}
584
585impl<K: Hash + Eq, V: Eq, S: BuildHasher> Eq for LinkedHashMap<K, V, S> {}
586
587impl<K: Hash + Eq + PartialOrd, V: PartialOrd, S: BuildHasher> PartialOrd
588    for LinkedHashMap<K, V, S>
589{
590    #[cfg_attr(feature = "inline-more", inline)]
591    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
592        self.iter().partial_cmp(other)
593    }
594
595    #[cfg_attr(feature = "inline-more", inline)]
596    fn lt(&self, other: &Self) -> bool {
597        self.iter().lt(other)
598    }
599
600    #[cfg_attr(feature = "inline-more", inline)]
601    fn le(&self, other: &Self) -> bool {
602        self.iter().le(other)
603    }
604
605    #[cfg_attr(feature = "inline-more", inline)]
606    fn ge(&self, other: &Self) -> bool {
607        self.iter().ge(other)
608    }
609
610    #[cfg_attr(feature = "inline-more", inline)]
611    fn gt(&self, other: &Self) -> bool {
612        self.iter().gt(other)
613    }
614}
615
616impl<K: Hash + Eq + Ord, V: Ord, S: BuildHasher> Ord for LinkedHashMap<K, V, S> {
617    #[cfg_attr(feature = "inline-more", inline)]
618    fn cmp(&self, other: &Self) -> Ordering {
619        self.iter().cmp(other)
620    }
621}
622
623impl<K: Hash + Eq, V: Hash, S: BuildHasher> Hash for LinkedHashMap<K, V, S> {
624    #[cfg_attr(feature = "inline-more", inline)]
625    fn hash<H: Hasher>(&self, h: &mut H) {
626        for e in self.iter() {
627            e.hash(h);
628        }
629    }
630}
631
632impl<K, V, S> Drop for LinkedHashMap<K, V, S> {
633    #[cfg_attr(feature = "inline-more", inline)]
634    fn drop(&mut self) {
635        unsafe {
636            if let Some(values) = self.values {
637                drop_value_nodes(values);
638                Box::from_raw(values.as_ptr());
639            }
640            drop_free_nodes(self.free);
641        }
642    }
643}
644
645unsafe impl<K: Send, V: Send, S: Send> Send for LinkedHashMap<K, V, S> {}
646unsafe impl<K: Sync, V: Sync, S: Sync> Sync for LinkedHashMap<K, V, S> {}
647
648impl<'a, K, V, S, Q> Index<&'a Q> for LinkedHashMap<K, V, S>
649where
650    K: Hash + Eq + Borrow<Q>,
651    S: BuildHasher,
652    Q: Eq + Hash + ?Sized,
653{
654    type Output = V;
655
656    #[cfg_attr(feature = "inline-more", inline)]
657    fn index(&self, index: &'a Q) -> &V {
658        self.get(index).expect("no entry found for key")
659    }
660}
661
662impl<'a, K, V, S, Q> IndexMut<&'a Q> for LinkedHashMap<K, V, S>
663where
664    K: Hash + Eq + Borrow<Q>,
665    S: BuildHasher,
666    Q: Eq + Hash + ?Sized,
667{
668    #[cfg_attr(feature = "inline-more", inline)]
669    fn index_mut(&mut self, index: &'a Q) -> &mut V {
670        self.get_mut(index).expect("no entry found for key")
671    }
672}
673
674impl<K: Hash + Eq + Clone, V: Clone, S: BuildHasher + Clone> Clone for LinkedHashMap<K, V, S> {
675    #[cfg_attr(feature = "inline-more", inline)]
676    fn clone(&self) -> Self {
677        let mut map = Self::with_hasher(self.hash_builder.clone());
678        map.extend(self.iter().map(|(k, v)| (k.clone(), v.clone())));
679        map
680    }
681}
682
683impl<K: Hash + Eq, V, S: BuildHasher> Extend<(K, V)> for LinkedHashMap<K, V, S> {
684    #[cfg_attr(feature = "inline-more", inline)]
685    fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I) {
686        for (k, v) in iter {
687            self.insert(k, v);
688        }
689    }
690}
691
692impl<'a, K, V, S> Extend<(&'a K, &'a V)> for LinkedHashMap<K, V, S>
693where
694    K: 'a + Hash + Eq + Copy,
695    V: 'a + Copy,
696    S: BuildHasher,
697{
698    #[cfg_attr(feature = "inline-more", inline)]
699    fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I) {
700        for (&k, &v) in iter {
701            self.insert(k, v);
702        }
703    }
704}
705
706pub enum Entry<'a, K, V, S> {
707    Occupied(OccupiedEntry<'a, K, V>),
708    Vacant(VacantEntry<'a, K, V, S>),
709}
710
711impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for Entry<'_, K, V, S> {
712    #[cfg_attr(feature = "inline-more", inline)]
713    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
714        match *self {
715            Entry::Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
716            Entry::Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
717        }
718    }
719}
720
721impl<'a, K, V, S> Entry<'a, K, V, S> {
722    /// If this entry is vacant, inserts a new entry with the given value and returns a reference to
723    /// it.
724    ///
725    /// If this entry is occupied, this method *moves the occupied entry to the back of the internal
726    /// linked list* and returns a reference to the existing value.
727    #[cfg_attr(feature = "inline-more", inline)]
728    pub fn or_insert(self, default: V) -> &'a mut V
729    where
730        K: Hash,
731        S: BuildHasher,
732    {
733        match self {
734            Entry::Occupied(mut entry) => {
735                entry.to_back();
736                entry.into_mut()
737            }
738            Entry::Vacant(entry) => entry.insert(default),
739        }
740    }
741
742    /// Similar to `Entry::or_insert`, but accepts a function to construct a new value if this entry
743    /// is vacant.
744    #[cfg_attr(feature = "inline-more", inline)]
745    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V
746    where
747        K: Hash,
748        S: BuildHasher,
749    {
750        match self {
751            Entry::Occupied(mut entry) => {
752                entry.to_back();
753                entry.into_mut()
754            }
755            Entry::Vacant(entry) => entry.insert(default()),
756        }
757    }
758
759    #[cfg_attr(feature = "inline-more", inline)]
760    pub fn key(&self) -> &K {
761        match *self {
762            Entry::Occupied(ref entry) => entry.key(),
763            Entry::Vacant(ref entry) => entry.key(),
764        }
765    }
766
767    #[cfg_attr(feature = "inline-more", inline)]
768    pub fn and_modify<F>(self, f: F) -> Self
769    where
770        F: FnOnce(&mut V),
771    {
772        match self {
773            Entry::Occupied(mut entry) => {
774                f(entry.get_mut());
775                Entry::Occupied(entry)
776            }
777            Entry::Vacant(entry) => Entry::Vacant(entry),
778        }
779    }
780}
781
782pub struct OccupiedEntry<'a, K, V> {
783    key: K,
784    raw_entry: RawOccupiedEntryMut<'a, K, V>,
785}
786
787impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for OccupiedEntry<'_, K, V> {
788    #[cfg_attr(feature = "inline-more", inline)]
789    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790        f.debug_struct("OccupiedEntry")
791            .field("key", self.key())
792            .field("value", self.get())
793            .finish()
794    }
795}
796
797impl<'a, K, V> OccupiedEntry<'a, K, V> {
798    #[cfg_attr(feature = "inline-more", inline)]
799    pub fn key(&self) -> &K {
800        self.raw_entry.key()
801    }
802
803    #[cfg_attr(feature = "inline-more", inline)]
804    pub fn remove_entry(self) -> (K, V) {
805        self.raw_entry.remove_entry()
806    }
807
808    #[cfg_attr(feature = "inline-more", inline)]
809    pub fn get(&self) -> &V {
810        self.raw_entry.get()
811    }
812
813    #[cfg_attr(feature = "inline-more", inline)]
814    pub fn get_mut(&mut self) -> &mut V {
815        self.raw_entry.get_mut()
816    }
817
818    #[cfg_attr(feature = "inline-more", inline)]
819    pub fn into_mut(self) -> &'a mut V {
820        self.raw_entry.into_mut()
821    }
822
823    #[cfg_attr(feature = "inline-more", inline)]
824    #[allow(clippy::wrong_self_convention)]
825    pub fn to_back(&mut self) {
826        self.raw_entry.to_back()
827    }
828
829    #[cfg_attr(feature = "inline-more", inline)]
830    #[allow(clippy::wrong_self_convention)]
831    pub fn to_front(&mut self) {
832        self.raw_entry.to_front()
833    }
834
835    /// Replaces this entry's value with the provided value.
836    ///
837    /// Similarly to `LinkedHashMap::insert`, this moves the existing entry to the back of the
838    /// internal linked list.
839    #[cfg_attr(feature = "inline-more", inline)]
840    pub fn insert(&mut self, value: V) -> V {
841        self.raw_entry.to_back();
842        self.raw_entry.replace_value(value)
843    }
844
845    #[cfg_attr(feature = "inline-more", inline)]
846    pub fn remove(self) -> V {
847        self.raw_entry.remove()
848    }
849
850    /// Similar to `OccupiedEntry::replace_entry`, but *does* move the entry to the back of the
851    /// internal linked list.
852    #[cfg_attr(feature = "inline-more", inline)]
853    pub fn insert_entry(mut self, value: V) -> (K, V) {
854        self.raw_entry.to_back();
855        self.replace_entry(value)
856    }
857
858    /// Replaces the entry's key with the key provided to `LinkedHashMap::entry`, and replaces the
859    /// entry's value with the given `value` parameter.
860    ///
861    /// Does *not* move the entry to the back of the internal linked list.
862    pub fn replace_entry(mut self, value: V) -> (K, V) {
863        let old_key = mem::replace(self.raw_entry.key_mut(), self.key);
864        let old_value = mem::replace(self.raw_entry.get_mut(), value);
865        (old_key, old_value)
866    }
867
868    /// Replaces this entry's key with the key provided to `LinkedHashMap::entry`.
869    ///
870    /// Does *not* move the entry to the back of the internal linked list.
871    #[cfg_attr(feature = "inline-more", inline)]
872    pub fn replace_key(mut self) -> K {
873        mem::replace(self.raw_entry.key_mut(), self.key)
874    }
875}
876
877pub struct VacantEntry<'a, K, V, S> {
878    key: K,
879    raw_entry: RawVacantEntryMut<'a, K, V, S>,
880}
881
882impl<K: fmt::Debug, V, S> fmt::Debug for VacantEntry<'_, K, V, S> {
883    #[cfg_attr(feature = "inline-more", inline)]
884    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
885        f.debug_tuple("VacantEntry").field(self.key()).finish()
886    }
887}
888
889impl<'a, K, V, S> VacantEntry<'a, K, V, S> {
890    #[cfg_attr(feature = "inline-more", inline)]
891    pub fn key(&self) -> &K {
892        &self.key
893    }
894
895    #[cfg_attr(feature = "inline-more", inline)]
896    pub fn into_key(self) -> K {
897        self.key
898    }
899
900    /// Insert's the key for this vacant entry paired with the given value as a new entry at the
901    /// *back* of the internal linked list.
902    #[cfg_attr(feature = "inline-more", inline)]
903    pub fn insert(self, value: V) -> &'a mut V
904    where
905        K: Hash,
906        S: BuildHasher,
907    {
908        self.raw_entry.insert(self.key, value).1
909    }
910}
911
912pub struct RawEntryBuilder<'a, K, V, S> {
913    hash_builder: &'a S,
914    entry: hash_map::RawEntryBuilder<'a, NonNull<Node<K, V>>, (), NullHasher>,
915}
916
917impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S>
918where
919    S: BuildHasher,
920{
921    #[cfg_attr(feature = "inline-more", inline)]
922    #[allow(clippy::wrong_self_convention)]
923    pub fn from_key<Q>(self, k: &Q) -> Option<(&'a K, &'a V)>
924    where
925        K: Borrow<Q>,
926        Q: Hash + Eq + ?Sized,
927    {
928        let hash = hash_key(self.hash_builder, k);
929        self.from_key_hashed_nocheck(hash, k)
930    }
931
932    #[inline]
933    #[allow(clippy::wrong_self_convention)]
934    pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> Option<(&'a K, &'a V)>
935    where
936        K: Borrow<Q>,
937        Q: Hash + Eq + ?Sized,
938    {
939        self.from_hash(hash, move |o| k.eq(o.borrow()))
940    }
941
942    #[cfg_attr(feature = "inline-more", inline)]
943    #[allow(clippy::wrong_self_convention)]
944    pub fn from_hash(
945        self,
946        hash: u64,
947        mut is_match: impl FnMut(&K) -> bool,
948    ) -> Option<(&'a K, &'a V)> {
949        unsafe {
950            let node = *self
951                .entry
952                .from_hash(hash, move |k| is_match((*k).as_ref().key_ref()))?
953                .0;
954
955            let (key, value) = (*node.as_ptr()).entry_ref();
956            Some((key, value))
957        }
958    }
959}
960
961unsafe impl<'a, K, V, S> Send for RawEntryBuilder<'a, K, V, S>
962where
963    K: Send,
964    V: Send,
965    S: Send,
966{
967}
968
969unsafe impl<'a, K, V, S> Sync for RawEntryBuilder<'a, K, V, S>
970where
971    K: Sync,
972    V: Sync,
973    S: Sync,
974{
975}
976
977pub struct RawEntryBuilderMut<'a, K, V, S> {
978    hash_builder: &'a S,
979    values: &'a mut Option<NonNull<Node<K, V>>>,
980    free: &'a mut Option<NonNull<Node<K, V>>>,
981    entry: hash_map::RawEntryBuilderMut<'a, NonNull<Node<K, V>>, (), NullHasher>,
982}
983
984impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S>
985where
986    S: BuildHasher,
987{
988    #[cfg_attr(feature = "inline-more", inline)]
989    #[allow(clippy::wrong_self_convention)]
990    pub fn from_key<Q>(self, k: &Q) -> RawEntryMut<'a, K, V, S>
991    where
992        K: Borrow<Q>,
993        Q: Hash + Eq + ?Sized,
994    {
995        let hash = hash_key(self.hash_builder, k);
996        self.from_key_hashed_nocheck(hash, k)
997    }
998
999    #[cfg_attr(feature = "inline-more", inline)]
1000    #[allow(clippy::wrong_self_convention)]
1001    pub fn from_key_hashed_nocheck<Q>(self, hash: u64, k: &Q) -> RawEntryMut<'a, K, V, S>
1002    where
1003        K: Borrow<Q>,
1004        Q: Hash + Eq + ?Sized,
1005    {
1006        self.from_hash(hash, move |o| k.eq(o.borrow()))
1007    }
1008
1009    #[cfg_attr(feature = "inline-more", inline)]
1010    #[allow(clippy::wrong_self_convention)]
1011    pub fn from_hash(
1012        self,
1013        hash: u64,
1014        mut is_match: impl FnMut(&K) -> bool,
1015    ) -> RawEntryMut<'a, K, V, S> {
1016        let entry = self
1017            .entry
1018            .from_hash(hash, move |k| is_match(unsafe { (*k).as_ref().key_ref() }));
1019
1020        match entry {
1021            hash_map::RawEntryMut::Occupied(occupied) => {
1022                RawEntryMut::Occupied(RawOccupiedEntryMut {
1023                    free: self.free,
1024                    values: self.values,
1025                    entry: occupied,
1026                })
1027            }
1028            hash_map::RawEntryMut::Vacant(vacant) => RawEntryMut::Vacant(RawVacantEntryMut {
1029                hash_builder: self.hash_builder,
1030                values: self.values,
1031                free: self.free,
1032                entry: vacant,
1033            }),
1034        }
1035    }
1036}
1037
1038unsafe impl<'a, K, V, S> Send for RawEntryBuilderMut<'a, K, V, S>
1039where
1040    K: Send,
1041    V: Send,
1042    S: Send,
1043{
1044}
1045
1046unsafe impl<'a, K, V, S> Sync for RawEntryBuilderMut<'a, K, V, S>
1047where
1048    K: Sync,
1049    V: Sync,
1050    S: Sync,
1051{
1052}
1053
1054pub enum RawEntryMut<'a, K, V, S> {
1055    Occupied(RawOccupiedEntryMut<'a, K, V>),
1056    Vacant(RawVacantEntryMut<'a, K, V, S>),
1057}
1058
1059impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
1060    /// Similarly to `Entry::or_insert`, if this entry is occupied, it will move the existing entry
1061    /// to the back of the internal linked list.
1062    #[cfg_attr(feature = "inline-more", inline)]
1063    pub fn or_insert(self, default_key: K, default_val: V) -> (&'a mut K, &'a mut V)
1064    where
1065        K: Hash,
1066        S: BuildHasher,
1067    {
1068        match self {
1069            RawEntryMut::Occupied(mut entry) => {
1070                entry.to_back();
1071                entry.into_key_value()
1072            }
1073            RawEntryMut::Vacant(entry) => entry.insert(default_key, default_val),
1074        }
1075    }
1076
1077    /// Similarly to `Entry::or_insert_with`, if this entry is occupied, it will move the existing
1078    /// entry to the back of the internal linked list.
1079    #[cfg_attr(feature = "inline-more", inline)]
1080    pub fn or_insert_with<F>(self, default: F) -> (&'a mut K, &'a mut V)
1081    where
1082        F: FnOnce() -> (K, V),
1083        K: Hash,
1084        S: BuildHasher,
1085    {
1086        match self {
1087            RawEntryMut::Occupied(mut entry) => {
1088                entry.to_back();
1089                entry.into_key_value()
1090            }
1091            RawEntryMut::Vacant(entry) => {
1092                let (k, v) = default();
1093                entry.insert(k, v)
1094            }
1095        }
1096    }
1097
1098    #[cfg_attr(feature = "inline-more", inline)]
1099    pub fn and_modify<F>(self, f: F) -> Self
1100    where
1101        F: FnOnce(&mut K, &mut V),
1102    {
1103        match self {
1104            RawEntryMut::Occupied(mut entry) => {
1105                {
1106                    let (k, v) = entry.get_key_value_mut();
1107                    f(k, v);
1108                }
1109                RawEntryMut::Occupied(entry)
1110            }
1111            RawEntryMut::Vacant(entry) => RawEntryMut::Vacant(entry),
1112        }
1113    }
1114}
1115
1116pub struct RawOccupiedEntryMut<'a, K, V> {
1117    free: &'a mut Option<NonNull<Node<K, V>>>,
1118    values: &'a mut Option<NonNull<Node<K, V>>>,
1119    entry: hash_map::RawOccupiedEntryMut<'a, NonNull<Node<K, V>>, (), NullHasher>,
1120}
1121
1122impl<'a, K, V> RawOccupiedEntryMut<'a, K, V> {
1123    #[cfg_attr(feature = "inline-more", inline)]
1124    pub fn key(&self) -> &K {
1125        self.get_key_value().0
1126    }
1127
1128    #[cfg_attr(feature = "inline-more", inline)]
1129    pub fn key_mut(&mut self) -> &mut K {
1130        self.get_key_value_mut().0
1131    }
1132
1133    #[cfg_attr(feature = "inline-more", inline)]
1134    pub fn into_key(self) -> &'a mut K {
1135        self.into_key_value().0
1136    }
1137
1138    #[cfg_attr(feature = "inline-more", inline)]
1139    pub fn get(&self) -> &V {
1140        self.get_key_value().1
1141    }
1142
1143    #[cfg_attr(feature = "inline-more", inline)]
1144    pub fn get_mut(&mut self) -> &mut V {
1145        self.get_key_value_mut().1
1146    }
1147
1148    #[cfg_attr(feature = "inline-more", inline)]
1149    pub fn into_mut(self) -> &'a mut V {
1150        self.into_key_value().1
1151    }
1152
1153    #[cfg_attr(feature = "inline-more", inline)]
1154    pub fn get_key_value(&self) -> (&K, &V) {
1155        unsafe {
1156            let node = *self.entry.key();
1157            let (key, value) = (*node.as_ptr()).entry_ref();
1158            (key, value)
1159        }
1160    }
1161
1162    #[inline]
1163    pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
1164        unsafe {
1165            let node = *self.entry.key_mut();
1166            let (key, value) = (*node.as_ptr()).entry_mut();
1167            (key, value)
1168        }
1169    }
1170
1171    #[cfg_attr(feature = "inline-more", inline)]
1172    pub fn into_key_value(self) -> (&'a mut K, &'a mut V) {
1173        unsafe {
1174            let node = *self.entry.into_key();
1175            let (key, value) = (*node.as_ptr()).entry_mut();
1176            (key, value)
1177        }
1178    }
1179
1180    #[cfg_attr(feature = "inline-more", inline)]
1181    #[allow(clippy::wrong_self_convention)]
1182    pub fn to_back(&mut self) {
1183        unsafe {
1184            let node = *self.entry.key_mut();
1185            detach_node(node);
1186            attach_before(node, NonNull::new_unchecked(self.values.as_ptr()));
1187        }
1188    }
1189
1190    #[cfg_attr(feature = "inline-more", inline)]
1191    #[allow(clippy::wrong_self_convention)]
1192    pub fn to_front(&mut self) {
1193        unsafe {
1194            let node = *self.entry.key_mut();
1195            detach_node(node);
1196            attach_before(node, (*self.values.as_ptr()).links.value.next);
1197        }
1198    }
1199
1200    #[cfg_attr(feature = "inline-more", inline)]
1201    pub fn replace_value(&mut self, value: V) -> V {
1202        unsafe {
1203            let mut node = *self.entry.key_mut();
1204            mem::replace(&mut node.as_mut().entry_mut().1, value)
1205        }
1206    }
1207
1208    #[cfg_attr(feature = "inline-more", inline)]
1209    pub fn replace_key(&mut self, key: K) -> K {
1210        unsafe {
1211            let mut node = *self.entry.key_mut();
1212            mem::replace(&mut node.as_mut().entry_mut().0, key)
1213        }
1214    }
1215
1216    #[cfg_attr(feature = "inline-more", inline)]
1217    pub fn remove(self) -> V {
1218        self.remove_entry().1
1219    }
1220
1221    #[cfg_attr(feature = "inline-more", inline)]
1222    pub fn remove_entry(self) -> (K, V) {
1223        let node = self.entry.remove_entry().0;
1224        unsafe { remove_node(self.free, node) }
1225    }
1226}
1227
1228pub struct RawVacantEntryMut<'a, K, V, S> {
1229    hash_builder: &'a S,
1230    values: &'a mut Option<NonNull<Node<K, V>>>,
1231    free: &'a mut Option<NonNull<Node<K, V>>>,
1232    entry: hash_map::RawVacantEntryMut<'a, NonNull<Node<K, V>>, (), NullHasher>,
1233}
1234
1235impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
1236    #[cfg_attr(feature = "inline-more", inline)]
1237    pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
1238    where
1239        K: Hash,
1240        S: BuildHasher,
1241    {
1242        let hash = hash_key(self.hash_builder, &key);
1243        self.insert_hashed_nocheck(hash, key, value)
1244    }
1245
1246    #[cfg_attr(feature = "inline-more", inline)]
1247    pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V)
1248    where
1249        K: Hash,
1250        S: BuildHasher,
1251    {
1252        let hash_builder = self.hash_builder;
1253        self.insert_with_hasher(hash, key, value, |k| hash_key(hash_builder, k))
1254    }
1255
1256    #[cfg_attr(feature = "inline-more", inline)]
1257    pub fn insert_with_hasher(
1258        self,
1259        hash: u64,
1260        key: K,
1261        value: V,
1262        hasher: impl Fn(&K) -> u64,
1263    ) -> (&'a mut K, &'a mut V)
1264    where
1265        S: BuildHasher,
1266    {
1267        unsafe {
1268            ensure_guard_node(self.values);
1269            let mut new_node = allocate_node(self.free);
1270            new_node.as_mut().put_entry((key, value));
1271            attach_before(new_node, NonNull::new_unchecked(self.values.as_ptr()));
1272
1273            let node = *self
1274                .entry
1275                .insert_with_hasher(hash, new_node, (), move |k| hasher((*k).as_ref().key_ref()))
1276                .0;
1277
1278            let (key, value) = (*node.as_ptr()).entry_mut();
1279            (key, value)
1280        }
1281    }
1282}
1283
1284impl<K, V, S> fmt::Debug for RawEntryBuilderMut<'_, K, V, S> {
1285    #[cfg_attr(feature = "inline-more", inline)]
1286    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1287        f.debug_struct("RawEntryBuilder").finish()
1288    }
1289}
1290
1291impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawEntryMut<'_, K, V, S> {
1292    #[cfg_attr(feature = "inline-more", inline)]
1293    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1294        match *self {
1295            RawEntryMut::Vacant(ref v) => f.debug_tuple("RawEntry").field(v).finish(),
1296            RawEntryMut::Occupied(ref o) => f.debug_tuple("RawEntry").field(o).finish(),
1297        }
1298    }
1299}
1300
1301impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for RawOccupiedEntryMut<'_, K, V> {
1302    #[cfg_attr(feature = "inline-more", inline)]
1303    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1304        f.debug_struct("RawOccupiedEntryMut")
1305            .field("key", self.key())
1306            .field("value", self.get())
1307            .finish()
1308    }
1309}
1310
1311impl<K, V, S> fmt::Debug for RawVacantEntryMut<'_, K, V, S> {
1312    #[cfg_attr(feature = "inline-more", inline)]
1313    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1314        f.debug_struct("RawVacantEntryMut").finish()
1315    }
1316}
1317
1318impl<K, V, S> fmt::Debug for RawEntryBuilder<'_, K, V, S> {
1319    #[cfg_attr(feature = "inline-more", inline)]
1320    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1321        f.debug_struct("RawEntryBuilder").finish()
1322    }
1323}
1324
1325unsafe impl<'a, K, V> Send for RawOccupiedEntryMut<'a, K, V>
1326where
1327    K: Send,
1328    V: Send,
1329{
1330}
1331
1332unsafe impl<'a, K, V> Sync for RawOccupiedEntryMut<'a, K, V>
1333where
1334    K: Sync,
1335    V: Sync,
1336{
1337}
1338
1339unsafe impl<'a, K, V, S> Send for RawVacantEntryMut<'a, K, V, S>
1340where
1341    K: Send,
1342    V: Send,
1343    S: Send,
1344{
1345}
1346
1347unsafe impl<'a, K, V, S> Sync for RawVacantEntryMut<'a, K, V, S>
1348where
1349    K: Sync,
1350    V: Sync,
1351    S: Sync,
1352{
1353}
1354
1355pub struct Iter<'a, K, V> {
1356    head: *const Node<K, V>,
1357    tail: *const Node<K, V>,
1358    remaining: usize,
1359    marker: PhantomData<(&'a K, &'a V)>,
1360}
1361
1362pub struct IterMut<'a, K, V> {
1363    head: Option<NonNull<Node<K, V>>>,
1364    tail: Option<NonNull<Node<K, V>>>,
1365    remaining: usize,
1366    marker: PhantomData<(&'a K, &'a mut V)>,
1367}
1368
1369pub struct IntoIter<K, V> {
1370    head: Option<NonNull<Node<K, V>>>,
1371    tail: Option<NonNull<Node<K, V>>>,
1372    remaining: usize,
1373    marker: PhantomData<(K, V)>,
1374}
1375
1376pub struct Drain<'a, K, V> {
1377    free: NonNull<Option<NonNull<Node<K, V>>>>,
1378    head: Option<NonNull<Node<K, V>>>,
1379    tail: Option<NonNull<Node<K, V>>>,
1380    remaining: usize,
1381    // We want `Drain` to be covariant
1382    marker: PhantomData<(K, V, &'a LinkedHashMap<K, V>)>,
1383}
1384
1385impl<K, V> IterMut<'_, K, V> {
1386    #[cfg_attr(feature = "inline-more", inline)]
1387    pub(crate) fn iter(&self) -> Iter<'_, K, V> {
1388        Iter {
1389            head: self.head.as_ptr(),
1390            tail: self.tail.as_ptr(),
1391            remaining: self.remaining,
1392            marker: PhantomData,
1393        }
1394    }
1395}
1396
1397impl<K, V> IntoIter<K, V> {
1398    #[cfg_attr(feature = "inline-more", inline)]
1399    pub(crate) fn iter(&self) -> Iter<'_, K, V> {
1400        Iter {
1401            head: self.head.as_ptr(),
1402            tail: self.tail.as_ptr(),
1403            remaining: self.remaining,
1404            marker: PhantomData,
1405        }
1406    }
1407}
1408
1409impl<K, V> Drain<'_, K, V> {
1410    #[cfg_attr(feature = "inline-more", inline)]
1411    pub(crate) fn iter(&self) -> Iter<'_, K, V> {
1412        Iter {
1413            head: self.head.as_ptr(),
1414            tail: self.tail.as_ptr(),
1415            remaining: self.remaining,
1416            marker: PhantomData,
1417        }
1418    }
1419}
1420
1421unsafe impl<'a, K, V> Send for Iter<'a, K, V>
1422where
1423    K: Send,
1424    V: Send,
1425{
1426}
1427
1428unsafe impl<'a, K, V> Send for IterMut<'a, K, V>
1429where
1430    K: Send,
1431    V: Send,
1432{
1433}
1434
1435unsafe impl<K, V> Send for IntoIter<K, V>
1436where
1437    K: Send,
1438    V: Send,
1439{
1440}
1441
1442unsafe impl<'a, K, V> Send for Drain<'a, K, V>
1443where
1444    K: Send,
1445    V: Send,
1446{
1447}
1448
1449unsafe impl<'a, K, V> Sync for Iter<'a, K, V>
1450where
1451    K: Sync,
1452    V: Sync,
1453{
1454}
1455
1456unsafe impl<'a, K, V> Sync for IterMut<'a, K, V>
1457where
1458    K: Sync,
1459    V: Sync,
1460{
1461}
1462
1463unsafe impl<K, V> Sync for IntoIter<K, V>
1464where
1465    K: Sync,
1466    V: Sync,
1467{
1468}
1469
1470unsafe impl<'a, K, V> Sync for Drain<'a, K, V>
1471where
1472    K: Sync,
1473    V: Sync,
1474{
1475}
1476
1477impl<'a, K, V> Clone for Iter<'a, K, V> {
1478    #[cfg_attr(feature = "inline-more", inline)]
1479    fn clone(&self) -> Self {
1480        Iter { ..*self }
1481    }
1482}
1483
1484impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Iter<'_, K, V> {
1485    #[cfg_attr(feature = "inline-more", inline)]
1486    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1487        f.debug_list().entries(self.clone()).finish()
1488    }
1489}
1490
1491impl<K, V> fmt::Debug for IterMut<'_, K, V>
1492where
1493    K: fmt::Debug,
1494    V: fmt::Debug,
1495{
1496    #[cfg_attr(feature = "inline-more", inline)]
1497    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1498        f.debug_list().entries(self.iter()).finish()
1499    }
1500}
1501
1502impl<K, V> fmt::Debug for IntoIter<K, V>
1503where
1504    K: fmt::Debug,
1505    V: fmt::Debug,
1506{
1507    #[cfg_attr(feature = "inline-more", inline)]
1508    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1509        f.debug_list().entries(self.iter()).finish()
1510    }
1511}
1512
1513impl<K, V> fmt::Debug for Drain<'_, K, V>
1514where
1515    K: fmt::Debug,
1516    V: fmt::Debug,
1517{
1518    #[cfg_attr(feature = "inline-more", inline)]
1519    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1520        f.debug_list().entries(self.iter()).finish()
1521    }
1522}
1523
1524impl<'a, K, V> Iterator for Iter<'a, K, V> {
1525    type Item = (&'a K, &'a V);
1526
1527    #[cfg_attr(feature = "inline-more", inline)]
1528    fn next(&mut self) -> Option<(&'a K, &'a V)> {
1529        if self.remaining == 0 {
1530            None
1531        } else {
1532            self.remaining -= 1;
1533            unsafe {
1534                let (key, value) = (*self.head).entry_ref();
1535                self.head = (*self.head).links.value.next.as_ptr();
1536                Some((key, value))
1537            }
1538        }
1539    }
1540
1541    #[cfg_attr(feature = "inline-more", inline)]
1542    fn size_hint(&self) -> (usize, Option<usize>) {
1543        (self.remaining, Some(self.remaining))
1544    }
1545}
1546
1547impl<'a, K, V> Iterator for IterMut<'a, K, V> {
1548    type Item = (&'a K, &'a mut V);
1549
1550    #[cfg_attr(feature = "inline-more", inline)]
1551    fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
1552        if self.remaining == 0 {
1553            None
1554        } else {
1555            self.remaining -= 1;
1556            unsafe {
1557                let head = self.head.as_ptr();
1558                let (key, value) = (*head).entry_mut();
1559                self.head = Some((*head).links.value.next);
1560                Some((key, value))
1561            }
1562        }
1563    }
1564
1565    #[cfg_attr(feature = "inline-more", inline)]
1566    fn size_hint(&self) -> (usize, Option<usize>) {
1567        (self.remaining, Some(self.remaining))
1568    }
1569}
1570
1571impl<K, V> Iterator for IntoIter<K, V> {
1572    type Item = (K, V);
1573
1574    #[cfg_attr(feature = "inline-more", inline)]
1575    fn next(&mut self) -> Option<(K, V)> {
1576        if self.remaining == 0 {
1577            return None;
1578        }
1579        self.remaining -= 1;
1580        unsafe {
1581            let head = self.head.as_ptr();
1582            self.head = Some((*head).links.value.next);
1583            let mut e = Box::from_raw(head);
1584            Some(e.take_entry())
1585        }
1586    }
1587
1588    #[cfg_attr(feature = "inline-more", inline)]
1589    fn size_hint(&self) -> (usize, Option<usize>) {
1590        (self.remaining, Some(self.remaining))
1591    }
1592}
1593
1594impl<'a, K, V> Iterator for Drain<'a, K, V> {
1595    type Item = (K, V);
1596
1597    #[cfg_attr(feature = "inline-more", inline)]
1598    fn next(&mut self) -> Option<(K, V)> {
1599        if self.remaining == 0 {
1600            return None;
1601        }
1602        self.remaining -= 1;
1603        unsafe {
1604            let mut head = NonNull::new_unchecked(self.head.as_ptr());
1605            self.head = Some(head.as_ref().links.value.next);
1606            let entry = head.as_mut().take_entry();
1607            push_free(self.free.as_mut(), head);
1608            Some(entry)
1609        }
1610    }
1611
1612    #[cfg_attr(feature = "inline-more", inline)]
1613    fn size_hint(&self) -> (usize, Option<usize>) {
1614        (self.remaining, Some(self.remaining))
1615    }
1616}
1617
1618impl<'a, K, V> DoubleEndedIterator for Iter<'a, K, V> {
1619    #[cfg_attr(feature = "inline-more", inline)]
1620    fn next_back(&mut self) -> Option<(&'a K, &'a V)> {
1621        if self.remaining == 0 {
1622            None
1623        } else {
1624            self.remaining -= 1;
1625            unsafe {
1626                let tail = self.tail;
1627                self.tail = (*tail).links.value.prev.as_ptr();
1628                let (key, value) = (*tail).entry_ref();
1629                Some((key, value))
1630            }
1631        }
1632    }
1633}
1634
1635impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> {
1636    #[cfg_attr(feature = "inline-more", inline)]
1637    fn next_back(&mut self) -> Option<(&'a K, &'a mut V)> {
1638        if self.remaining == 0 {
1639            None
1640        } else {
1641            self.remaining -= 1;
1642            unsafe {
1643                let tail = self.tail.as_ptr();
1644                self.tail = Some((*tail).links.value.prev);
1645                let (key, value) = (*tail).entry_mut();
1646                Some((key, value))
1647            }
1648        }
1649    }
1650}
1651
1652impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
1653    #[cfg_attr(feature = "inline-more", inline)]
1654    fn next_back(&mut self) -> Option<(K, V)> {
1655        if self.remaining == 0 {
1656            return None;
1657        }
1658        self.remaining -= 1;
1659        unsafe {
1660            let mut e = *Box::from_raw(self.tail.as_ptr());
1661            self.tail = Some(e.links.value.prev);
1662            Some(e.take_entry())
1663        }
1664    }
1665}
1666
1667impl<'a, K, V> DoubleEndedIterator for Drain<'a, K, V> {
1668    #[cfg_attr(feature = "inline-more", inline)]
1669    fn next_back(&mut self) -> Option<(K, V)> {
1670        if self.remaining == 0 {
1671            return None;
1672        }
1673        self.remaining -= 1;
1674        unsafe {
1675            let mut tail = NonNull::new_unchecked(self.tail.as_ptr());
1676            self.tail = Some(tail.as_ref().links.value.prev);
1677            let entry = tail.as_mut().take_entry();
1678            push_free(&mut *self.free.as_ptr(), tail);
1679            Some(entry)
1680        }
1681    }
1682}
1683
1684impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
1685
1686impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
1687
1688impl<K, V> ExactSizeIterator for IntoIter<K, V> {}
1689
1690impl<K, V> Drop for IntoIter<K, V> {
1691    #[cfg_attr(feature = "inline-more", inline)]
1692    fn drop(&mut self) {
1693        for _ in 0..self.remaining {
1694            unsafe {
1695                let tail = self.tail.as_ptr();
1696                self.tail = Some((*tail).links.value.prev);
1697                (*tail).take_entry();
1698                Box::from_raw(tail);
1699            }
1700        }
1701    }
1702}
1703
1704impl<'a, K, V> Drop for Drain<'a, K, V> {
1705    #[cfg_attr(feature = "inline-more", inline)]
1706    fn drop(&mut self) {
1707        for _ in 0..self.remaining {
1708            unsafe {
1709                let mut tail = NonNull::new_unchecked(self.tail.as_ptr());
1710                self.tail = Some(tail.as_ref().links.value.prev);
1711                tail.as_mut().take_entry();
1712                push_free(&mut *self.free.as_ptr(), tail);
1713            }
1714        }
1715    }
1716}
1717
1718pub struct Keys<'a, K, V> {
1719    inner: Iter<'a, K, V>,
1720}
1721
1722impl<K: fmt::Debug, V> fmt::Debug for Keys<'_, K, V> {
1723    #[cfg_attr(feature = "inline-more", inline)]
1724    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1725        f.debug_list().entries(self.clone()).finish()
1726    }
1727}
1728
1729impl<'a, K, V> Clone for Keys<'a, K, V> {
1730    #[cfg_attr(feature = "inline-more", inline)]
1731    fn clone(&self) -> Keys<'a, K, V> {
1732        Keys {
1733            inner: self.inner.clone(),
1734        }
1735    }
1736}
1737
1738impl<'a, K, V> Iterator for Keys<'a, K, V> {
1739    type Item = &'a K;
1740
1741    #[cfg_attr(feature = "inline-more", inline)]
1742    fn next(&mut self) -> Option<&'a K> {
1743        self.inner.next().map(|e| e.0)
1744    }
1745
1746    #[cfg_attr(feature = "inline-more", inline)]
1747    fn size_hint(&self) -> (usize, Option<usize>) {
1748        self.inner.size_hint()
1749    }
1750}
1751
1752impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
1753    #[cfg_attr(feature = "inline-more", inline)]
1754    fn next_back(&mut self) -> Option<&'a K> {
1755        self.inner.next_back().map(|e| e.0)
1756    }
1757}
1758
1759impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
1760    #[cfg_attr(feature = "inline-more", inline)]
1761    fn len(&self) -> usize {
1762        self.inner.len()
1763    }
1764}
1765
1766pub struct Values<'a, K, V> {
1767    inner: Iter<'a, K, V>,
1768}
1769
1770impl<K, V> Clone for Values<'_, K, V> {
1771    #[cfg_attr(feature = "inline-more", inline)]
1772    fn clone(&self) -> Self {
1773        Values {
1774            inner: self.inner.clone(),
1775        }
1776    }
1777}
1778
1779impl<K, V: fmt::Debug> fmt::Debug for Values<'_, K, V> {
1780    #[cfg_attr(feature = "inline-more", inline)]
1781    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1782        f.debug_list().entries(self.clone()).finish()
1783    }
1784}
1785
1786impl<'a, K, V> Iterator for Values<'a, K, V> {
1787    type Item = &'a V;
1788
1789    #[cfg_attr(feature = "inline-more", inline)]
1790    fn next(&mut self) -> Option<&'a V> {
1791        self.inner.next().map(|e| e.1)
1792    }
1793
1794    #[cfg_attr(feature = "inline-more", inline)]
1795    fn size_hint(&self) -> (usize, Option<usize>) {
1796        self.inner.size_hint()
1797    }
1798}
1799
1800impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
1801    #[cfg_attr(feature = "inline-more", inline)]
1802    fn next_back(&mut self) -> Option<&'a V> {
1803        self.inner.next_back().map(|e| e.1)
1804    }
1805}
1806
1807impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
1808    #[cfg_attr(feature = "inline-more", inline)]
1809    fn len(&self) -> usize {
1810        self.inner.len()
1811    }
1812}
1813
1814pub struct ValuesMut<'a, K, V> {
1815    inner: IterMut<'a, K, V>,
1816}
1817
1818impl<K, V> fmt::Debug for ValuesMut<'_, K, V>
1819where
1820    K: fmt::Debug,
1821    V: fmt::Debug,
1822{
1823    #[cfg_attr(feature = "inline-more", inline)]
1824    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1825        f.debug_list().entries(self.inner.iter()).finish()
1826    }
1827}
1828
1829impl<'a, K, V> Iterator for ValuesMut<'a, K, V> {
1830    type Item = &'a mut V;
1831
1832    #[cfg_attr(feature = "inline-more", inline)]
1833    fn next(&mut self) -> Option<&'a mut V> {
1834        self.inner.next().map(|e| e.1)
1835    }
1836
1837    #[cfg_attr(feature = "inline-more", inline)]
1838    fn size_hint(&self) -> (usize, Option<usize>) {
1839        self.inner.size_hint()
1840    }
1841}
1842
1843impl<'a, K, V> DoubleEndedIterator for ValuesMut<'a, K, V> {
1844    #[cfg_attr(feature = "inline-more", inline)]
1845    fn next_back(&mut self) -> Option<&'a mut V> {
1846        self.inner.next_back().map(|e| e.1)
1847    }
1848}
1849
1850impl<'a, K, V> ExactSizeIterator for ValuesMut<'a, K, V> {
1851    #[cfg_attr(feature = "inline-more", inline)]
1852    fn len(&self) -> usize {
1853        self.inner.len()
1854    }
1855}
1856
1857impl<'a, K, V, S> IntoIterator for &'a LinkedHashMap<K, V, S> {
1858    type Item = (&'a K, &'a V);
1859    type IntoIter = Iter<'a, K, V>;
1860
1861    #[cfg_attr(feature = "inline-more", inline)]
1862    fn into_iter(self) -> Iter<'a, K, V> {
1863        self.iter()
1864    }
1865}
1866
1867impl<'a, K, V, S> IntoIterator for &'a mut LinkedHashMap<K, V, S> {
1868    type Item = (&'a K, &'a mut V);
1869    type IntoIter = IterMut<'a, K, V>;
1870
1871    #[cfg_attr(feature = "inline-more", inline)]
1872    fn into_iter(self) -> IterMut<'a, K, V> {
1873        self.iter_mut()
1874    }
1875}
1876
1877impl<K, V, S> IntoIterator for LinkedHashMap<K, V, S> {
1878    type Item = (K, V);
1879    type IntoIter = IntoIter<K, V>;
1880
1881    #[cfg_attr(feature = "inline-more", inline)]
1882    fn into_iter(mut self) -> IntoIter<K, V> {
1883        unsafe {
1884            let (head, tail) = if let Some(values) = self.values {
1885                let ValueLinks {
1886                    next: head,
1887                    prev: tail,
1888                } = values.as_ref().links.value;
1889
1890                Box::from_raw(self.values.as_ptr());
1891                self.values = None;
1892
1893                (Some(head), Some(tail))
1894            } else {
1895                (None, None)
1896            };
1897            let len = self.len();
1898
1899            drop_free_nodes(self.free);
1900            self.free = None;
1901
1902            self.map.clear();
1903
1904            IntoIter {
1905                head,
1906                tail,
1907                remaining: len,
1908                marker: PhantomData,
1909            }
1910        }
1911    }
1912}
1913
1914// A ZST that asserts that the inner HashMap will not do its own key hashing
1915struct NullHasher;
1916
1917impl BuildHasher for NullHasher {
1918    type Hasher = Self;
1919
1920    #[cfg_attr(feature = "inline-more", inline)]
1921    fn build_hasher(&self) -> Self {
1922        Self
1923    }
1924}
1925
1926impl Hasher for NullHasher {
1927    #[cfg_attr(feature = "inline-more", inline)]
1928    fn write(&mut self, _bytes: &[u8]) {
1929        unreachable!("inner map should not be using its built-in hasher")
1930    }
1931
1932    #[cfg_attr(feature = "inline-more", inline)]
1933    fn finish(&self) -> u64 {
1934        unreachable!("inner map should not be using its built-in hasher")
1935    }
1936}
1937
1938struct ValueLinks<K, V> {
1939    next: NonNull<Node<K, V>>,
1940    prev: NonNull<Node<K, V>>,
1941}
1942
1943impl<K, V> Clone for ValueLinks<K, V> {
1944    #[cfg_attr(feature = "inline-more", inline)]
1945    fn clone(&self) -> Self {
1946        ValueLinks {
1947            next: self.next,
1948            prev: self.prev,
1949        }
1950    }
1951}
1952
1953impl<K, V> Copy for ValueLinks<K, V> {}
1954
1955struct FreeLink<K, V> {
1956    next: Option<NonNull<Node<K, V>>>,
1957}
1958
1959impl<K, V> Clone for FreeLink<K, V> {
1960    #[cfg_attr(feature = "inline-more", inline)]
1961    fn clone(&self) -> Self {
1962        FreeLink { next: self.next }
1963    }
1964}
1965
1966impl<K, V> Copy for FreeLink<K, V> {}
1967
1968union Links<K, V> {
1969    value: ValueLinks<K, V>,
1970    free: FreeLink<K, V>,
1971}
1972
1973struct Node<K, V> {
1974    entry: MaybeUninit<(K, V)>,
1975    links: Links<K, V>,
1976}
1977
1978impl<K, V> Node<K, V> {
1979    #[cfg_attr(feature = "inline-more", inline)]
1980    unsafe fn put_entry(&mut self, entry: (K, V)) {
1981        self.entry.as_mut_ptr().write(entry)
1982    }
1983
1984    #[cfg_attr(feature = "inline-more", inline)]
1985    unsafe fn entry_ref(&self) -> &(K, V) {
1986        &*self.entry.as_ptr()
1987    }
1988
1989    #[cfg_attr(feature = "inline-more", inline)]
1990    unsafe fn key_ref(&self) -> &K {
1991        &(*self.entry.as_ptr()).0
1992    }
1993
1994    #[cfg_attr(feature = "inline-more", inline)]
1995    unsafe fn entry_mut(&mut self) -> &mut (K, V) {
1996        &mut *self.entry.as_mut_ptr()
1997    }
1998
1999    #[cfg_attr(feature = "inline-more", inline)]
2000    unsafe fn take_entry(&mut self) -> (K, V) {
2001        self.entry.as_ptr().read()
2002    }
2003}
2004
2005trait OptNonNullExt<T> {
2006    #[allow(clippy::wrong_self_convention)]
2007    fn as_ptr(self) -> *mut T;
2008}
2009
2010impl<T> OptNonNullExt<T> for Option<NonNull<T>> {
2011    #[cfg_attr(feature = "inline-more", inline)]
2012    fn as_ptr(self) -> *mut T {
2013        match self {
2014            Some(ptr) => ptr.as_ptr(),
2015            None => ptr::null_mut(),
2016        }
2017    }
2018}
2019
2020// Allocate a circular list guard node if not present.
2021#[cfg_attr(feature = "inline-more", inline)]
2022unsafe fn ensure_guard_node<K, V>(head: &mut Option<NonNull<Node<K, V>>>) {
2023    if head.is_none() {
2024        let mut p = NonNull::new_unchecked(Box::into_raw(Box::new(Node {
2025            entry: MaybeUninit::uninit(),
2026            links: Links {
2027                value: ValueLinks {
2028                    next: NonNull::dangling(),
2029                    prev: NonNull::dangling(),
2030                },
2031            },
2032        })));
2033        p.as_mut().links.value = ValueLinks { next: p, prev: p };
2034        *head = Some(p);
2035    }
2036}
2037
2038// Attach the `to_attach` node to the existing circular list *before* `node`.
2039#[cfg_attr(feature = "inline-more", inline)]
2040unsafe fn attach_before<K, V>(mut to_attach: NonNull<Node<K, V>>, mut node: NonNull<Node<K, V>>) {
2041    to_attach.as_mut().links.value = ValueLinks {
2042        prev: node.as_ref().links.value.prev,
2043        next: node,
2044    };
2045    node.as_mut().links.value.prev = to_attach;
2046    (*to_attach.as_mut().links.value.prev.as_ptr())
2047        .links
2048        .value
2049        .next = to_attach;
2050}
2051
2052#[cfg_attr(feature = "inline-more", inline)]
2053unsafe fn detach_node<K, V>(mut node: NonNull<Node<K, V>>) {
2054    node.as_mut().links.value.prev.as_mut().links.value.next = node.as_ref().links.value.next;
2055    node.as_mut().links.value.next.as_mut().links.value.prev = node.as_ref().links.value.prev;
2056}
2057
2058#[cfg_attr(feature = "inline-more", inline)]
2059unsafe fn push_free<K, V>(
2060    free_list: &mut Option<NonNull<Node<K, V>>>,
2061    mut node: NonNull<Node<K, V>>,
2062) {
2063    node.as_mut().links.free.next = *free_list;
2064    *free_list = Some(node);
2065}
2066
2067#[cfg_attr(feature = "inline-more", inline)]
2068unsafe fn pop_free<K, V>(
2069    free_list: &mut Option<NonNull<Node<K, V>>>,
2070) -> Option<NonNull<Node<K, V>>> {
2071    if let Some(free) = *free_list {
2072        *free_list = free.as_ref().links.free.next;
2073        Some(free)
2074    } else {
2075        None
2076    }
2077}
2078
2079#[cfg_attr(feature = "inline-more", inline)]
2080unsafe fn allocate_node<K, V>(free_list: &mut Option<NonNull<Node<K, V>>>) -> NonNull<Node<K, V>> {
2081    if let Some(mut free) = pop_free(free_list) {
2082        free.as_mut().links.value = ValueLinks {
2083            next: NonNull::dangling(),
2084            prev: NonNull::dangling(),
2085        };
2086        free
2087    } else {
2088        NonNull::new_unchecked(Box::into_raw(Box::new(Node {
2089            entry: MaybeUninit::uninit(),
2090            links: Links {
2091                value: ValueLinks {
2092                    next: NonNull::dangling(),
2093                    prev: NonNull::dangling(),
2094                },
2095            },
2096        })))
2097    }
2098}
2099
2100// Given node is assumed to be the guard node and is *not* dropped.
2101#[cfg_attr(feature = "inline-more", inline)]
2102unsafe fn drop_value_nodes<K, V>(guard: NonNull<Node<K, V>>) {
2103    let mut cur = guard.as_ref().links.value.prev;
2104    while cur != guard {
2105        let prev = cur.as_ref().links.value.prev;
2106        cur.as_mut().take_entry();
2107        Box::from_raw(cur.as_ptr());
2108        cur = prev;
2109    }
2110}
2111
2112// Drops all linked free nodes starting with the given node.  Free nodes are only non-circular
2113// singly linked, and should have uninitialized keys / values.
2114#[cfg_attr(feature = "inline-more", inline)]
2115unsafe fn drop_free_nodes<K, V>(mut free: Option<NonNull<Node<K, V>>>) {
2116    while let Some(some_free) = free {
2117        let next_free = some_free.as_ref().links.free.next;
2118        Box::from_raw(some_free.as_ptr());
2119        free = next_free;
2120    }
2121}
2122
2123#[cfg_attr(feature = "inline-more", inline)]
2124unsafe fn remove_node<K, V>(
2125    free_list: &mut Option<NonNull<Node<K, V>>>,
2126    mut node: NonNull<Node<K, V>>,
2127) -> (K, V) {
2128    detach_node(node);
2129    push_free(free_list, node);
2130    node.as_mut().take_entry()
2131}
2132
2133#[cfg_attr(feature = "inline-more", inline)]
2134fn hash_key<S, Q>(s: &S, k: &Q) -> u64
2135where
2136    S: BuildHasher,
2137    Q: Hash + ?Sized,
2138{
2139    let mut hasher = s.build_hasher();
2140    k.hash(&mut hasher);
2141    hasher.finish()
2142}