indexmap/map/raw_entry_v1.rs
1//! Opt-in access to the experimental raw entry API.
2//!
3//! This module is designed to mimic the raw entry API of [`HashMap`][std::collections::hash_map],
4//! matching its unstable state as of Rust 1.75. See the tracking issue
5//! [rust#56167](https://github.com/rust-lang/rust/issues/56167) for more details.
6//!
7//! The trait [`RawEntryApiV1`] and the `_v1` suffix on its methods are meant to insulate this for
8//! the future, in case later breaking changes are needed. If the standard library stabilizes its
9//! `hash_raw_entry` feature (or some replacement), matching *inherent* methods will be added to
10//! `IndexMap` without such an opt-in trait.
11
12use super::{Core, OccupiedEntry};
13use crate::{Equivalent, HashValue, IndexMap};
14use core::fmt;
15use core::hash::{BuildHasher, Hash};
16use core::marker::PhantomData;
17use core::mem;
18
19/// Opt-in access to the experimental raw entry API.
20///
21/// See the [`raw_entry_v1`][self] module documentation for more information.
22#[expect(private_bounds)]
23pub trait RawEntryApiV1<K, V, S>: Sealed {
24 /// Creates a raw immutable entry builder for the [`IndexMap`].
25 ///
26 /// Raw entries provide the lowest level of control for searching and
27 /// manipulating a map. They must be manually initialized with a hash and
28 /// then manually searched.
29 ///
30 /// This is useful for
31 /// * Hash memoization
32 /// * Using a search key that doesn't work with the [`Equivalent`] trait
33 /// * Using custom comparison logic without newtype wrappers
34 ///
35 /// Unless you are in such a situation, higher-level and more foolproof APIs like
36 /// [`get`][IndexMap::get] should be preferred.
37 ///
38 /// Immutable raw entries have very limited use; you might instead want
39 /// [`raw_entry_mut_v1`][Self::raw_entry_mut_v1].
40 ///
41 /// # Examples
42 ///
43 /// ```
44 /// use core::hash::BuildHasher;
45 /// use indexmap::map::{IndexMap, RawEntryApiV1};
46 ///
47 /// let mut map = IndexMap::new();
48 /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
49 ///
50 /// for k in ["a", "b", "c", "d", "e", "f"] {
51 /// let hash = map.hasher().hash_one(k);
52 /// let i = map.get_index_of(k);
53 /// let v = map.get(k);
54 /// let kv = map.get_key_value(k);
55 /// let ikv = map.get_full(k);
56 ///
57 /// println!("Key: {} and value: {:?}", k, v);
58 ///
59 /// assert_eq!(map.raw_entry_v1().from_key(k), kv);
60 /// assert_eq!(map.raw_entry_v1().from_hash(hash, |q| *q == k), kv);
61 /// assert_eq!(map.raw_entry_v1().from_key_hashed_nocheck(hash, k), kv);
62 /// assert_eq!(map.raw_entry_v1().from_hash_full(hash, |q| *q == k), ikv);
63 /// assert_eq!(map.raw_entry_v1().index_from_hash(hash, |q| *q == k), i);
64 /// }
65 /// ```
66 fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S>;
67
68 /// Creates a raw entry builder for the [`IndexMap`].
69 ///
70 /// Raw entries provide the lowest level of control for searching and
71 /// manipulating a map. They must be manually initialized with a hash and
72 /// then manually searched. After this, insertions into a vacant entry
73 /// still require an owned key to be provided.
74 ///
75 /// Raw entries are useful for such exotic situations as:
76 ///
77 /// * Hash memoization
78 /// * Deferring the creation of an owned key until it is known to be required
79 /// * Using a search key that doesn't work with the [`Equivalent`] trait
80 /// * Using custom comparison logic without newtype wrappers
81 ///
82 /// Because raw entries provide much more low-level control, it's much easier
83 /// to put the `IndexMap` into an inconsistent state which, while memory-safe,
84 /// will cause the map to produce seemingly random results. Higher-level and more
85 /// foolproof APIs like [`entry`][IndexMap::entry] should be preferred when possible.
86 ///
87 /// Raw entries give mutable access to the keys. This must not be used
88 /// to modify how the key would compare or hash, as the map will not re-evaluate
89 /// where the key should go, meaning the keys may become "lost" if their
90 /// location does not reflect their state. For instance, if you change a key
91 /// so that the map now contains keys which compare equal, search may start
92 /// acting erratically, with two keys randomly masking each other. Implementations
93 /// are free to assume this doesn't happen (within the limits of memory-safety).
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// use core::hash::BuildHasher;
99 /// use indexmap::map::{IndexMap, RawEntryApiV1};
100 /// use indexmap::map::raw_entry_v1::RawEntryMut;
101 ///
102 /// let mut map = IndexMap::new();
103 /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
104 ///
105 /// // Existing key (insert and update)
106 /// match map.raw_entry_mut_v1().from_key("a") {
107 /// RawEntryMut::Vacant(_) => unreachable!(),
108 /// RawEntryMut::Occupied(mut view) => {
109 /// assert_eq!(view.index(), 0);
110 /// assert_eq!(view.get(), &100);
111 /// let v = view.get_mut();
112 /// let new_v = (*v) * 10;
113 /// *v = new_v;
114 /// assert_eq!(view.insert(1111), 1000);
115 /// }
116 /// }
117 ///
118 /// assert_eq!(map["a"], 1111);
119 /// assert_eq!(map.len(), 3);
120 ///
121 /// // Existing key (take)
122 /// let hash = map.hasher().hash_one("c");
123 /// match map.raw_entry_mut_v1().from_key_hashed_nocheck(hash, "c") {
124 /// RawEntryMut::Vacant(_) => unreachable!(),
125 /// RawEntryMut::Occupied(view) => {
126 /// assert_eq!(view.index(), 2);
127 /// assert_eq!(view.shift_remove_entry(), ("c", 300));
128 /// }
129 /// }
130 /// assert_eq!(map.raw_entry_v1().from_key("c"), None);
131 /// assert_eq!(map.len(), 2);
132 ///
133 /// // Nonexistent key (insert and update)
134 /// let key = "d";
135 /// let hash = map.hasher().hash_one(key);
136 /// match map.raw_entry_mut_v1().from_hash(hash, |q| *q == key) {
137 /// RawEntryMut::Occupied(_) => unreachable!(),
138 /// RawEntryMut::Vacant(view) => {
139 /// assert_eq!(view.index(), 2);
140 /// let (k, value) = view.insert("d", 4000);
141 /// assert_eq!((*k, *value), ("d", 4000));
142 /// *value = 40000;
143 /// }
144 /// }
145 /// assert_eq!(map["d"], 40000);
146 /// assert_eq!(map.len(), 3);
147 ///
148 /// match map.raw_entry_mut_v1().from_hash(hash, |q| *q == key) {
149 /// RawEntryMut::Vacant(_) => unreachable!(),
150 /// RawEntryMut::Occupied(view) => {
151 /// assert_eq!(view.index(), 2);
152 /// assert_eq!(view.swap_remove_entry(), ("d", 40000));
153 /// }
154 /// }
155 /// assert_eq!(map.get("d"), None);
156 /// assert_eq!(map.len(), 2);
157 /// ```
158 fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S>;
159}
160
161impl<K, V, S> RawEntryApiV1<K, V, S> for IndexMap<K, V, S> {
162 fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S> {
163 RawEntryBuilder { map: self }
164 }
165
166 fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S> {
167 RawEntryBuilderMut { map: self }
168 }
169}
170
171/// A builder for computing where in an [`IndexMap`] a key-value pair would be stored.
172///
173/// This `struct` is created by the [`IndexMap::raw_entry_v1`] method, provided by the
174/// [`RawEntryApiV1`] trait. See its documentation for more.
175pub struct RawEntryBuilder<'a, K, V, S> {
176 map: &'a IndexMap<K, V, S>,
177}
178
179impl<K, V, S> fmt::Debug for RawEntryBuilder<'_, K, V, S> {
180 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
181 f.debug_struct("RawEntryBuilder").finish_non_exhaustive()
182 }
183}
184
185impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S> {
186 /// Access an entry by key.
187 pub fn from_key<Q>(self, key: &Q) -> Option<(&'a K, &'a V)>
188 where
189 S: BuildHasher,
190 Q: ?Sized + Hash + Equivalent<K>,
191 {
192 self.map.get_key_value(key)
193 }
194
195 /// Access an entry by a key and its hash.
196 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> Option<(&'a K, &'a V)>
197 where
198 Q: ?Sized + Equivalent<K>,
199 {
200 let hash = HashValue(hash as usize);
201 let i = self.map.core.get_index_of(hash, key)?;
202 self.map.get_index(i)
203 }
204
205 /// Access an entry by hash.
206 pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
207 where
208 F: FnMut(&K) -> bool,
209 {
210 let map = self.map;
211 let i = self.index_from_hash(hash, is_match)?;
212 map.get_index(i)
213 }
214
215 /// Access an entry by hash, including its index.
216 pub fn from_hash_full<F>(self, hash: u64, is_match: F) -> Option<(usize, &'a K, &'a V)>
217 where
218 F: FnMut(&K) -> bool,
219 {
220 let map = self.map;
221 let i = self.index_from_hash(hash, is_match)?;
222 let (key, value) = map.get_index(i)?;
223 Some((i, key, value))
224 }
225
226 /// Access the index of an entry by hash.
227 pub fn index_from_hash<F>(self, hash: u64, is_match: F) -> Option<usize>
228 where
229 F: FnMut(&K) -> bool,
230 {
231 let hash = HashValue(hash as usize);
232 self.map.core.get_index_of_raw(hash, is_match)
233 }
234}
235
236/// A builder for computing where in an [`IndexMap`] a key-value pair would be stored.
237///
238/// This `struct` is created by the [`IndexMap::raw_entry_mut_v1`] method, provided by the
239/// [`RawEntryApiV1`] trait. See its documentation for more.
240pub struct RawEntryBuilderMut<'a, K, V, S> {
241 map: &'a mut IndexMap<K, V, S>,
242}
243
244impl<K, V, S> fmt::Debug for RawEntryBuilderMut<'_, K, V, S> {
245 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246 f.debug_struct("RawEntryBuilderMut").finish_non_exhaustive()
247 }
248}
249
250impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S> {
251 /// Access an entry by key.
252 pub fn from_key<Q>(self, key: &Q) -> RawEntryMut<'a, K, V, S>
253 where
254 S: BuildHasher,
255 Q: ?Sized + Hash + Equivalent<K>,
256 {
257 let hash = self.map.hash(key);
258 self.from_key_hashed_nocheck(hash.get(), key)
259 }
260
261 /// Access an entry by a key and its hash.
262 pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> RawEntryMut<'a, K, V, S>
263 where
264 Q: ?Sized + Equivalent<K>,
265 {
266 self.from_hash(hash, |k| Q::equivalent(key, k))
267 }
268
269 /// Access an entry by hash.
270 pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
271 where
272 F: FnMut(&K) -> bool,
273 {
274 let hash = HashValue(hash as usize);
275 match OccupiedEntry::from_hash(&mut self.map.core, hash, is_match) {
276 Ok(inner) => RawEntryMut::Occupied(RawOccupiedEntryMut {
277 inner,
278 hash_builder: PhantomData,
279 }),
280 Err(map) => RawEntryMut::Vacant(RawVacantEntryMut {
281 map,
282 hash_builder: &self.map.hash_builder,
283 }),
284 }
285 }
286}
287
288/// Raw entry for an existing key-value pair or a vacant location to
289/// insert one.
290pub enum RawEntryMut<'a, K, V, S> {
291 /// Existing slot with equivalent key.
292 Occupied(RawOccupiedEntryMut<'a, K, V, S>),
293 /// Vacant slot (no equivalent key in the map).
294 Vacant(RawVacantEntryMut<'a, K, V, S>),
295}
296
297impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawEntryMut<'_, K, V, S> {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 let mut tuple = f.debug_tuple("RawEntryMut");
300 match self {
301 Self::Vacant(v) => tuple.field(v),
302 Self::Occupied(o) => tuple.field(o),
303 };
304 tuple.finish()
305 }
306}
307
308impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
309 /// Return the index where the key-value pair exists or may be inserted.
310 #[inline]
311 pub fn index(&self) -> usize {
312 match self {
313 Self::Occupied(entry) => entry.index(),
314 Self::Vacant(entry) => entry.index(),
315 }
316 }
317
318 /// Inserts the given default key and value in the entry if it is vacant and returns mutable
319 /// references to them. Otherwise mutable references to an already existent pair are returned.
320 pub fn or_insert(self, default_key: K, default_value: V) -> (&'a mut K, &'a mut V)
321 where
322 K: Hash,
323 S: BuildHasher,
324 {
325 match self {
326 Self::Occupied(entry) => entry.into_key_value_mut(),
327 Self::Vacant(entry) => entry.insert(default_key, default_value),
328 }
329 }
330
331 /// Inserts the result of the `call` function in the entry if it is vacant and returns mutable
332 /// references to them. Otherwise mutable references to an already existent pair are returned.
333 pub fn or_insert_with<F>(self, call: F) -> (&'a mut K, &'a mut V)
334 where
335 F: FnOnce() -> (K, V),
336 K: Hash,
337 S: BuildHasher,
338 {
339 match self {
340 Self::Occupied(entry) => entry.into_key_value_mut(),
341 Self::Vacant(entry) => {
342 let (key, value) = call();
343 entry.insert(key, value)
344 }
345 }
346 }
347
348 /// Modifies the entry if it is occupied.
349 pub fn and_modify<F>(mut self, f: F) -> Self
350 where
351 F: FnOnce(&mut K, &mut V),
352 {
353 if let Self::Occupied(entry) = &mut self {
354 let (k, v) = entry.get_key_value_mut();
355 f(k, v);
356 }
357 self
358 }
359}
360
361/// A raw view into an occupied entry in an [`IndexMap`].
362/// It is part of the [`RawEntryMut`] enum.
363pub struct RawOccupiedEntryMut<'a, K, V, S> {
364 inner: OccupiedEntry<'a, K, V>,
365 hash_builder: PhantomData<&'a S>,
366}
367
368impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawOccupiedEntryMut<'_, K, V, S> {
369 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370 f.debug_struct("RawOccupiedEntryMut")
371 .field("key", self.key())
372 .field("value", self.get())
373 .finish_non_exhaustive()
374 }
375}
376
377impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
378 /// Return the index of the key-value pair
379 #[inline]
380 pub fn index(&self) -> usize {
381 self.inner.index()
382 }
383
384 /// Gets a reference to the entry's key in the map.
385 ///
386 /// Note that this is not the key that was used to find the entry. There may be an observable
387 /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
388 /// extra fields or the memory address of an allocation.
389 pub fn key(&self) -> &K {
390 self.inner.key()
391 }
392
393 /// Gets a mutable reference to the entry's key in the map.
394 ///
395 /// Note that this is not the key that was used to find the entry. There may be an observable
396 /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
397 /// extra fields or the memory address of an allocation.
398 pub fn key_mut(&mut self) -> &mut K {
399 &mut self.inner.get_bucket_mut().key
400 }
401
402 /// Converts into a mutable reference to the entry's key in the map,
403 /// with a lifetime bound to the map itself.
404 ///
405 /// Note that this is not the key that was used to find the entry. There may be an observable
406 /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
407 /// extra fields or the memory address of an allocation.
408 pub fn into_key(self) -> &'a mut K {
409 &mut self.inner.into_bucket().key
410 }
411
412 /// Gets a reference to the entry's value in the map.
413 pub fn get(&self) -> &V {
414 self.inner.get()
415 }
416
417 /// Gets a mutable reference to the entry's value in the map.
418 ///
419 /// If you need a reference which may outlive the destruction of the
420 /// [`RawEntryMut`] value, see [`into_mut`][Self::into_mut].
421 pub fn get_mut(&mut self) -> &mut V {
422 self.inner.get_mut()
423 }
424
425 /// Converts into a mutable reference to the entry's value in the map,
426 /// with a lifetime bound to the map itself.
427 pub fn into_mut(self) -> &'a mut V {
428 self.inner.into_mut()
429 }
430
431 /// Gets a reference to the entry's key and value in the map.
432 pub fn get_key_value(&self) -> (&K, &V) {
433 self.inner.get_bucket().refs()
434 }
435
436 /// Gets a reference to the entry's key and value in the map.
437 pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
438 self.inner.get_bucket_mut().muts()
439 }
440
441 /// Converts into a mutable reference to the entry's key and value in the map,
442 /// with a lifetime bound to the map itself.
443 pub fn into_key_value_mut(self) -> (&'a mut K, &'a mut V) {
444 self.inner.into_bucket().muts()
445 }
446
447 /// Sets the value of the entry, and returns the entry's old value.
448 pub fn insert(&mut self, value: V) -> V {
449 self.inner.insert(value)
450 }
451
452 /// Sets the key of the entry, and returns the entry's old key.
453 pub fn insert_key(&mut self, key: K) -> K {
454 mem::replace(self.key_mut(), key)
455 }
456
457 /// Remove the key, value pair stored in the map for this entry, and return the value.
458 ///
459 /// **NOTE:** This is equivalent to [`.swap_remove()`][Self::swap_remove], replacing this
460 /// entry's position with the last element, and it is deprecated in favor of calling that
461 /// explicitly. If you need to preserve the relative order of the keys in the map, use
462 /// [`.shift_remove()`][Self::shift_remove] instead.
463 #[deprecated(note = "`remove` disrupts the map order -- \
464 use `swap_remove` or `shift_remove` for explicit behavior.")]
465 pub fn remove(self) -> V {
466 self.swap_remove()
467 }
468
469 /// Remove the key, value pair stored in the map for this entry, and return the value.
470 ///
471 /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it
472 /// with the last element of the map and popping it off.
473 /// **This perturbs the position of what used to be the last element!**
474 ///
475 /// Computes in **O(1)** time (average).
476 pub fn swap_remove(self) -> V {
477 self.inner.swap_remove()
478 }
479
480 /// Remove the key, value pair stored in the map for this entry, and return the value.
481 ///
482 /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the
483 /// elements that follow it, preserving their relative order.
484 /// **This perturbs the index of all of those elements!**
485 ///
486 /// Computes in **O(n)** time (average).
487 pub fn shift_remove(self) -> V {
488 self.inner.shift_remove()
489 }
490
491 /// Remove and return the key, value pair stored in the map for this entry
492 ///
493 /// **NOTE:** This is equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry],
494 /// replacing this entry's position with the last element, and it is deprecated in favor of
495 /// calling that explicitly. If you need to preserve the relative order of the keys in the map,
496 /// use [`.shift_remove_entry()`][Self::shift_remove_entry] instead.
497 #[deprecated(note = "`remove_entry` disrupts the map order -- \
498 use `swap_remove_entry` or `shift_remove_entry` for explicit behavior.")]
499 pub fn remove_entry(self) -> (K, V) {
500 self.swap_remove_entry()
501 }
502
503 /// Remove and return the key, value pair stored in the map for this entry
504 ///
505 /// Like [`Vec::swap_remove`][alloc::vec::Vec::swap_remove], the pair is removed by swapping it
506 /// with the last element of the map and popping it off.
507 /// **This perturbs the position of what used to be the last element!**
508 ///
509 /// Computes in **O(1)** time (average).
510 pub fn swap_remove_entry(self) -> (K, V) {
511 self.inner.swap_remove_entry()
512 }
513
514 /// Remove and return the key, value pair stored in the map for this entry
515 ///
516 /// Like [`Vec::remove`][alloc::vec::Vec::remove], the pair is removed by shifting all of the
517 /// elements that follow it, preserving their relative order.
518 /// **This perturbs the index of all of those elements!**
519 ///
520 /// Computes in **O(n)** time (average).
521 pub fn shift_remove_entry(self) -> (K, V) {
522 self.inner.shift_remove_entry()
523 }
524
525 /// Moves the position of the entry to a new index
526 /// by shifting all other entries in-between.
527 ///
528 /// This is equivalent to [`IndexMap::move_index`]
529 /// coming `from` the current [`.index()`][Self::index].
530 ///
531 /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
532 /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
533 ///
534 /// ***Panics*** if `to` is out of bounds.
535 ///
536 /// Computes in **O(n)** time (average).
537 #[track_caller]
538 pub fn move_index(self, to: usize) {
539 self.inner.move_index(to);
540 }
541
542 /// Swaps the position of entry with another.
543 ///
544 /// This is equivalent to [`IndexMap::swap_indices`]
545 /// with the current [`.index()`][Self::index] as one of the two being swapped.
546 ///
547 /// ***Panics*** if the `other` index is out of bounds.
548 ///
549 /// Computes in **O(1)** time (average).
550 #[track_caller]
551 pub fn swap_indices(self, other: usize) {
552 self.inner.swap_indices(other);
553 }
554}
555
556/// A view into a vacant raw entry in an [`IndexMap`].
557/// It is part of the [`RawEntryMut`] enum.
558pub struct RawVacantEntryMut<'a, K, V, S> {
559 map: &'a mut Core<K, V>,
560 hash_builder: &'a S,
561}
562
563impl<K, V, S> fmt::Debug for RawVacantEntryMut<'_, K, V, S> {
564 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565 f.debug_struct("RawVacantEntryMut").finish_non_exhaustive()
566 }
567}
568
569impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
570 /// Return the index where a key-value pair may be inserted.
571 pub fn index(&self) -> usize {
572 self.map.len()
573 }
574
575 /// Inserts the given key and value into the map,
576 /// and returns mutable references to them.
577 pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
578 where
579 K: Hash,
580 S: BuildHasher,
581 {
582 let h = self.hash_builder.hash_one(&key);
583 self.insert_hashed_nocheck(h, key, value)
584 }
585
586 /// Inserts the given key and value into the map with the provided hash,
587 /// and returns mutable references to them.
588 pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
589 let hash = HashValue(hash as usize);
590 self.map.insert_unique(hash, key, value).muts()
591 }
592
593 /// Inserts the given key and value into the map at the given index,
594 /// shifting others to the right, and returns mutable references to them.
595 ///
596 /// ***Panics*** if `index` is out of bounds.
597 ///
598 /// Computes in **O(n)** time (average).
599 #[track_caller]
600 pub fn shift_insert(self, index: usize, key: K, value: V) -> (&'a mut K, &'a mut V)
601 where
602 K: Hash,
603 S: BuildHasher,
604 {
605 let h = self.hash_builder.hash_one(&key);
606 self.shift_insert_hashed_nocheck(index, h, key, value)
607 }
608
609 /// Inserts the given key and value into the map with the provided hash
610 /// at the given index, and returns mutable references to them.
611 ///
612 /// ***Panics*** if `index` is out of bounds.
613 ///
614 /// Computes in **O(n)** time (average).
615 #[track_caller]
616 pub fn shift_insert_hashed_nocheck(
617 self,
618 index: usize,
619 hash: u64,
620 key: K,
621 value: V,
622 ) -> (&'a mut K, &'a mut V) {
623 let hash = HashValue(hash as usize);
624 self.map.shift_insert_unique(index, hash, key, value).muts()
625 }
626}
627
628trait Sealed {}
629
630impl<K, V, S> Sealed for IndexMap<K, V, S> {}
631
632#[test]
633fn assert_send_sync() {
634 fn assert_send_sync<T: Send + Sync>() {}
635 assert_send_sync::<RawEntryMut<'_, i32, i32, ()>>();
636}