indexmap/map/core/
entry.rs

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