1 use core::fmt::{self, Debug};
2 use core::marker::PhantomData;
5 use super::super::borrow::DormantMutRef;
6 use super::super::node::{marker, Handle, NodeRef};
11 /// A view into a single entry in a map, which may either be vacant or occupied.
13 /// This `enum` is constructed from the [`entry`] method on [`BTreeMap`].
15 /// [`entry`]: BTreeMap::entry
16 #[stable(feature = "rust1", since = "1.0.0")]
17 #[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")]
18 pub enum Entry<'a, K: 'a, V: 'a> {
20 #[stable(feature = "rust1", since = "1.0.0")]
21 Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V>),
23 /// An occupied entry.
24 #[stable(feature = "rust1", since = "1.0.0")]
25 Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V>),
28 #[stable(feature = "debug_btree_map", since = "1.12.0")]
29 impl<K: Debug + Ord, V: Debug> Debug for Entry<'_, K, V> {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
33 Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
38 /// A view into a vacant entry in a `BTreeMap`.
39 /// It is part of the [`Entry`] enum.
40 #[stable(feature = "rust1", since = "1.0.0")]
41 pub struct VacantEntry<'a, K: 'a, V: 'a> {
43 /// `None` for a (empty) map without root
44 pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
45 pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V>>,
47 // Be invariant in `K` and `V`
48 pub(super) _marker: PhantomData<&'a mut (K, V)>,
51 #[stable(feature = "debug_btree_map", since = "1.12.0")]
52 impl<K: Debug + Ord, V> Debug for VacantEntry<'_, K, V> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 f.debug_tuple("VacantEntry").field(self.key()).finish()
58 /// A view into an occupied entry in a `BTreeMap`.
59 /// It is part of the [`Entry`] enum.
60 #[stable(feature = "rust1", since = "1.0.0")]
61 pub struct OccupiedEntry<'a, K: 'a, V: 'a> {
62 pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
63 pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V>>,
65 // Be invariant in `K` and `V`
66 pub(super) _marker: PhantomData<&'a mut (K, V)>,
69 #[stable(feature = "debug_btree_map", since = "1.12.0")]
70 impl<K: Debug + Ord, V: Debug> Debug for OccupiedEntry<'_, K, V> {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish()
76 /// The error returned by [`try_insert`](BTreeMap::try_insert) when the key already exists.
78 /// Contains the occupied entry, and the value that was not inserted.
79 #[unstable(feature = "map_try_insert", issue = "82766")]
80 pub struct OccupiedError<'a, K: 'a, V: 'a> {
81 /// The entry in the map that was already occupied.
82 pub entry: OccupiedEntry<'a, K, V>,
83 /// The value which was not inserted, because the entry was already occupied.
87 #[unstable(feature = "map_try_insert", issue = "82766")]
88 impl<K: Debug + Ord, V: Debug> Debug for OccupiedError<'_, K, V> {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 f.debug_struct("OccupiedError")
91 .field("key", self.entry.key())
92 .field("old_value", self.entry.get())
93 .field("new_value", &self.value)
98 #[unstable(feature = "map_try_insert", issue = "82766")]
99 impl<'a, K: Debug + Ord, V: Debug> fmt::Display for OccupiedError<'a, K, V> {
100 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 "failed to insert {:?}, key {:?} already exists with value {:?}",
111 impl<'a, K: Ord, V> Entry<'a, K, V> {
112 /// Ensures a value is in the entry by inserting the default if empty, and returns
113 /// a mutable reference to the value in the entry.
118 /// use std::collections::BTreeMap;
120 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
121 /// map.entry("poneyland").or_insert(12);
123 /// assert_eq!(map["poneyland"], 12);
125 #[stable(feature = "rust1", since = "1.0.0")]
126 pub fn or_insert(self, default: V) -> &'a mut V {
128 Occupied(entry) => entry.into_mut(),
129 Vacant(entry) => entry.insert(default),
133 /// Ensures a value is in the entry by inserting the result of the default function if empty,
134 /// and returns a mutable reference to the value in the entry.
139 /// use std::collections::BTreeMap;
141 /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
142 /// let s = "hoho".to_string();
144 /// map.entry("poneyland").or_insert_with(|| s);
146 /// assert_eq!(map["poneyland"], "hoho".to_string());
148 #[stable(feature = "rust1", since = "1.0.0")]
149 pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
151 Occupied(entry) => entry.into_mut(),
152 Vacant(entry) => entry.insert(default()),
156 /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
157 /// This method allows for generating key-derived values for insertion by providing the default
158 /// function a reference to the key that was moved during the `.entry(key)` method call.
160 /// The reference to the moved key is provided so that cloning or copying the key is
161 /// unnecessary, unlike with `.or_insert_with(|| ... )`.
166 /// use std::collections::BTreeMap;
168 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
170 /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
172 /// assert_eq!(map["poneyland"], 9);
175 #[stable(feature = "or_insert_with_key", since = "1.50.0")]
176 pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
178 Occupied(entry) => entry.into_mut(),
180 let value = default(entry.key());
186 /// Returns a reference to this entry's key.
191 /// use std::collections::BTreeMap;
193 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
194 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
196 #[stable(feature = "map_entry_keys", since = "1.10.0")]
197 pub fn key(&self) -> &K {
199 Occupied(ref entry) => entry.key(),
200 Vacant(ref entry) => entry.key(),
204 /// Provides in-place mutable access to an occupied entry before any
205 /// potential inserts into the map.
210 /// use std::collections::BTreeMap;
212 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
214 /// map.entry("poneyland")
215 /// .and_modify(|e| { *e += 1 })
217 /// assert_eq!(map["poneyland"], 42);
219 /// map.entry("poneyland")
220 /// .and_modify(|e| { *e += 1 })
222 /// assert_eq!(map["poneyland"], 43);
224 #[stable(feature = "entry_and_modify", since = "1.26.0")]
225 pub fn and_modify<F>(self, f: F) -> Self
230 Occupied(mut entry) => {
234 Vacant(entry) => Vacant(entry),
239 impl<'a, K: Ord, V: Default> Entry<'a, K, V> {
240 #[stable(feature = "entry_or_default", since = "1.28.0")]
241 /// Ensures a value is in the entry by inserting the default value if empty,
242 /// and returns a mutable reference to the value in the entry.
247 /// use std::collections::BTreeMap;
249 /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
250 /// map.entry("poneyland").or_default();
252 /// assert_eq!(map["poneyland"], None);
254 pub fn or_default(self) -> &'a mut V {
256 Occupied(entry) => entry.into_mut(),
257 Vacant(entry) => entry.insert(Default::default()),
262 impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
263 /// Gets a reference to the key that would be used when inserting a value
264 /// through the VacantEntry.
269 /// use std::collections::BTreeMap;
271 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
272 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
274 #[stable(feature = "map_entry_keys", since = "1.10.0")]
275 pub fn key(&self) -> &K {
279 /// Take ownership of the key.
284 /// use std::collections::BTreeMap;
285 /// use std::collections::btree_map::Entry;
287 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
289 /// if let Entry::Vacant(v) = map.entry("poneyland") {
293 #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
294 pub fn into_key(self) -> K {
298 /// Sets the value of the entry with the `VacantEntry`'s key,
299 /// and returns a mutable reference to it.
304 /// use std::collections::BTreeMap;
305 /// use std::collections::btree_map::Entry;
307 /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
309 /// if let Entry::Vacant(o) = map.entry("poneyland") {
312 /// assert_eq!(map["poneyland"], 37);
314 #[stable(feature = "rust1", since = "1.0.0")]
315 pub fn insert(self, value: V) -> &'a mut V {
316 let out_ptr = match self.handle {
318 // SAFETY: There is no tree yet so no reference to it exists.
319 let map = unsafe { self.dormant_map.awaken() };
320 let mut root = NodeRef::new_leaf();
321 let val_ptr = root.borrow_mut().push(self.key, value) as *mut V;
322 map.root = Some(root.forget_type());
326 Some(handle) => match handle.insert_recursing(self.key, value) {
328 // SAFETY: We have consumed self.handle.
329 let map = unsafe { self.dormant_map.awaken() };
333 (Some(ins), val_ptr) => {
335 // SAFETY: We have consumed self.handle and dropped the
336 // remaining reference to the tree, ins.left.
337 let map = unsafe { self.dormant_map.awaken() };
338 let root = map.root.as_mut().unwrap(); // same as ins.left
339 root.push_internal_level().push(ins.kv.0, ins.kv.1, ins.right);
345 // Now that we have finished growing the tree using borrowed references,
346 // dereference the pointer to a part of it, that we picked up along the way.
347 unsafe { &mut *out_ptr }
351 impl<'a, K: Ord, V> OccupiedEntry<'a, K, V> {
352 /// Gets a reference to the key in the entry.
357 /// use std::collections::BTreeMap;
359 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
360 /// map.entry("poneyland").or_insert(12);
361 /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
364 #[stable(feature = "map_entry_keys", since = "1.10.0")]
365 pub fn key(&self) -> &K {
366 self.handle.reborrow().into_kv().0
369 /// Take ownership of the key and value from the map.
374 /// use std::collections::BTreeMap;
375 /// use std::collections::btree_map::Entry;
377 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
378 /// map.entry("poneyland").or_insert(12);
380 /// if let Entry::Occupied(o) = map.entry("poneyland") {
381 /// // We delete the entry from the map.
382 /// o.remove_entry();
385 /// // If now try to get the value, it will panic:
386 /// // println!("{}", map["poneyland"]);
388 #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
389 pub fn remove_entry(self) -> (K, V) {
393 /// Gets a reference to the value in the entry.
398 /// use std::collections::BTreeMap;
399 /// use std::collections::btree_map::Entry;
401 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
402 /// map.entry("poneyland").or_insert(12);
404 /// if let Entry::Occupied(o) = map.entry("poneyland") {
405 /// assert_eq!(o.get(), &12);
409 #[stable(feature = "rust1", since = "1.0.0")]
410 pub fn get(&self) -> &V {
411 self.handle.reborrow().into_kv().1
414 /// Gets a mutable reference to the value in the entry.
416 /// If you need a reference to the `OccupiedEntry` that may outlive the
417 /// destruction of the `Entry` value, see [`into_mut`].
419 /// [`into_mut`]: OccupiedEntry::into_mut
424 /// use std::collections::BTreeMap;
425 /// use std::collections::btree_map::Entry;
427 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
428 /// map.entry("poneyland").or_insert(12);
430 /// assert_eq!(map["poneyland"], 12);
431 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
432 /// *o.get_mut() += 10;
433 /// assert_eq!(*o.get(), 22);
435 /// // We can use the same Entry multiple times.
436 /// *o.get_mut() += 2;
438 /// assert_eq!(map["poneyland"], 24);
440 #[stable(feature = "rust1", since = "1.0.0")]
441 pub fn get_mut(&mut self) -> &mut V {
442 self.handle.kv_mut().1
445 /// Converts the entry into a mutable reference to its value.
447 /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
449 /// [`get_mut`]: OccupiedEntry::get_mut
454 /// use std::collections::BTreeMap;
455 /// use std::collections::btree_map::Entry;
457 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
458 /// map.entry("poneyland").or_insert(12);
460 /// assert_eq!(map["poneyland"], 12);
461 /// if let Entry::Occupied(o) = map.entry("poneyland") {
462 /// *o.into_mut() += 10;
464 /// assert_eq!(map["poneyland"], 22);
466 #[must_use = "`self` will be dropped if the result is not used"]
467 #[stable(feature = "rust1", since = "1.0.0")]
468 pub fn into_mut(self) -> &'a mut V {
469 self.handle.into_val_mut()
472 /// Sets the value of the entry with the `OccupiedEntry`'s key,
473 /// and returns the entry's old value.
478 /// use std::collections::BTreeMap;
479 /// use std::collections::btree_map::Entry;
481 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
482 /// map.entry("poneyland").or_insert(12);
484 /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
485 /// assert_eq!(o.insert(15), 12);
487 /// assert_eq!(map["poneyland"], 15);
489 #[stable(feature = "rust1", since = "1.0.0")]
490 pub fn insert(&mut self, value: V) -> V {
491 mem::replace(self.get_mut(), value)
494 /// Takes the value of the entry out of the map, and returns it.
499 /// use std::collections::BTreeMap;
500 /// use std::collections::btree_map::Entry;
502 /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
503 /// map.entry("poneyland").or_insert(12);
505 /// if let Entry::Occupied(o) = map.entry("poneyland") {
506 /// assert_eq!(o.remove(), 12);
508 /// // If we try to get "poneyland"'s value, it'll panic:
509 /// // println!("{}", map["poneyland"]);
511 #[stable(feature = "rust1", since = "1.0.0")]
512 pub fn remove(self) -> V {
516 // Body of `remove_entry`, probably separate because the name reflects the returned pair.
517 pub(super) fn remove_kv(self) -> (K, V) {
518 let mut emptied_internal_root = false;
519 let (old_kv, _) = self.handle.remove_kv_tracking(|| emptied_internal_root = true);
520 // SAFETY: we consumed the intermediate root borrow, `self.handle`.
521 let map = unsafe { self.dormant_map.awaken() };
523 if emptied_internal_root {
524 let root = map.root.as_mut().unwrap();
525 root.pop_internal_level();