indexmap/map/core/
entry.rs

1use super::{equivalent, Entries, IndexMapCore, RefMut};
2use crate::HashValue;
3use core::cmp::Ordering;
4use core::{fmt, mem};
5use hashbrown::hash_table;
6
7impl<K, V> IndexMapCore<K, V> {
8    pub(crate) fn entry(&mut self, hash: HashValue, key: K) -> Entry<'_, K, V>
9    where
10        K: Eq,
11    {
12        let entries = &mut self.entries;
13        let eq = equivalent(&key, entries);
14        match self.indices.find_entry(hash.get(), eq) {
15            Ok(index) => Entry::Occupied(OccupiedEntry { entries, index }),
16            Err(absent) => Entry::Vacant(VacantEntry {
17                map: RefMut::new(absent.into_table(), entries),
18                hash,
19                key,
20            }),
21        }
22    }
23}
24
25/// Entry for an existing key-value pair in an [`IndexMap`][crate::IndexMap]
26/// or a vacant location to insert one.
27pub enum Entry<'a, K, V> {
28    /// Existing slot with equivalent key.
29    Occupied(OccupiedEntry<'a, K, V>),
30    /// Vacant slot (no equivalent key in the map).
31    Vacant(VacantEntry<'a, K, V>),
32}
33
34impl<'a, K, V> Entry<'a, K, V> {
35    /// Return the index where the key-value pair exists or will be inserted.
36    pub fn index(&self) -> usize {
37        match *self {
38            Entry::Occupied(ref entry) => entry.index(),
39            Entry::Vacant(ref entry) => entry.index(),
40        }
41    }
42
43    /// Sets the value of the entry (after inserting if vacant), and returns an `OccupiedEntry`.
44    ///
45    /// Computes in **O(1)** time (amortized average).
46    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
47        match self {
48            Entry::Occupied(mut entry) => {
49                entry.insert(value);
50                entry
51            }
52            Entry::Vacant(entry) => entry.insert_entry(value),
53        }
54    }
55
56    /// Inserts the given default value in the entry if it is vacant and returns a mutable
57    /// reference to it. Otherwise a mutable reference to an already existent value is returned.
58    ///
59    /// Computes in **O(1)** time (amortized average).
60    pub fn or_insert(self, default: V) -> &'a mut V {
61        match self {
62            Entry::Occupied(entry) => entry.into_mut(),
63            Entry::Vacant(entry) => entry.insert(default),
64        }
65    }
66
67    /// Inserts the result of the `call` function in the entry if it is vacant and returns a mutable
68    /// reference to it. Otherwise a mutable reference to an already existent value is returned.
69    ///
70    /// Computes in **O(1)** time (amortized average).
71    pub fn or_insert_with<F>(self, call: F) -> &'a mut V
72    where
73        F: FnOnce() -> V,
74    {
75        match self {
76            Entry::Occupied(entry) => entry.into_mut(),
77            Entry::Vacant(entry) => entry.insert(call()),
78        }
79    }
80
81    /// Inserts the result of the `call` function with a reference to the entry's key if it is
82    /// vacant, and returns a mutable reference to the new value. Otherwise a mutable reference to
83    /// an already existent value is returned.
84    ///
85    /// Computes in **O(1)** time (amortized average).
86    pub fn or_insert_with_key<F>(self, call: F) -> &'a mut V
87    where
88        F: FnOnce(&K) -> V,
89    {
90        match self {
91            Entry::Occupied(entry) => entry.into_mut(),
92            Entry::Vacant(entry) => {
93                let value = call(&entry.key);
94                entry.insert(value)
95            }
96        }
97    }
98
99    /// Gets a reference to the entry's key, either within the map if occupied,
100    /// or else the new key that was used to find the entry.
101    pub fn key(&self) -> &K {
102        match *self {
103            Entry::Occupied(ref entry) => entry.key(),
104            Entry::Vacant(ref entry) => entry.key(),
105        }
106    }
107
108    /// Modifies the entry if it is occupied.
109    pub fn and_modify<F>(mut self, f: F) -> Self
110    where
111        F: FnOnce(&mut V),
112    {
113        if let Entry::Occupied(entry) = &mut self {
114            f(entry.get_mut());
115        }
116        self
117    }
118
119    /// Inserts a default-constructed value in the entry if it is vacant and returns a mutable
120    /// reference to it. Otherwise a mutable reference to an already existent value is returned.
121    ///
122    /// Computes in **O(1)** time (amortized average).
123    pub fn or_default(self) -> &'a mut V
124    where
125        V: Default,
126    {
127        match self {
128            Entry::Occupied(entry) => entry.into_mut(),
129            Entry::Vacant(entry) => entry.insert(V::default()),
130        }
131    }
132}
133
134impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for Entry<'_, K, V> {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        let mut tuple = f.debug_tuple("Entry");
137        match self {
138            Entry::Vacant(v) => tuple.field(v),
139            Entry::Occupied(o) => tuple.field(o),
140        };
141        tuple.finish()
142    }
143}
144
145/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap].
146/// It is part of the [`Entry`] enum.
147pub struct OccupiedEntry<'a, K, V> {
148    entries: &'a mut Entries<K, V>,
149    index: hash_table::OccupiedEntry<'a, usize>,
150}
151
152impl<'a, K, V> OccupiedEntry<'a, K, V> {
153    pub(crate) fn new(
154        entries: &'a mut Entries<K, V>,
155        index: hash_table::OccupiedEntry<'a, usize>,
156    ) -> Self {
157        Self { entries, index }
158    }
159
160    /// Return the index of the key-value pair
161    #[inline]
162    pub fn index(&self) -> usize {
163        *self.index.get()
164    }
165
166    #[inline]
167    fn into_ref_mut(self) -> RefMut<'a, K, V> {
168        RefMut::new(self.index.into_table(), self.entries)
169    }
170
171    /// Gets a reference to the entry's key in the map.
172    ///
173    /// Note that this is not the key that was used to find the entry. There may be an observable
174    /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
175    /// extra fields or the memory address of an allocation.
176    pub fn key(&self) -> &K {
177        &self.entries[self.index()].key
178    }
179
180    pub(crate) fn key_mut(&mut self) -> &mut K {
181        let index = self.index();
182        &mut self.entries[index].key
183    }
184
185    /// Gets a reference to the entry's value in the map.
186    pub fn get(&self) -> &V {
187        &self.entries[self.index()].value
188    }
189
190    /// Gets a mutable reference to the entry's value in the map.
191    ///
192    /// If you need a reference which may outlive the destruction of the
193    /// [`Entry`] value, see [`into_mut`][Self::into_mut].
194    pub fn get_mut(&mut self) -> &mut V {
195        let index = self.index();
196        &mut self.entries[index].value
197    }
198
199    /// Converts into a mutable reference to the entry's value in the map,
200    /// with a lifetime bound to the map itself.
201    pub fn into_mut(self) -> &'a mut V {
202        let index = self.index();
203        &mut self.entries[index].value
204    }
205
206    pub(super) fn into_muts(self) -> (&'a mut K, &'a mut V) {
207        let index = self.index();
208        self.entries[index].muts()
209    }
210
211    /// Sets the value of the entry to `value`, and returns the entry's old value.
212    pub fn insert(&mut self, value: V) -> V {
213        mem::replace(self.get_mut(), value)
214    }
215
216    /// Remove the key, value pair stored in the map for this entry, and return the value.
217    ///
218    /// **NOTE:** This is equivalent to [`.swap_remove()`][Self::swap_remove], replacing this
219    /// entry's position with the last element, and it is deprecated in favor of calling that
220    /// explicitly. If you need to preserve the relative order of the keys in the map, use
221    /// [`.shift_remove()`][Self::shift_remove] instead.
222    #[deprecated(note = "`remove` disrupts the map order -- \
223        use `swap_remove` or `shift_remove` for explicit behavior.")]
224    pub fn remove(self) -> V {
225        self.swap_remove()
226    }
227
228    /// Remove the key, value pair stored in the map for this entry, and return the value.
229    ///
230    /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
231    /// the last element of the map and popping it off.
232    /// **This perturbs the position of what used to be the last element!**
233    ///
234    /// Computes in **O(1)** time (average).
235    pub fn swap_remove(self) -> V {
236        self.swap_remove_entry().1
237    }
238
239    /// Remove the key, value pair stored in the map for this entry, and return the value.
240    ///
241    /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
242    /// elements that follow it, preserving their relative order.
243    /// **This perturbs the index of all of those elements!**
244    ///
245    /// Computes in **O(n)** time (average).
246    pub fn shift_remove(self) -> V {
247        self.shift_remove_entry().1
248    }
249
250    /// Remove and return the key, value pair stored in the map for this entry
251    ///
252    /// **NOTE:** This is equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry],
253    /// replacing this entry's position with the last element, and it is deprecated in favor of
254    /// calling that explicitly. If you need to preserve the relative order of the keys in the map,
255    /// use [`.shift_remove_entry()`][Self::shift_remove_entry] instead.
256    #[deprecated(note = "`remove_entry` disrupts the map order -- \
257        use `swap_remove_entry` or `shift_remove_entry` for explicit behavior.")]
258    pub fn remove_entry(self) -> (K, V) {
259        self.swap_remove_entry()
260    }
261
262    /// Remove and return the key, value pair stored in the map for this entry
263    ///
264    /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
265    /// the last element of the map and popping it off.
266    /// **This perturbs the position of what used to be the last element!**
267    ///
268    /// Computes in **O(1)** time (average).
269    pub fn swap_remove_entry(self) -> (K, V) {
270        let (index, entry) = self.index.remove();
271        RefMut::new(entry.into_table(), self.entries).swap_remove_finish(index)
272    }
273
274    /// Remove and return the key, value pair stored in the map for this entry
275    ///
276    /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
277    /// elements that follow it, preserving their relative order.
278    /// **This perturbs the index of all of those elements!**
279    ///
280    /// Computes in **O(n)** time (average).
281    pub fn shift_remove_entry(self) -> (K, V) {
282        let (index, entry) = self.index.remove();
283        RefMut::new(entry.into_table(), self.entries).shift_remove_finish(index)
284    }
285
286    /// Moves the position of the entry to a new index
287    /// by shifting all other entries in-between.
288    ///
289    /// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
290    /// coming `from` the current [`.index()`][Self::index].
291    ///
292    /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
293    /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
294    ///
295    /// ***Panics*** if `to` is out of bounds.
296    ///
297    /// Computes in **O(n)** time (average).
298    #[track_caller]
299    pub fn move_index(self, to: usize) {
300        let index = self.index();
301        self.into_ref_mut().move_index(index, to);
302    }
303
304    /// Swaps the position of entry with another.
305    ///
306    /// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
307    /// with the current [`.index()`][Self::index] as one of the two being swapped.
308    ///
309    /// ***Panics*** if the `other` index is out of bounds.
310    ///
311    /// Computes in **O(1)** time (average).
312    #[track_caller]
313    pub fn swap_indices(self, other: usize) {
314        let index = self.index();
315        self.into_ref_mut().swap_indices(index, other);
316    }
317}
318
319impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for OccupiedEntry<'_, K, V> {
320    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
321        f.debug_struct("OccupiedEntry")
322            .field("key", self.key())
323            .field("value", self.get())
324            .finish()
325    }
326}
327
328impl<'a, K, V> From<IndexedEntry<'a, K, V>> for OccupiedEntry<'a, K, V> {
329    fn from(other: IndexedEntry<'a, K, V>) -> Self {
330        let IndexedEntry {
331            map: RefMut { indices, entries },
332            index,
333        } = other;
334        let hash = entries[index].hash;
335        Self {
336            entries,
337            index: indices
338                .find_entry(hash.get(), move |&i| i == index)
339                .expect("index not found"),
340        }
341    }
342}
343
344/// A view into a vacant entry in an [`IndexMap`][crate::IndexMap].
345/// It is part of the [`Entry`] enum.
346pub struct VacantEntry<'a, K, V> {
347    map: RefMut<'a, K, V>,
348    hash: HashValue,
349    key: K,
350}
351
352impl<'a, K, V> VacantEntry<'a, K, V> {
353    /// Return the index where a key-value pair may be inserted.
354    pub fn index(&self) -> usize {
355        self.map.indices.len()
356    }
357
358    /// Gets a reference to the key that was used to find the entry.
359    pub fn key(&self) -> &K {
360        &self.key
361    }
362
363    pub(crate) fn key_mut(&mut self) -> &mut K {
364        &mut self.key
365    }
366
367    /// Takes ownership of the key, leaving the entry vacant.
368    pub fn into_key(self) -> K {
369        self.key
370    }
371
372    /// Inserts the entry's key and the given value into the map, and returns a mutable reference
373    /// to the value.
374    ///
375    /// Computes in **O(1)** time (amortized average).
376    pub fn insert(self, value: V) -> &'a mut V {
377        self.insert_entry(value).into_mut()
378    }
379
380    /// Inserts the entry's key and the given value into the map, and returns an `OccupiedEntry`.
381    ///
382    /// Computes in **O(1)** time (amortized average).
383    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
384        let Self { map, hash, key } = self;
385        map.insert_unique(hash, key, value)
386    }
387
388    /// Inserts the entry's key and the given value into the map at its ordered
389    /// position among sorted keys, and returns the new index and a mutable
390    /// reference to the value.
391    ///
392    /// If the existing keys are **not** already sorted, then the insertion
393    /// index is unspecified (like [`slice::binary_search`]), but the key-value
394    /// pair is inserted at that position regardless.
395    ///
396    /// Computes in **O(n)** time (average).
397    pub fn insert_sorted(self, value: V) -> (usize, &'a mut V)
398    where
399        K: Ord,
400    {
401        let slice = crate::map::Slice::from_slice(self.map.entries);
402        let i = slice.binary_search_keys(&self.key).unwrap_err();
403        (i, self.shift_insert(i, value))
404    }
405
406    /// Inserts the entry's key and the given value into the map at its ordered
407    /// position among keys sorted by `cmp`, and returns the new index and a
408    /// mutable reference to the value.
409    ///
410    /// If the existing keys are **not** already sorted, then the insertion
411    /// index is unspecified (like [`slice::binary_search`]), but the key-value
412    /// pair is inserted at that position regardless.
413    ///
414    /// Computes in **O(n)** time (average).
415    pub fn insert_sorted_by<F>(self, value: V, mut cmp: F) -> (usize, &'a mut V)
416    where
417        K: Ord,
418        F: FnMut(&K, &V, &K, &V) -> Ordering,
419    {
420        let slice = crate::map::Slice::from_slice(self.map.entries);
421        let (Ok(i) | Err(i)) = slice.binary_search_by(|k, v| cmp(k, v, &self.key, &value));
422        (i, self.shift_insert(i, value))
423    }
424
425    /// Inserts the entry's key and the given value into the map at its ordered
426    /// position using a sort-key extraction function, and returns the new index
427    /// and a mutable reference to the value.
428    ///
429    /// If the existing keys are **not** already sorted, then the insertion
430    /// index is unspecified (like [`slice::binary_search`]), but the key-value
431    /// pair is inserted at that position regardless.
432    ///
433    /// Computes in **O(n)** time (average).
434    pub fn insert_sorted_by_key<B, F>(self, value: V, mut sort_key: F) -> (usize, &'a mut V)
435    where
436        B: Ord,
437        F: FnMut(&K, &V) -> B,
438    {
439        let search_key = sort_key(&self.key, &value);
440        let slice = crate::map::Slice::from_slice(self.map.entries);
441        let (Ok(i) | Err(i)) = slice.binary_search_by_key(&search_key, sort_key);
442        (i, self.shift_insert(i, value))
443    }
444
445    /// Inserts the entry's key and the given value into the map at the given index,
446    /// shifting others to the right, and returns a mutable reference to the value.
447    ///
448    /// ***Panics*** if `index` is out of bounds.
449    ///
450    /// Computes in **O(n)** time (average).
451    #[track_caller]
452    pub fn shift_insert(mut self, index: usize, value: V) -> &'a mut V {
453        self.map
454            .shift_insert_unique(index, self.hash, self.key, value);
455        &mut self.map.entries[index].value
456    }
457
458    /// Replaces the key at the given index with this entry's key, returning the
459    /// old key and an `OccupiedEntry` for that index.
460    ///
461    /// ***Panics*** if `index` is out of bounds.
462    ///
463    /// Computes in **O(1)** time (average).
464    #[track_caller]
465    pub fn replace_index(self, index: usize) -> (K, OccupiedEntry<'a, K, V>) {
466        self.map.replace_index_unique(index, self.hash, self.key)
467    }
468}
469
470impl<K: fmt::Debug, V> fmt::Debug for VacantEntry<'_, K, V> {
471    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
472        f.debug_tuple("VacantEntry").field(self.key()).finish()
473    }
474}
475
476/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap] obtained by index.
477///
478/// This `struct` is created from the [`get_index_entry`][crate::IndexMap::get_index_entry] method.
479pub struct IndexedEntry<'a, K, V> {
480    map: RefMut<'a, K, V>,
481    // We have a mutable reference to the map, which keeps the index
482    // valid and pointing to the correct entry.
483    index: usize,
484}
485
486impl<'a, K, V> IndexedEntry<'a, K, V> {
487    pub(crate) fn new(map: &'a mut IndexMapCore<K, V>, index: usize) -> Self {
488        Self {
489            map: map.borrow_mut(),
490            index,
491        }
492    }
493
494    /// Return the index of the key-value pair
495    #[inline]
496    pub fn index(&self) -> usize {
497        self.index
498    }
499
500    /// Gets a reference to the entry's key in the map.
501    pub fn key(&self) -> &K {
502        &self.map.entries[self.index].key
503    }
504
505    pub(crate) fn key_mut(&mut self) -> &mut K {
506        &mut self.map.entries[self.index].key
507    }
508
509    /// Gets a reference to the entry's value in the map.
510    pub fn get(&self) -> &V {
511        &self.map.entries[self.index].value
512    }
513
514    /// Gets a mutable reference to the entry's value in the map.
515    ///
516    /// If you need a reference which may outlive the destruction of the
517    /// `IndexedEntry` value, see [`into_mut`][Self::into_mut].
518    pub fn get_mut(&mut self) -> &mut V {
519        &mut self.map.entries[self.index].value
520    }
521
522    /// Sets the value of the entry to `value`, and returns the entry's old value.
523    pub fn insert(&mut self, value: V) -> V {
524        mem::replace(self.get_mut(), value)
525    }
526
527    /// Converts into a mutable reference to the entry's value in the map,
528    /// with a lifetime bound to the map itself.
529    pub fn into_mut(self) -> &'a mut V {
530        &mut self.map.entries[self.index].value
531    }
532
533    /// Remove and return the key, value pair stored in the map for this entry
534    ///
535    /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
536    /// the last element of the map and popping it off.
537    /// **This perturbs the position of what used to be the last element!**
538    ///
539    /// Computes in **O(1)** time (average).
540    pub fn swap_remove_entry(mut self) -> (K, V) {
541        self.map.swap_remove_index(self.index).unwrap()
542    }
543
544    /// Remove and return the key, value pair stored in the map for this entry
545    ///
546    /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
547    /// elements that follow it, preserving their relative order.
548    /// **This perturbs the index of all of those elements!**
549    ///
550    /// Computes in **O(n)** time (average).
551    pub fn shift_remove_entry(mut self) -> (K, V) {
552        self.map.shift_remove_index(self.index).unwrap()
553    }
554
555    /// Remove the key, value pair stored in the map for this entry, and return the value.
556    ///
557    /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
558    /// the last element of the map and popping it off.
559    /// **This perturbs the position of what used to be the last element!**
560    ///
561    /// Computes in **O(1)** time (average).
562    pub fn swap_remove(self) -> V {
563        self.swap_remove_entry().1
564    }
565
566    /// Remove the key, value pair stored in the map for this entry, and return the value.
567    ///
568    /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
569    /// elements that follow it, preserving their relative order.
570    /// **This perturbs the index of all of those elements!**
571    ///
572    /// Computes in **O(n)** time (average).
573    pub fn shift_remove(self) -> V {
574        self.shift_remove_entry().1
575    }
576
577    /// Moves the position of the entry to a new index
578    /// by shifting all other entries in-between.
579    ///
580    /// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
581    /// coming `from` the current [`.index()`][Self::index].
582    ///
583    /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
584    /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
585    ///
586    /// ***Panics*** if `to` is out of bounds.
587    ///
588    /// Computes in **O(n)** time (average).
589    #[track_caller]
590    pub fn move_index(mut self, to: usize) {
591        self.map.move_index(self.index, to);
592    }
593
594    /// Swaps the position of entry with another.
595    ///
596    /// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
597    /// with the current [`.index()`][Self::index] as one of the two being swapped.
598    ///
599    /// ***Panics*** if the `other` index is out of bounds.
600    ///
601    /// Computes in **O(1)** time (average).
602    #[track_caller]
603    pub fn swap_indices(mut self, other: usize) {
604        self.map.swap_indices(self.index, other);
605    }
606}
607
608impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IndexedEntry<'_, K, V> {
609    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
610        f.debug_struct("IndexedEntry")
611            .field("index", &self.index)
612            .field("key", self.key())
613            .field("value", self.get())
614            .finish()
615    }
616}
617
618impl<'a, K, V> From<OccupiedEntry<'a, K, V>> for IndexedEntry<'a, K, V> {
619    fn from(other: OccupiedEntry<'a, K, V>) -> Self {
620        Self {
621            index: other.index(),
622            map: other.into_ref_mut(),
623        }
624    }
625}