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> {}