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}