indexmap/map/core/
entry.rs

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