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    pub fn swap_indices(self, other: usize) {
312        let index = self.index();
313        self.into_ref_mut().swap_indices(index, other);
314    }
315}
316
317impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for OccupiedEntry<'_, K, V> {
318    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
319        f.debug_struct("OccupiedEntry")
320            .field("key", self.key())
321            .field("value", self.get())
322            .finish()
323    }
324}
325
326impl<'a, K, V> From<IndexedEntry<'a, K, V>> for OccupiedEntry<'a, K, V> {
327    fn from(other: IndexedEntry<'a, K, V>) -> Self {
328        let IndexedEntry {
329            map: RefMut { indices, entries },
330            index,
331        } = other;
332        let hash = entries[index].hash;
333        Self {
334            entries,
335            index: indices
336                .find_entry(hash.get(), move |&i| i == index)
337                .expect("index not found"),
338        }
339    }
340}
341
342/// A view into a vacant entry in an [`IndexMap`][crate::IndexMap].
343/// It is part of the [`Entry`] enum.
344pub struct VacantEntry<'a, K, V> {
345    map: RefMut<'a, K, V>,
346    hash: HashValue,
347    key: K,
348}
349
350impl<'a, K, V> VacantEntry<'a, K, V> {
351    /// Return the index where a key-value pair may be inserted.
352    pub fn index(&self) -> usize {
353        self.map.indices.len()
354    }
355
356    /// Gets a reference to the key that was used to find the entry.
357    pub fn key(&self) -> &K {
358        &self.key
359    }
360
361    pub(crate) fn key_mut(&mut self) -> &mut K {
362        &mut self.key
363    }
364
365    /// Takes ownership of the key, leaving the entry vacant.
366    pub fn into_key(self) -> K {
367        self.key
368    }
369
370    /// Inserts the entry's key and the given value into the map, and returns a mutable reference
371    /// to the value.
372    ///
373    /// Computes in **O(1)** time (amortized average).
374    pub fn insert(self, value: V) -> &'a mut V {
375        self.insert_entry(value).into_mut()
376    }
377
378    /// Inserts the entry's key and the given value into the map, and returns an `OccupiedEntry`.
379    ///
380    /// Computes in **O(1)** time (amortized average).
381    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V> {
382        let Self { map, hash, key } = self;
383        map.insert_unique(hash, key, value)
384    }
385
386    /// Inserts the entry's key and the given value into the map at its ordered
387    /// position among sorted keys, and returns the new index and a mutable
388    /// reference to the value.
389    ///
390    /// If the existing keys are **not** already sorted, then the insertion
391    /// index is unspecified (like [`slice::binary_search`]), but the key-value
392    /// pair is inserted at that position regardless.
393    ///
394    /// Computes in **O(n)** time (average).
395    pub fn insert_sorted(self, value: V) -> (usize, &'a mut V)
396    where
397        K: Ord,
398    {
399        let slice = crate::map::Slice::from_slice(self.map.entries);
400        let i = slice.binary_search_keys(&self.key).unwrap_err();
401        (i, self.shift_insert(i, value))
402    }
403
404    /// Inserts the entry's key and the given value into the map at the given index,
405    /// shifting others to the right, and returns a mutable reference to the value.
406    ///
407    /// ***Panics*** if `index` is out of bounds.
408    ///
409    /// Computes in **O(n)** time (average).
410    pub fn shift_insert(mut self, index: usize, value: V) -> &'a mut V {
411        self.map
412            .shift_insert_unique(index, self.hash, self.key, value);
413        &mut self.map.entries[index].value
414    }
415}
416
417impl<K: fmt::Debug, V> fmt::Debug for VacantEntry<'_, K, V> {
418    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
419        f.debug_tuple("VacantEntry").field(self.key()).finish()
420    }
421}
422
423/// A view into an occupied entry in an [`IndexMap`][crate::IndexMap] obtained by index.
424///
425/// This `struct` is created from the [`get_index_entry`][crate::IndexMap::get_index_entry] method.
426pub struct IndexedEntry<'a, K, V> {
427    map: RefMut<'a, K, V>,
428    // We have a mutable reference to the map, which keeps the index
429    // valid and pointing to the correct entry.
430    index: usize,
431}
432
433impl<'a, K, V> IndexedEntry<'a, K, V> {
434    pub(crate) fn new(map: &'a mut IndexMapCore<K, V>, index: usize) -> Self {
435        Self {
436            map: map.borrow_mut(),
437            index,
438        }
439    }
440
441    /// Return the index of the key-value pair
442    #[inline]
443    pub fn index(&self) -> usize {
444        self.index
445    }
446
447    /// Gets a reference to the entry's key in the map.
448    pub fn key(&self) -> &K {
449        &self.map.entries[self.index].key
450    }
451
452    pub(crate) fn key_mut(&mut self) -> &mut K {
453        &mut self.map.entries[self.index].key
454    }
455
456    /// Gets a reference to the entry's value in the map.
457    pub fn get(&self) -> &V {
458        &self.map.entries[self.index].value
459    }
460
461    /// Gets a mutable reference to the entry's value in the map.
462    ///
463    /// If you need a reference which may outlive the destruction of the
464    /// `IndexedEntry` value, see [`into_mut`][Self::into_mut].
465    pub fn get_mut(&mut self) -> &mut V {
466        &mut self.map.entries[self.index].value
467    }
468
469    /// Sets the value of the entry to `value`, and returns the entry's old value.
470    pub fn insert(&mut self, value: V) -> V {
471        mem::replace(self.get_mut(), value)
472    }
473
474    /// Converts into a mutable reference to the entry's value in the map,
475    /// with a lifetime bound to the map itself.
476    pub fn into_mut(self) -> &'a mut V {
477        &mut self.map.entries[self.index].value
478    }
479
480    /// Remove and return the key, value pair stored in the map for this entry
481    ///
482    /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
483    /// the last element of the map and popping it off.
484    /// **This perturbs the position of what used to be the last element!**
485    ///
486    /// Computes in **O(1)** time (average).
487    pub fn swap_remove_entry(mut self) -> (K, V) {
488        self.map.swap_remove_index(self.index).unwrap()
489    }
490
491    /// Remove and return the key, value pair stored in the map for this entry
492    ///
493    /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
494    /// elements that follow it, preserving their relative order.
495    /// **This perturbs the index of all of those elements!**
496    ///
497    /// Computes in **O(n)** time (average).
498    pub fn shift_remove_entry(mut self) -> (K, V) {
499        self.map.shift_remove_index(self.index).unwrap()
500    }
501
502    /// Remove the key, value pair stored in the map for this entry, and return the value.
503    ///
504    /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
505    /// the last element of the map and popping it off.
506    /// **This perturbs the position of what used to be the last element!**
507    ///
508    /// Computes in **O(1)** time (average).
509    pub fn swap_remove(self) -> V {
510        self.swap_remove_entry().1
511    }
512
513    /// Remove the key, value pair stored in the map for this entry, and return the value.
514    ///
515    /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
516    /// elements that follow it, preserving their relative order.
517    /// **This perturbs the index of all of those elements!**
518    ///
519    /// Computes in **O(n)** time (average).
520    pub fn shift_remove(self) -> V {
521        self.shift_remove_entry().1
522    }
523
524    /// Moves the position of the entry to a new index
525    /// by shifting all other entries in-between.
526    ///
527    /// This is equivalent to [`IndexMap::move_index`][`crate::IndexMap::move_index`]
528    /// coming `from` the current [`.index()`][Self::index].
529    ///
530    /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
531    /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
532    ///
533    /// ***Panics*** if `to` is out of bounds.
534    ///
535    /// Computes in **O(n)** time (average).
536    #[track_caller]
537    pub fn move_index(mut self, to: usize) {
538        self.map.move_index(self.index, to);
539    }
540
541    /// Swaps the position of entry with another.
542    ///
543    /// This is equivalent to [`IndexMap::swap_indices`][`crate::IndexMap::swap_indices`]
544    /// with the current [`.index()`][Self::index] as one of the two being swapped.
545    ///
546    /// ***Panics*** if the `other` index is out of bounds.
547    ///
548    /// Computes in **O(1)** time (average).
549    pub fn swap_indices(mut self, other: usize) {
550        self.map.swap_indices(self.index, other);
551    }
552}
553
554impl<K: fmt::Debug, V: fmt::Debug> fmt::Debug for IndexedEntry<'_, K, V> {
555    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
556        f.debug_struct("IndexedEntry")
557            .field("index", &self.index)
558            .field("key", self.key())
559            .field("value", self.get())
560            .finish()
561    }
562}
563
564impl<'a, K, V> From<OccupiedEntry<'a, K, V>> for IndexedEntry<'a, K, V> {
565    fn from(other: OccupiedEntry<'a, K, V>) -> Self {
566        Self {
567            index: other.index(),
568            map: other.into_ref_mut(),
569        }
570    }
571}