summaryrefslogtreecommitdiffstats
path: root/third_party/rust/indexmap/src/map/core/raw_entry_v1.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/indexmap/src/map/core/raw_entry_v1.rs')
-rw-r--r--third_party/rust/indexmap/src/map/core/raw_entry_v1.rs652
1 files changed, 652 insertions, 0 deletions
diff --git a/third_party/rust/indexmap/src/map/core/raw_entry_v1.rs b/third_party/rust/indexmap/src/map/core/raw_entry_v1.rs
new file mode 100644
index 0000000000..87e532d557
--- /dev/null
+++ b/third_party/rust/indexmap/src/map/core/raw_entry_v1.rs
@@ -0,0 +1,652 @@
+//! Opt-in access to the experimental raw entry API.
+//!
+//! This module is designed to mimic the raw entry API of [`HashMap`][std::collections::hash_map],
+//! matching its unstable state as of Rust 1.75. See the tracking issue
+//! [rust#56167](https://github.com/rust-lang/rust/issues/56167) for more details.
+//!
+//! The trait [`RawEntryApiV1`] and the `_v1` suffix on its methods are meant to insulate this for
+//! the future, in case later breaking changes are needed. If the standard library stabilizes its
+//! `hash_raw_entry` feature (or some replacement), matching *inherent* methods will be added to
+//! `IndexMap` without such an opt-in trait.
+
+use super::raw::RawTableEntry;
+use super::IndexMapCore;
+use crate::{Equivalent, HashValue, IndexMap};
+use core::fmt;
+use core::hash::{BuildHasher, Hash, Hasher};
+use core::marker::PhantomData;
+use core::mem;
+
+/// Opt-in access to the experimental raw entry API.
+///
+/// See the [`raw_entry_v1`][self] module documentation for more information.
+pub trait RawEntryApiV1<K, V, S>: private::Sealed {
+ /// Creates a raw immutable entry builder for the [`IndexMap`].
+ ///
+ /// Raw entries provide the lowest level of control for searching and
+ /// manipulating a map. They must be manually initialized with a hash and
+ /// then manually searched.
+ ///
+ /// This is useful for
+ /// * Hash memoization
+ /// * Using a search key that doesn't work with the [`Equivalent`] trait
+ /// * Using custom comparison logic without newtype wrappers
+ ///
+ /// Unless you are in such a situation, higher-level and more foolproof APIs like
+ /// [`get`][IndexMap::get] should be preferred.
+ ///
+ /// Immutable raw entries have very limited use; you might instead want
+ /// [`raw_entry_mut_v1`][Self::raw_entry_mut_v1].
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use core::hash::{BuildHasher, Hash};
+ /// use indexmap::map::{IndexMap, RawEntryApiV1};
+ ///
+ /// let mut map = IndexMap::new();
+ /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
+ ///
+ /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
+ /// use core::hash::Hasher;
+ /// let mut state = hash_builder.build_hasher();
+ /// key.hash(&mut state);
+ /// state.finish()
+ /// }
+ ///
+ /// for k in ["a", "b", "c", "d", "e", "f"] {
+ /// let hash = compute_hash(map.hasher(), k);
+ /// let i = map.get_index_of(k);
+ /// let v = map.get(k);
+ /// let kv = map.get_key_value(k);
+ /// let ikv = map.get_full(k);
+ ///
+ /// println!("Key: {} and value: {:?}", k, v);
+ ///
+ /// assert_eq!(map.raw_entry_v1().from_key(k), kv);
+ /// assert_eq!(map.raw_entry_v1().from_hash(hash, |q| *q == k), kv);
+ /// assert_eq!(map.raw_entry_v1().from_key_hashed_nocheck(hash, k), kv);
+ /// assert_eq!(map.raw_entry_v1().from_hash_full(hash, |q| *q == k), ikv);
+ /// assert_eq!(map.raw_entry_v1().index_from_hash(hash, |q| *q == k), i);
+ /// }
+ /// ```
+ fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S>;
+
+ /// Creates a raw entry builder for the [`IndexMap`].
+ ///
+ /// Raw entries provide the lowest level of control for searching and
+ /// manipulating a map. They must be manually initialized with a hash and
+ /// then manually searched. After this, insertions into a vacant entry
+ /// still require an owned key to be provided.
+ ///
+ /// Raw entries are useful for such exotic situations as:
+ ///
+ /// * Hash memoization
+ /// * Deferring the creation of an owned key until it is known to be required
+ /// * Using a search key that doesn't work with the [`Equivalent`] trait
+ /// * Using custom comparison logic without newtype wrappers
+ ///
+ /// Because raw entries provide much more low-level control, it's much easier
+ /// to put the `IndexMap` into an inconsistent state which, while memory-safe,
+ /// will cause the map to produce seemingly random results. Higher-level and more
+ /// foolproof APIs like [`entry`][IndexMap::entry] should be preferred when possible.
+ ///
+ /// Raw entries give mutable access to the keys. This must not be used
+ /// to modify how the key would compare or hash, as the map will not re-evaluate
+ /// where the key should go, meaning the keys may become "lost" if their
+ /// location does not reflect their state. For instance, if you change a key
+ /// so that the map now contains keys which compare equal, search may start
+ /// acting erratically, with two keys randomly masking each other. Implementations
+ /// are free to assume this doesn't happen (within the limits of memory-safety).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use core::hash::{BuildHasher, Hash};
+ /// use indexmap::map::{IndexMap, RawEntryApiV1};
+ /// use indexmap::map::raw_entry_v1::RawEntryMut;
+ ///
+ /// let mut map = IndexMap::new();
+ /// map.extend([("a", 100), ("b", 200), ("c", 300)]);
+ ///
+ /// fn compute_hash<K: Hash + ?Sized, S: BuildHasher>(hash_builder: &S, key: &K) -> u64 {
+ /// use core::hash::Hasher;
+ /// let mut state = hash_builder.build_hasher();
+ /// key.hash(&mut state);
+ /// state.finish()
+ /// }
+ ///
+ /// // Existing key (insert and update)
+ /// match map.raw_entry_mut_v1().from_key("a") {
+ /// RawEntryMut::Vacant(_) => unreachable!(),
+ /// RawEntryMut::Occupied(mut view) => {
+ /// assert_eq!(view.index(), 0);
+ /// assert_eq!(view.get(), &100);
+ /// let v = view.get_mut();
+ /// let new_v = (*v) * 10;
+ /// *v = new_v;
+ /// assert_eq!(view.insert(1111), 1000);
+ /// }
+ /// }
+ ///
+ /// assert_eq!(map["a"], 1111);
+ /// assert_eq!(map.len(), 3);
+ ///
+ /// // Existing key (take)
+ /// let hash = compute_hash(map.hasher(), "c");
+ /// match map.raw_entry_mut_v1().from_key_hashed_nocheck(hash, "c") {
+ /// RawEntryMut::Vacant(_) => unreachable!(),
+ /// RawEntryMut::Occupied(view) => {
+ /// assert_eq!(view.index(), 2);
+ /// assert_eq!(view.shift_remove_entry(), ("c", 300));
+ /// }
+ /// }
+ /// assert_eq!(map.raw_entry_v1().from_key("c"), None);
+ /// assert_eq!(map.len(), 2);
+ ///
+ /// // Nonexistent key (insert and update)
+ /// let key = "d";
+ /// let hash = compute_hash(map.hasher(), key);
+ /// match map.raw_entry_mut_v1().from_hash(hash, |q| *q == key) {
+ /// RawEntryMut::Occupied(_) => unreachable!(),
+ /// RawEntryMut::Vacant(view) => {
+ /// assert_eq!(view.index(), 2);
+ /// let (k, value) = view.insert("d", 4000);
+ /// assert_eq!((*k, *value), ("d", 4000));
+ /// *value = 40000;
+ /// }
+ /// }
+ /// assert_eq!(map["d"], 40000);
+ /// assert_eq!(map.len(), 3);
+ ///
+ /// match map.raw_entry_mut_v1().from_hash(hash, |q| *q == key) {
+ /// RawEntryMut::Vacant(_) => unreachable!(),
+ /// RawEntryMut::Occupied(view) => {
+ /// assert_eq!(view.index(), 2);
+ /// assert_eq!(view.swap_remove_entry(), ("d", 40000));
+ /// }
+ /// }
+ /// assert_eq!(map.get("d"), None);
+ /// assert_eq!(map.len(), 2);
+ /// ```
+ fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S>;
+}
+
+impl<K, V, S> RawEntryApiV1<K, V, S> for IndexMap<K, V, S> {
+ fn raw_entry_v1(&self) -> RawEntryBuilder<'_, K, V, S> {
+ RawEntryBuilder { map: self }
+ }
+
+ fn raw_entry_mut_v1(&mut self) -> RawEntryBuilderMut<'_, K, V, S> {
+ RawEntryBuilderMut { map: self }
+ }
+}
+
+/// A builder for computing where in an [`IndexMap`] a key-value pair would be stored.
+///
+/// This `struct` is created by the [`IndexMap::raw_entry_v1`] method, provided by the
+/// [`RawEntryApiV1`] trait. See its documentation for more.
+pub struct RawEntryBuilder<'a, K, V, S> {
+ map: &'a IndexMap<K, V, S>,
+}
+
+impl<K, V, S> fmt::Debug for RawEntryBuilder<'_, K, V, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RawEntryBuilder").finish_non_exhaustive()
+ }
+}
+
+impl<'a, K, V, S> RawEntryBuilder<'a, K, V, S> {
+ /// Access an entry by key.
+ pub fn from_key<Q>(self, key: &Q) -> Option<(&'a K, &'a V)>
+ where
+ S: BuildHasher,
+ Q: ?Sized + Hash + Equivalent<K>,
+ {
+ self.map.get_key_value(key)
+ }
+
+ /// Access an entry by a key and its hash.
+ pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> Option<(&'a K, &'a V)>
+ where
+ Q: ?Sized + Equivalent<K>,
+ {
+ let hash = HashValue(hash as usize);
+ let i = self.map.core.get_index_of(hash, key)?;
+ self.map.get_index(i)
+ }
+
+ /// Access an entry by hash.
+ pub fn from_hash<F>(self, hash: u64, is_match: F) -> Option<(&'a K, &'a V)>
+ where
+ F: FnMut(&K) -> bool,
+ {
+ let map = self.map;
+ let i = self.index_from_hash(hash, is_match)?;
+ map.get_index(i)
+ }
+
+ /// Access an entry by hash, including its index.
+ pub fn from_hash_full<F>(self, hash: u64, is_match: F) -> Option<(usize, &'a K, &'a V)>
+ where
+ F: FnMut(&K) -> bool,
+ {
+ let map = self.map;
+ let i = self.index_from_hash(hash, is_match)?;
+ let (key, value) = map.get_index(i)?;
+ Some((i, key, value))
+ }
+
+ /// Access the index of an entry by hash.
+ pub fn index_from_hash<F>(self, hash: u64, mut is_match: F) -> Option<usize>
+ where
+ F: FnMut(&K) -> bool,
+ {
+ let hash = HashValue(hash as usize);
+ let entries = &*self.map.core.entries;
+ let eq = move |&i: &usize| is_match(&entries[i].key);
+ self.map.core.indices.get(hash.get(), eq).copied()
+ }
+}
+
+/// A builder for computing where in an [`IndexMap`] a key-value pair would be stored.
+///
+/// This `struct` is created by the [`IndexMap::raw_entry_mut_v1`] method, provided by the
+/// [`RawEntryApiV1`] trait. See its documentation for more.
+pub struct RawEntryBuilderMut<'a, K, V, S> {
+ map: &'a mut IndexMap<K, V, S>,
+}
+
+impl<K, V, S> fmt::Debug for RawEntryBuilderMut<'_, K, V, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RawEntryBuilderMut").finish_non_exhaustive()
+ }
+}
+
+impl<'a, K, V, S> RawEntryBuilderMut<'a, K, V, S> {
+ /// Access an entry by key.
+ pub fn from_key<Q>(self, key: &Q) -> RawEntryMut<'a, K, V, S>
+ where
+ S: BuildHasher,
+ Q: ?Sized + Hash + Equivalent<K>,
+ {
+ let hash = self.map.hash(key);
+ self.from_key_hashed_nocheck(hash.get(), key)
+ }
+
+ /// Access an entry by a key and its hash.
+ pub fn from_key_hashed_nocheck<Q>(self, hash: u64, key: &Q) -> RawEntryMut<'a, K, V, S>
+ where
+ Q: ?Sized + Equivalent<K>,
+ {
+ self.from_hash(hash, |k| Q::equivalent(key, k))
+ }
+
+ /// Access an entry by hash.
+ pub fn from_hash<F>(self, hash: u64, is_match: F) -> RawEntryMut<'a, K, V, S>
+ where
+ F: FnMut(&K) -> bool,
+ {
+ let hash = HashValue(hash as usize);
+ match self.map.core.raw_entry(hash, is_match) {
+ Ok(raw) => RawEntryMut::Occupied(RawOccupiedEntryMut {
+ raw,
+ hash_builder: PhantomData,
+ }),
+ Err(map) => RawEntryMut::Vacant(RawVacantEntryMut {
+ map,
+ hash_builder: &self.map.hash_builder,
+ }),
+ }
+ }
+}
+
+/// Raw entry for an existing key-value pair or a vacant location to
+/// insert one.
+pub enum RawEntryMut<'a, K, V, S> {
+ /// Existing slot with equivalent key.
+ Occupied(RawOccupiedEntryMut<'a, K, V, S>),
+ /// Vacant slot (no equivalent key in the map).
+ Vacant(RawVacantEntryMut<'a, K, V, S>),
+}
+
+impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawEntryMut<'_, K, V, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut tuple = f.debug_tuple("RawEntryMut");
+ match self {
+ Self::Vacant(v) => tuple.field(v),
+ Self::Occupied(o) => tuple.field(o),
+ };
+ tuple.finish()
+ }
+}
+
+impl<'a, K, V, S> RawEntryMut<'a, K, V, S> {
+ /// Return the index where the key-value pair exists or may be inserted.
+ #[inline]
+ pub fn index(&self) -> usize {
+ match self {
+ Self::Occupied(entry) => entry.index(),
+ Self::Vacant(entry) => entry.index(),
+ }
+ }
+
+ /// Inserts the given default key and value in the entry if it is vacant and returns mutable
+ /// references to them. Otherwise mutable references to an already existent pair are returned.
+ pub fn or_insert(self, default_key: K, default_value: V) -> (&'a mut K, &'a mut V)
+ where
+ K: Hash,
+ S: BuildHasher,
+ {
+ match self {
+ Self::Occupied(entry) => entry.into_key_value_mut(),
+ Self::Vacant(entry) => entry.insert(default_key, default_value),
+ }
+ }
+
+ /// Inserts the result of the `call` function in the entry if it is vacant and returns mutable
+ /// references to them. Otherwise mutable references to an already existent pair are returned.
+ pub fn or_insert_with<F>(self, call: F) -> (&'a mut K, &'a mut V)
+ where
+ F: FnOnce() -> (K, V),
+ K: Hash,
+ S: BuildHasher,
+ {
+ match self {
+ Self::Occupied(entry) => entry.into_key_value_mut(),
+ Self::Vacant(entry) => {
+ let (key, value) = call();
+ entry.insert(key, value)
+ }
+ }
+ }
+
+ /// Modifies the entry if it is occupied.
+ pub fn and_modify<F>(mut self, f: F) -> Self
+ where
+ F: FnOnce(&mut K, &mut V),
+ {
+ if let Self::Occupied(entry) = &mut self {
+ let (k, v) = entry.get_key_value_mut();
+ f(k, v);
+ }
+ self
+ }
+}
+
+/// A raw view into an occupied entry in an [`IndexMap`].
+/// It is part of the [`RawEntryMut`] enum.
+pub struct RawOccupiedEntryMut<'a, K, V, S> {
+ raw: RawTableEntry<'a, K, V>,
+ hash_builder: PhantomData<&'a S>,
+}
+
+impl<K: fmt::Debug, V: fmt::Debug, S> fmt::Debug for RawOccupiedEntryMut<'_, K, V, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RawOccupiedEntryMut")
+ .field("key", self.key())
+ .field("value", self.get())
+ .finish_non_exhaustive()
+ }
+}
+
+impl<'a, K, V, S> RawOccupiedEntryMut<'a, K, V, S> {
+ /// Return the index of the key-value pair
+ #[inline]
+ pub fn index(&self) -> usize {
+ self.raw.index()
+ }
+
+ /// Gets a reference to the entry's key in the map.
+ ///
+ /// Note that this is not the key that was used to find the entry. There may be an observable
+ /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
+ /// extra fields or the memory address of an allocation.
+ pub fn key(&self) -> &K {
+ &self.raw.bucket().key
+ }
+
+ /// Gets a mutable reference to the entry's key in the map.
+ ///
+ /// Note that this is not the key that was used to find the entry. There may be an observable
+ /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
+ /// extra fields or the memory address of an allocation.
+ pub fn key_mut(&mut self) -> &mut K {
+ &mut self.raw.bucket_mut().key
+ }
+
+ /// Converts into a mutable reference to the entry's key in the map,
+ /// with a lifetime bound to the map itself.
+ ///
+ /// Note that this is not the key that was used to find the entry. There may be an observable
+ /// difference if the key type has any distinguishing features outside of `Hash` and `Eq`, like
+ /// extra fields or the memory address of an allocation.
+ pub fn into_key(self) -> &'a mut K {
+ &mut self.raw.into_bucket().key
+ }
+
+ /// Gets a reference to the entry's value in the map.
+ pub fn get(&self) -> &V {
+ &self.raw.bucket().value
+ }
+
+ /// Gets a mutable reference to the entry's value in the map.
+ ///
+ /// If you need a reference which may outlive the destruction of the
+ /// [`RawEntryMut`] value, see [`into_mut`][Self::into_mut].
+ pub fn get_mut(&mut self) -> &mut V {
+ &mut self.raw.bucket_mut().value
+ }
+
+ /// Converts into a mutable reference to the entry's value in the map,
+ /// with a lifetime bound to the map itself.
+ pub fn into_mut(self) -> &'a mut V {
+ &mut self.raw.into_bucket().value
+ }
+
+ /// Gets a reference to the entry's key and value in the map.
+ pub fn get_key_value(&self) -> (&K, &V) {
+ self.raw.bucket().refs()
+ }
+
+ /// Gets a reference to the entry's key and value in the map.
+ pub fn get_key_value_mut(&mut self) -> (&mut K, &mut V) {
+ self.raw.bucket_mut().muts()
+ }
+
+ /// Converts into a mutable reference to the entry's key and value in the map,
+ /// with a lifetime bound to the map itself.
+ pub fn into_key_value_mut(self) -> (&'a mut K, &'a mut V) {
+ self.raw.into_bucket().muts()
+ }
+
+ /// Sets the value of the entry, and returns the entry's old value.
+ pub fn insert(&mut self, value: V) -> V {
+ mem::replace(self.get_mut(), value)
+ }
+
+ /// Sets the key of the entry, and returns the entry's old key.
+ pub fn insert_key(&mut self, key: K) -> K {
+ mem::replace(self.key_mut(), key)
+ }
+
+ /// Remove the key, value pair stored in the map for this entry, and return the value.
+ ///
+ /// **NOTE:** This is equivalent to [`.swap_remove()`][Self::swap_remove], replacing this
+ /// entry's position with the last element, and it is deprecated in favor of calling that
+ /// explicitly. If you need to preserve the relative order of the keys in the map, use
+ /// [`.shift_remove()`][Self::shift_remove] instead.
+ #[deprecated(note = "`remove` disrupts the map order -- \
+ use `swap_remove` or `shift_remove` for explicit behavior.")]
+ pub fn remove(self) -> V {
+ self.swap_remove()
+ }
+
+ /// Remove the key, value pair stored in the map for this entry, and return the value.
+ ///
+ /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
+ /// the last element of the map and popping it off.
+ /// **This perturbs the position of what used to be the last element!**
+ ///
+ /// Computes in **O(1)** time (average).
+ pub fn swap_remove(self) -> V {
+ self.swap_remove_entry().1
+ }
+
+ /// Remove the key, value pair stored in the map for this entry, and return the value.
+ ///
+ /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
+ /// elements that follow it, preserving their relative order.
+ /// **This perturbs the index of all of those elements!**
+ ///
+ /// Computes in **O(n)** time (average).
+ pub fn shift_remove(self) -> V {
+ self.shift_remove_entry().1
+ }
+
+ /// Remove and return the key, value pair stored in the map for this entry
+ ///
+ /// **NOTE:** This is equivalent to [`.swap_remove_entry()`][Self::swap_remove_entry],
+ /// replacing this entry's position with the last element, and it is deprecated in favor of
+ /// calling that explicitly. If you need to preserve the relative order of the keys in the map,
+ /// use [`.shift_remove_entry()`][Self::shift_remove_entry] instead.
+ #[deprecated(note = "`remove_entry` disrupts the map order -- \
+ use `swap_remove_entry` or `shift_remove_entry` for explicit behavior.")]
+ pub fn remove_entry(self) -> (K, V) {
+ self.swap_remove_entry()
+ }
+
+ /// Remove and return the key, value pair stored in the map for this entry
+ ///
+ /// Like [`Vec::swap_remove`][crate::Vec::swap_remove], the pair is removed by swapping it with
+ /// the last element of the map and popping it off.
+ /// **This perturbs the position of what used to be the last element!**
+ ///
+ /// Computes in **O(1)** time (average).
+ pub fn swap_remove_entry(self) -> (K, V) {
+ let (map, index) = self.raw.remove_index();
+ map.swap_remove_finish(index)
+ }
+
+ /// Remove and return the key, value pair stored in the map for this entry
+ ///
+ /// Like [`Vec::remove`][crate::Vec::remove], the pair is removed by shifting all of the
+ /// elements that follow it, preserving their relative order.
+ /// **This perturbs the index of all of those elements!**
+ ///
+ /// Computes in **O(n)** time (average).
+ pub fn shift_remove_entry(self) -> (K, V) {
+ let (map, index) = self.raw.remove_index();
+ map.shift_remove_finish(index)
+ }
+
+ /// Moves the position of the entry to a new index
+ /// by shifting all other entries in-between.
+ ///
+ /// This is equivalent to [`IndexMap::move_index`]
+ /// coming `from` the current [`.index()`][Self::index].
+ ///
+ /// * If `self.index() < to`, the other pairs will shift down while the targeted pair moves up.
+ /// * If `self.index() > to`, the other pairs will shift up while the targeted pair moves down.
+ ///
+ /// ***Panics*** if `to` is out of bounds.
+ ///
+ /// Computes in **O(n)** time (average).
+ pub fn move_index(self, to: usize) {
+ let (map, index) = self.raw.into_inner();
+ map.move_index(index, to);
+ }
+
+ /// Swaps the position of entry with another.
+ ///
+ /// This is equivalent to [`IndexMap::swap_indices`]
+ /// with the current [`.index()`][Self::index] as one of the two being swapped.
+ ///
+ /// ***Panics*** if the `other` index is out of bounds.
+ ///
+ /// Computes in **O(1)** time (average).
+ pub fn swap_indices(self, other: usize) {
+ let (map, index) = self.raw.into_inner();
+ map.swap_indices(index, other)
+ }
+}
+
+/// A view into a vacant raw entry in an [`IndexMap`].
+/// It is part of the [`RawEntryMut`] enum.
+pub struct RawVacantEntryMut<'a, K, V, S> {
+ map: &'a mut IndexMapCore<K, V>,
+ hash_builder: &'a S,
+}
+
+impl<K, V, S> fmt::Debug for RawVacantEntryMut<'_, K, V, S> {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.debug_struct("RawVacantEntryMut").finish_non_exhaustive()
+ }
+}
+
+impl<'a, K, V, S> RawVacantEntryMut<'a, K, V, S> {
+ /// Return the index where a key-value pair may be inserted.
+ pub fn index(&self) -> usize {
+ self.map.indices.len()
+ }
+
+ /// Inserts the given key and value into the map,
+ /// and returns mutable references to them.
+ pub fn insert(self, key: K, value: V) -> (&'a mut K, &'a mut V)
+ where
+ K: Hash,
+ S: BuildHasher,
+ {
+ let mut h = self.hash_builder.build_hasher();
+ key.hash(&mut h);
+ self.insert_hashed_nocheck(h.finish(), key, value)
+ }
+
+ /// Inserts the given key and value into the map with the provided hash,
+ /// and returns mutable references to them.
+ pub fn insert_hashed_nocheck(self, hash: u64, key: K, value: V) -> (&'a mut K, &'a mut V) {
+ let hash = HashValue(hash as usize);
+ let i = self.map.insert_unique(hash, key, value);
+ self.map.entries[i].muts()
+ }
+
+ /// Inserts the given key and value into the map at the given index,
+ /// shifting others to the right, and returns mutable references to them.
+ ///
+ /// ***Panics*** if `index` is out of bounds.
+ ///
+ /// Computes in **O(n)** time (average).
+ pub fn shift_insert(self, index: usize, key: K, value: V) -> (&'a mut K, &'a mut V)
+ where
+ K: Hash,
+ S: BuildHasher,
+ {
+ let mut h = self.hash_builder.build_hasher();
+ key.hash(&mut h);
+ self.shift_insert_hashed_nocheck(index, h.finish(), key, value)
+ }
+
+ /// Inserts the given key and value into the map with the provided hash
+ /// at the given index, and returns mutable references to them.
+ ///
+ /// ***Panics*** if `index` is out of bounds.
+ ///
+ /// Computes in **O(n)** time (average).
+ pub fn shift_insert_hashed_nocheck(
+ self,
+ index: usize,
+ hash: u64,
+ key: K,
+ value: V,
+ ) -> (&'a mut K, &'a mut V) {
+ let hash = HashValue(hash as usize);
+ self.map.shift_insert_unique(index, hash, key, value);
+ self.map.entries[index].muts()
+ }
+}
+
+mod private {
+ pub trait Sealed {}
+
+ impl<K, V, S> Sealed for super::IndexMap<K, V, S> {}
+}