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
23pub struct LinkedHashMap<K, V, S = DefaultHashBuilder> {
39 map: HashMap<NonNull<Node<K, V>>, (), NullHasher>,
40 hash_builder: S,
43 values: Option<NonNull<Node<K, V>>>,
47 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 #[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 #[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 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 #[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 #[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 #[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 #[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 #[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 #[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 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 #[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 #[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 #[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 #[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 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
1914struct 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#[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#[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#[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#[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}