alloc/collections/btree/map/
entry.rs

1use core::fmt::{self, Debug};
2use core::marker::PhantomData;
3use core::mem;
4
5use Entry::*;
6
7use super::super::borrow::DormantMutRef;
8use super::super::node::{Handle, NodeRef, marker};
9use super::BTreeMap;
10use crate::alloc::{Allocator, Global};
11
12/// A view into a single entry in a map, which may either be vacant or occupied.
13///
14/// This `enum` is constructed from the [`entry`] method on [`BTreeMap`].
15///
16/// [`entry`]: BTreeMap::entry
17#[stable(feature = "rust1", since = "1.0.0")]
18#[cfg_attr(not(test), rustc_diagnostic_item = "BTreeEntry")]
19pub enum Entry<
20    'a,
21    K: 'a,
22    V: 'a,
23    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
24> {
25    /// A vacant entry.
26    #[stable(feature = "rust1", since = "1.0.0")]
27    Vacant(#[stable(feature = "rust1", since = "1.0.0")] VacantEntry<'a, K, V, A>),
28
29    /// An occupied entry.
30    #[stable(feature = "rust1", since = "1.0.0")]
31    Occupied(#[stable(feature = "rust1", since = "1.0.0")] OccupiedEntry<'a, K, V, A>),
32}
33
34#[stable(feature = "debug_btree_map", since = "1.12.0")]
35impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for Entry<'_, K, V, A> {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        match *self {
38            Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
39            Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
40        }
41    }
42}
43
44/// A view into a vacant entry in a `BTreeMap`.
45/// It is part of the [`Entry`] enum.
46#[stable(feature = "rust1", since = "1.0.0")]
47pub struct VacantEntry<
48    'a,
49    K,
50    V,
51    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
52> {
53    pub(super) key: K,
54    /// `None` for a (empty) map without root
55    pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
56    pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
57
58    /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
59    pub(super) alloc: A,
60
61    // Be invariant in `K` and `V`
62    pub(super) _marker: PhantomData<&'a mut (K, V)>,
63}
64
65#[stable(feature = "debug_btree_map", since = "1.12.0")]
66impl<K: Debug + Ord, V, A: Allocator + Clone> Debug for VacantEntry<'_, K, V, A> {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        f.debug_tuple("VacantEntry").field(self.key()).finish()
69    }
70}
71
72/// A view into an occupied entry in a `BTreeMap`.
73/// It is part of the [`Entry`] enum.
74#[stable(feature = "rust1", since = "1.0.0")]
75pub struct OccupiedEntry<
76    'a,
77    K,
78    V,
79    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
80> {
81    pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
82    pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, A>>,
83
84    /// The BTreeMap will outlive this IntoIter so we don't care about drop order for `alloc`.
85    pub(super) alloc: A,
86
87    // Be invariant in `K` and `V`
88    pub(super) _marker: PhantomData<&'a mut (K, V)>,
89}
90
91#[stable(feature = "debug_btree_map", since = "1.12.0")]
92impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedEntry<'_, K, V, A> {
93    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
94        f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish()
95    }
96}
97
98/// The error returned by [`try_insert`](BTreeMap::try_insert) when the key already exists.
99///
100/// Contains the occupied entry, and the value that was not inserted.
101#[unstable(feature = "map_try_insert", issue = "82766")]
102pub struct OccupiedError<'a, K: 'a, V: 'a, A: Allocator + Clone = Global> {
103    /// The entry in the map that was already occupied.
104    pub entry: OccupiedEntry<'a, K, V, A>,
105    /// The value which was not inserted, because the entry was already occupied.
106    pub value: V,
107}
108
109#[unstable(feature = "map_try_insert", issue = "82766")]
110impl<K: Debug + Ord, V: Debug, A: Allocator + Clone> Debug for OccupiedError<'_, K, V, A> {
111    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112        f.debug_struct("OccupiedError")
113            .field("key", self.entry.key())
114            .field("old_value", self.entry.get())
115            .field("new_value", &self.value)
116            .finish()
117    }
118}
119
120#[unstable(feature = "map_try_insert", issue = "82766")]
121impl<'a, K: Debug + Ord, V: Debug, A: Allocator + Clone> fmt::Display
122    for OccupiedError<'a, K, V, A>
123{
124    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125        write!(
126            f,
127            "failed to insert {:?}, key {:?} already exists with value {:?}",
128            self.value,
129            self.entry.key(),
130            self.entry.get(),
131        )
132    }
133}
134
135#[unstable(feature = "map_try_insert", issue = "82766")]
136impl<'a, K: core::fmt::Debug + Ord, V: core::fmt::Debug> core::error::Error
137    for crate::collections::btree_map::OccupiedError<'a, K, V>
138{
139}
140
141impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
142    /// Ensures a value is in the entry by inserting the default if empty, and returns
143    /// a mutable reference to the value in the entry.
144    ///
145    /// # Examples
146    ///
147    /// ```
148    /// use std::collections::BTreeMap;
149    ///
150    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
151    /// map.entry("poneyland").or_insert(12);
152    ///
153    /// assert_eq!(map["poneyland"], 12);
154    /// ```
155    #[stable(feature = "rust1", since = "1.0.0")]
156    pub fn or_insert(self, default: V) -> &'a mut V {
157        match self {
158            Occupied(entry) => entry.into_mut(),
159            Vacant(entry) => entry.insert(default),
160        }
161    }
162
163    /// Ensures a value is in the entry by inserting the result of the default function if empty,
164    /// and returns a mutable reference to the value in the entry.
165    ///
166    /// # Examples
167    ///
168    /// ```
169    /// use std::collections::BTreeMap;
170    ///
171    /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
172    /// let s = "hoho".to_string();
173    ///
174    /// map.entry("poneyland").or_insert_with(|| s);
175    ///
176    /// assert_eq!(map["poneyland"], "hoho".to_string());
177    /// ```
178    #[stable(feature = "rust1", since = "1.0.0")]
179    pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
180        match self {
181            Occupied(entry) => entry.into_mut(),
182            Vacant(entry) => entry.insert(default()),
183        }
184    }
185
186    /// Ensures a value is in the entry by inserting, if empty, the result of the default function.
187    ///
188    /// This method allows for generating key-derived values for insertion by providing the default
189    /// function a reference to the key that was moved during the `.entry(key)` method call.
190    ///
191    /// The reference to the moved key is provided so that cloning or copying the key is
192    /// unnecessary, unlike with `.or_insert_with(|| ... )`.
193    ///
194    /// # Examples
195    ///
196    /// ```
197    /// use std::collections::BTreeMap;
198    ///
199    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
200    ///
201    /// map.entry("poneyland").or_insert_with_key(|key| key.chars().count());
202    ///
203    /// assert_eq!(map["poneyland"], 9);
204    /// ```
205    #[inline]
206    #[stable(feature = "or_insert_with_key", since = "1.50.0")]
207    pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
208        match self {
209            Occupied(entry) => entry.into_mut(),
210            Vacant(entry) => {
211                let value = default(entry.key());
212                entry.insert(value)
213            }
214        }
215    }
216
217    /// Returns a reference to this entry's key.
218    ///
219    /// # Examples
220    ///
221    /// ```
222    /// use std::collections::BTreeMap;
223    ///
224    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
225    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
226    /// ```
227    #[stable(feature = "map_entry_keys", since = "1.10.0")]
228    pub fn key(&self) -> &K {
229        match *self {
230            Occupied(ref entry) => entry.key(),
231            Vacant(ref entry) => entry.key(),
232        }
233    }
234
235    /// Provides in-place mutable access to an occupied entry before any
236    /// potential inserts into the map.
237    ///
238    /// # Examples
239    ///
240    /// ```
241    /// use std::collections::BTreeMap;
242    ///
243    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
244    ///
245    /// map.entry("poneyland")
246    ///    .and_modify(|e| { *e += 1 })
247    ///    .or_insert(42);
248    /// assert_eq!(map["poneyland"], 42);
249    ///
250    /// map.entry("poneyland")
251    ///    .and_modify(|e| { *e += 1 })
252    ///    .or_insert(42);
253    /// assert_eq!(map["poneyland"], 43);
254    /// ```
255    #[stable(feature = "entry_and_modify", since = "1.26.0")]
256    pub fn and_modify<F>(self, f: F) -> Self
257    where
258        F: FnOnce(&mut V),
259    {
260        match self {
261            Occupied(mut entry) => {
262                f(entry.get_mut());
263                Occupied(entry)
264            }
265            Vacant(entry) => Vacant(entry),
266        }
267    }
268
269    /// Sets the value of the entry, and returns an `OccupiedEntry`.
270    ///
271    /// # Examples
272    ///
273    /// ```
274    /// #![feature(btree_entry_insert)]
275    /// use std::collections::BTreeMap;
276    ///
277    /// let mut map: BTreeMap<&str, String> = BTreeMap::new();
278    /// let entry = map.entry("poneyland").insert_entry("hoho".to_string());
279    ///
280    /// assert_eq!(entry.key(), &"poneyland");
281    /// ```
282    #[inline]
283    #[unstable(feature = "btree_entry_insert", issue = "65225")]
284    pub fn insert_entry(self, value: V) -> OccupiedEntry<'a, K, V, A> {
285        match self {
286            Occupied(mut entry) => {
287                entry.insert(value);
288                entry
289            }
290            Vacant(entry) => entry.insert_entry(value),
291        }
292    }
293}
294
295impl<'a, K: Ord, V: Default, A: Allocator + Clone> Entry<'a, K, V, A> {
296    #[stable(feature = "entry_or_default", since = "1.28.0")]
297    /// Ensures a value is in the entry by inserting the default value if empty,
298    /// and returns a mutable reference to the value in the entry.
299    ///
300    /// # Examples
301    ///
302    /// ```
303    /// use std::collections::BTreeMap;
304    ///
305    /// let mut map: BTreeMap<&str, Option<usize>> = BTreeMap::new();
306    /// map.entry("poneyland").or_default();
307    ///
308    /// assert_eq!(map["poneyland"], None);
309    /// ```
310    pub fn or_default(self) -> &'a mut V {
311        match self {
312            Occupied(entry) => entry.into_mut(),
313            Vacant(entry) => entry.insert(Default::default()),
314        }
315    }
316}
317
318impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> {
319    /// Gets a reference to the key that would be used when inserting a value
320    /// through the VacantEntry.
321    ///
322    /// # Examples
323    ///
324    /// ```
325    /// use std::collections::BTreeMap;
326    ///
327    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
328    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
329    /// ```
330    #[stable(feature = "map_entry_keys", since = "1.10.0")]
331    pub fn key(&self) -> &K {
332        &self.key
333    }
334
335    /// Take ownership of the key.
336    ///
337    /// # Examples
338    ///
339    /// ```
340    /// use std::collections::BTreeMap;
341    /// use std::collections::btree_map::Entry;
342    ///
343    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
344    ///
345    /// if let Entry::Vacant(v) = map.entry("poneyland") {
346    ///     v.into_key();
347    /// }
348    /// ```
349    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
350    pub fn into_key(self) -> K {
351        self.key
352    }
353
354    /// Sets the value of the entry with the `VacantEntry`'s key,
355    /// and returns a mutable reference to it.
356    ///
357    /// # Examples
358    ///
359    /// ```
360    /// use std::collections::BTreeMap;
361    /// use std::collections::btree_map::Entry;
362    ///
363    /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
364    ///
365    /// if let Entry::Vacant(o) = map.entry("poneyland") {
366    ///     o.insert(37);
367    /// }
368    /// assert_eq!(map["poneyland"], 37);
369    /// ```
370    #[stable(feature = "rust1", since = "1.0.0")]
371    #[rustc_confusables("push", "put")]
372    pub fn insert(self, value: V) -> &'a mut V {
373        self.insert_entry(value).into_mut()
374    }
375
376    /// Sets the value of the entry with the `VacantEntry`'s key,
377    /// and returns an `OccupiedEntry`.
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// #![feature(btree_entry_insert)]
383    /// use std::collections::BTreeMap;
384    /// use std::collections::btree_map::Entry;
385    ///
386    /// let mut map: BTreeMap<&str, u32> = BTreeMap::new();
387    ///
388    /// if let Entry::Vacant(o) = map.entry("poneyland") {
389    ///     let entry = o.insert_entry(37);
390    ///     assert_eq!(entry.get(), &37);
391    /// }
392    /// assert_eq!(map["poneyland"], 37);
393    /// ```
394    #[unstable(feature = "btree_entry_insert", issue = "65225")]
395    pub fn insert_entry(mut self, value: V) -> OccupiedEntry<'a, K, V, A> {
396        let handle = match self.handle {
397            None => {
398                // SAFETY: There is no tree yet so no reference to it exists.
399                let map = unsafe { self.dormant_map.reborrow() };
400                let root = map.root.insert(NodeRef::new_leaf(self.alloc.clone()).forget_type());
401                // SAFETY: We *just* created the root as a leaf, and we're
402                // stacking the new handle on the original borrow lifetime.
403                unsafe {
404                    let mut leaf = root.borrow_mut().cast_to_leaf_unchecked();
405                    leaf.push_with_handle(self.key, value)
406                }
407            }
408            Some(handle) => handle.insert_recursing(self.key, value, self.alloc.clone(), |ins| {
409                drop(ins.left);
410                // SAFETY: Pushing a new root node doesn't invalidate
411                // handles to existing nodes.
412                let map = unsafe { self.dormant_map.reborrow() };
413                let root = map.root.as_mut().unwrap(); // same as ins.left
414                root.push_internal_level(self.alloc.clone()).push(ins.kv.0, ins.kv.1, ins.right)
415            }),
416        };
417
418        // SAFETY: modifying the length doesn't invalidate handles to existing nodes.
419        unsafe { self.dormant_map.reborrow().length += 1 };
420
421        OccupiedEntry {
422            handle: handle.forget_node_type(),
423            dormant_map: self.dormant_map,
424            alloc: self.alloc,
425            _marker: PhantomData,
426        }
427    }
428}
429
430impl<'a, K: Ord, V, A: Allocator + Clone> OccupiedEntry<'a, K, V, A> {
431    /// Gets a reference to the key in the entry.
432    ///
433    /// # Examples
434    ///
435    /// ```
436    /// use std::collections::BTreeMap;
437    ///
438    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
439    /// map.entry("poneyland").or_insert(12);
440    /// assert_eq!(map.entry("poneyland").key(), &"poneyland");
441    /// ```
442    #[must_use]
443    #[stable(feature = "map_entry_keys", since = "1.10.0")]
444    pub fn key(&self) -> &K {
445        self.handle.reborrow().into_kv().0
446    }
447
448    /// Converts the entry into a reference to its key.
449    pub(crate) fn into_key(self) -> &'a K {
450        self.handle.into_kv_mut().0
451    }
452
453    /// Take ownership of the key and value from the map.
454    ///
455    /// # Examples
456    ///
457    /// ```
458    /// use std::collections::BTreeMap;
459    /// use std::collections::btree_map::Entry;
460    ///
461    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
462    /// map.entry("poneyland").or_insert(12);
463    ///
464    /// if let Entry::Occupied(o) = map.entry("poneyland") {
465    ///     // We delete the entry from the map.
466    ///     o.remove_entry();
467    /// }
468    ///
469    /// // If now try to get the value, it will panic:
470    /// // println!("{}", map["poneyland"]);
471    /// ```
472    #[stable(feature = "map_entry_recover_keys2", since = "1.12.0")]
473    pub fn remove_entry(self) -> (K, V) {
474        self.remove_kv()
475    }
476
477    /// Gets a reference to the value in the entry.
478    ///
479    /// # Examples
480    ///
481    /// ```
482    /// use std::collections::BTreeMap;
483    /// use std::collections::btree_map::Entry;
484    ///
485    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
486    /// map.entry("poneyland").or_insert(12);
487    ///
488    /// if let Entry::Occupied(o) = map.entry("poneyland") {
489    ///     assert_eq!(o.get(), &12);
490    /// }
491    /// ```
492    #[must_use]
493    #[stable(feature = "rust1", since = "1.0.0")]
494    pub fn get(&self) -> &V {
495        self.handle.reborrow().into_kv().1
496    }
497
498    /// Gets a mutable reference to the value in the entry.
499    ///
500    /// If you need a reference to the `OccupiedEntry` that may outlive the
501    /// destruction of the `Entry` value, see [`into_mut`].
502    ///
503    /// [`into_mut`]: OccupiedEntry::into_mut
504    ///
505    /// # Examples
506    ///
507    /// ```
508    /// use std::collections::BTreeMap;
509    /// use std::collections::btree_map::Entry;
510    ///
511    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
512    /// map.entry("poneyland").or_insert(12);
513    ///
514    /// assert_eq!(map["poneyland"], 12);
515    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
516    ///     *o.get_mut() += 10;
517    ///     assert_eq!(*o.get(), 22);
518    ///
519    ///     // We can use the same Entry multiple times.
520    ///     *o.get_mut() += 2;
521    /// }
522    /// assert_eq!(map["poneyland"], 24);
523    /// ```
524    #[stable(feature = "rust1", since = "1.0.0")]
525    pub fn get_mut(&mut self) -> &mut V {
526        self.handle.kv_mut().1
527    }
528
529    /// Converts the entry into a mutable reference to its value.
530    ///
531    /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
532    ///
533    /// [`get_mut`]: OccupiedEntry::get_mut
534    ///
535    /// # Examples
536    ///
537    /// ```
538    /// use std::collections::BTreeMap;
539    /// use std::collections::btree_map::Entry;
540    ///
541    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
542    /// map.entry("poneyland").or_insert(12);
543    ///
544    /// assert_eq!(map["poneyland"], 12);
545    /// if let Entry::Occupied(o) = map.entry("poneyland") {
546    ///     *o.into_mut() += 10;
547    /// }
548    /// assert_eq!(map["poneyland"], 22);
549    /// ```
550    #[must_use = "`self` will be dropped if the result is not used"]
551    #[stable(feature = "rust1", since = "1.0.0")]
552    pub fn into_mut(self) -> &'a mut V {
553        self.handle.into_val_mut()
554    }
555
556    /// Sets the value of the entry with the `OccupiedEntry`'s key,
557    /// and returns the entry's old value.
558    ///
559    /// # Examples
560    ///
561    /// ```
562    /// use std::collections::BTreeMap;
563    /// use std::collections::btree_map::Entry;
564    ///
565    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
566    /// map.entry("poneyland").or_insert(12);
567    ///
568    /// if let Entry::Occupied(mut o) = map.entry("poneyland") {
569    ///     assert_eq!(o.insert(15), 12);
570    /// }
571    /// assert_eq!(map["poneyland"], 15);
572    /// ```
573    #[stable(feature = "rust1", since = "1.0.0")]
574    #[rustc_confusables("push", "put")]
575    pub fn insert(&mut self, value: V) -> V {
576        mem::replace(self.get_mut(), value)
577    }
578
579    /// Takes the value of the entry out of the map, and returns it.
580    ///
581    /// # Examples
582    ///
583    /// ```
584    /// use std::collections::BTreeMap;
585    /// use std::collections::btree_map::Entry;
586    ///
587    /// let mut map: BTreeMap<&str, usize> = BTreeMap::new();
588    /// map.entry("poneyland").or_insert(12);
589    ///
590    /// if let Entry::Occupied(o) = map.entry("poneyland") {
591    ///     assert_eq!(o.remove(), 12);
592    /// }
593    /// // If we try to get "poneyland"'s value, it'll panic:
594    /// // println!("{}", map["poneyland"]);
595    /// ```
596    #[stable(feature = "rust1", since = "1.0.0")]
597    #[rustc_confusables("delete", "take")]
598    pub fn remove(self) -> V {
599        self.remove_kv().1
600    }
601
602    // Body of `remove_entry`, probably separate because the name reflects the returned pair.
603    pub(super) fn remove_kv(self) -> (K, V) {
604        let mut emptied_internal_root = false;
605        let (old_kv, _) =
606            self.handle.remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
607        // SAFETY: we consumed the intermediate root borrow, `self.handle`.
608        let map = unsafe { self.dormant_map.awaken() };
609        map.length -= 1;
610        if emptied_internal_root {
611            let root = map.root.as_mut().unwrap();
612            root.pop_internal_level(self.alloc);
613        }
614        old_kv
615    }
616}