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