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}