alloc/collections/btree/set/
entry.rs

1use core::fmt::{self, Debug};
2
3use Entry::*;
4
5use super::{SetValZST, map};
6use crate::alloc::{Allocator, Global};
7
8/// A view into a single entry in a set, which may either be vacant or occupied.
9///
10/// This `enum` is constructed from the [`entry`] method on [`BTreeSet`].
11///
12/// [`BTreeSet`]: super::BTreeSet
13/// [`entry`]: super::BTreeSet::entry
14///
15/// # Examples
16///
17/// ```
18/// #![feature(btree_set_entry)]
19///
20/// use std::collections::btree_set::BTreeSet;
21///
22/// let mut set = BTreeSet::new();
23/// set.extend(["a", "b", "c"]);
24/// assert_eq!(set.len(), 3);
25///
26/// // Existing value (insert)
27/// let entry = set.entry("a");
28/// let _raw_o = entry.insert();
29/// assert_eq!(set.len(), 3);
30/// // Nonexistent value (insert)
31/// set.entry("d").insert();
32///
33/// // Existing value (or_insert)
34/// set.entry("b").or_insert();
35/// // Nonexistent value (or_insert)
36/// set.entry("e").or_insert();
37///
38/// println!("Our BTreeSet: {:?}", set);
39/// assert!(set.iter().eq(&["a", "b", "c", "d", "e"]));
40/// ```
41#[unstable(feature = "btree_set_entry", issue = "133549")]
42pub enum Entry<
43    'a,
44    T,
45    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
46> {
47    /// An occupied entry.
48    ///
49    /// # Examples
50    ///
51    /// ```
52    /// #![feature(btree_set_entry)]
53    ///
54    /// use std::collections::btree_set::{Entry, BTreeSet};
55    ///
56    /// let mut set = BTreeSet::from(["a", "b"]);
57    ///
58    /// match set.entry("a") {
59    ///     Entry::Vacant(_) => unreachable!(),
60    ///     Entry::Occupied(_) => { }
61    /// }
62    /// ```
63    #[unstable(feature = "btree_set_entry", issue = "133549")]
64    Occupied(OccupiedEntry<'a, T, A>),
65
66    /// A vacant entry.
67    ///
68    /// # Examples
69    ///
70    /// ```
71    /// #![feature(btree_set_entry)]
72    ///
73    /// use std::collections::btree_set::{Entry, BTreeSet};
74    ///
75    /// let mut set = BTreeSet::new();
76    ///
77    /// match set.entry("a") {
78    ///     Entry::Occupied(_) => unreachable!(),
79    ///     Entry::Vacant(_) => { }
80    /// }
81    /// ```
82    #[unstable(feature = "btree_set_entry", issue = "133549")]
83    Vacant(VacantEntry<'a, T, A>),
84}
85
86#[unstable(feature = "btree_set_entry", issue = "133549")]
87impl<T: Debug + Ord, A: Allocator + Clone> Debug for Entry<'_, T, A> {
88    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
89        match *self {
90            Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
91            Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
92        }
93    }
94}
95
96/// A view into an occupied entry in a `BTreeSet`.
97/// It is part of the [`Entry`] enum.
98///
99/// # Examples
100///
101/// ```
102/// #![feature(btree_set_entry)]
103///
104/// use std::collections::btree_set::{Entry, BTreeSet};
105///
106/// let mut set = BTreeSet::new();
107/// set.extend(["a", "b", "c"]);
108///
109/// let _entry_o = set.entry("a").insert();
110/// assert_eq!(set.len(), 3);
111///
112/// // Existing key
113/// match set.entry("a") {
114///     Entry::Vacant(_) => unreachable!(),
115///     Entry::Occupied(view) => {
116///         assert_eq!(view.get(), &"a");
117///     }
118/// }
119///
120/// assert_eq!(set.len(), 3);
121///
122/// // Existing key (take)
123/// match set.entry("c") {
124///     Entry::Vacant(_) => unreachable!(),
125///     Entry::Occupied(view) => {
126///         assert_eq!(view.remove(), "c");
127///     }
128/// }
129/// assert_eq!(set.get(&"c"), None);
130/// assert_eq!(set.len(), 2);
131/// ```
132#[unstable(feature = "btree_set_entry", issue = "133549")]
133pub struct OccupiedEntry<
134    'a,
135    T,
136    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
137> {
138    pub(super) inner: map::OccupiedEntry<'a, T, SetValZST, A>,
139}
140
141#[unstable(feature = "btree_set_entry", issue = "133549")]
142impl<T: Debug + Ord, A: Allocator + Clone> Debug for OccupiedEntry<'_, T, A> {
143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144        f.debug_struct("OccupiedEntry").field("value", self.get()).finish()
145    }
146}
147
148/// A view into a vacant entry in a `BTreeSet`.
149/// It is part of the [`Entry`] enum.
150///
151/// # Examples
152///
153/// ```
154/// #![feature(btree_set_entry)]
155///
156/// use std::collections::btree_set::{Entry, BTreeSet};
157///
158/// let mut set = BTreeSet::<&str>::new();
159///
160/// let entry_v = match set.entry("a") {
161///     Entry::Vacant(view) => view,
162///     Entry::Occupied(_) => unreachable!(),
163/// };
164/// entry_v.insert();
165/// assert!(set.contains("a") && set.len() == 1);
166///
167/// // Nonexistent key (insert)
168/// match set.entry("b") {
169///     Entry::Vacant(view) => view.insert(),
170///     Entry::Occupied(_) => unreachable!(),
171/// }
172/// assert!(set.contains("b") && set.len() == 2);
173/// ```
174#[unstable(feature = "btree_set_entry", issue = "133549")]
175pub struct VacantEntry<
176    'a,
177    T,
178    #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator + Clone = Global,
179> {
180    pub(super) inner: map::VacantEntry<'a, T, SetValZST, A>,
181}
182
183#[unstable(feature = "btree_set_entry", issue = "133549")]
184impl<T: Debug + Ord, A: Allocator + Clone> Debug for VacantEntry<'_, T, A> {
185    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186        f.debug_tuple("VacantEntry").field(self.get()).finish()
187    }
188}
189
190impl<'a, T: Ord, A: Allocator + Clone> Entry<'a, T, A> {
191    /// Sets the value of the entry, and returns an `OccupiedEntry`.
192    ///
193    /// # Examples
194    ///
195    /// ```
196    /// #![feature(btree_set_entry)]
197    ///
198    /// use std::collections::BTreeSet;
199    ///
200    /// let mut set = BTreeSet::new();
201    /// let entry = set.entry("horseyland").insert();
202    ///
203    /// assert_eq!(entry.get(), &"horseyland");
204    /// ```
205    #[inline]
206    #[unstable(feature = "btree_set_entry", issue = "133549")]
207    pub fn insert(self) -> OccupiedEntry<'a, T, A> {
208        match self {
209            Occupied(entry) => entry,
210            Vacant(entry) => entry.insert_entry(),
211        }
212    }
213
214    /// Ensures a value is in the entry by inserting if it was vacant.
215    ///
216    /// # Examples
217    ///
218    /// ```
219    /// #![feature(btree_set_entry)]
220    ///
221    /// use std::collections::BTreeSet;
222    ///
223    /// let mut set = BTreeSet::new();
224    ///
225    /// // nonexistent key
226    /// set.entry("poneyland").or_insert();
227    /// assert!(set.contains("poneyland"));
228    ///
229    /// // existing key
230    /// set.entry("poneyland").or_insert();
231    /// assert!(set.contains("poneyland"));
232    /// assert_eq!(set.len(), 1);
233    /// ```
234    #[inline]
235    #[unstable(feature = "btree_set_entry", issue = "133549")]
236    pub fn or_insert(self) {
237        if let Vacant(entry) = self {
238            entry.insert();
239        }
240    }
241
242    /// Returns a reference to this entry's value.
243    ///
244    /// # Examples
245    ///
246    /// ```
247    /// #![feature(btree_set_entry)]
248    ///
249    /// use std::collections::BTreeSet;
250    ///
251    /// let mut set = BTreeSet::new();
252    /// set.entry("poneyland").or_insert();
253    ///
254    /// // existing key
255    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
256    /// // nonexistent key
257    /// assert_eq!(set.entry("horseland").get(), &"horseland");
258    /// ```
259    #[inline]
260    #[unstable(feature = "btree_set_entry", issue = "133549")]
261    pub fn get(&self) -> &T {
262        match *self {
263            Occupied(ref entry) => entry.get(),
264            Vacant(ref entry) => entry.get(),
265        }
266    }
267}
268
269impl<'a, T: Ord, A: Allocator + Clone> OccupiedEntry<'a, T, A> {
270    /// Gets a reference to the value in the entry.
271    ///
272    /// # Examples
273    ///
274    /// ```
275    /// #![feature(btree_set_entry)]
276    ///
277    /// use std::collections::btree_set::{Entry, BTreeSet};
278    ///
279    /// let mut set = BTreeSet::new();
280    /// set.entry("poneyland").or_insert();
281    ///
282    /// match set.entry("poneyland") {
283    ///     Entry::Vacant(_) => panic!(),
284    ///     Entry::Occupied(entry) => assert_eq!(entry.get(), &"poneyland"),
285    /// }
286    /// ```
287    #[inline]
288    #[unstable(feature = "btree_set_entry", issue = "133549")]
289    pub fn get(&self) -> &T {
290        self.inner.key()
291    }
292
293    /// Takes the value out of the entry, and returns it.
294    ///
295    /// # Examples
296    ///
297    /// ```
298    /// #![feature(btree_set_entry)]
299    ///
300    /// use std::collections::BTreeSet;
301    /// use std::collections::btree_set::Entry;
302    ///
303    /// let mut set = BTreeSet::new();
304    /// set.entry("poneyland").or_insert();
305    ///
306    /// if let Entry::Occupied(o) = set.entry("poneyland") {
307    ///     assert_eq!(o.remove(), "poneyland");
308    /// }
309    ///
310    /// assert_eq!(set.contains("poneyland"), false);
311    /// ```
312    #[inline]
313    #[unstable(feature = "btree_set_entry", issue = "133549")]
314    pub fn remove(self) -> T {
315        self.inner.remove_entry().0
316    }
317}
318
319impl<'a, T: Ord, A: Allocator + Clone> VacantEntry<'a, T, A> {
320    /// Gets a reference to the value that would be used when inserting
321    /// through the `VacantEntry`.
322    ///
323    /// # Examples
324    ///
325    /// ```
326    /// #![feature(btree_set_entry)]
327    ///
328    /// use std::collections::BTreeSet;
329    ///
330    /// let mut set = BTreeSet::new();
331    /// assert_eq!(set.entry("poneyland").get(), &"poneyland");
332    /// ```
333    #[inline]
334    #[unstable(feature = "btree_set_entry", issue = "133549")]
335    pub fn get(&self) -> &T {
336        self.inner.key()
337    }
338
339    /// Take ownership of the value.
340    ///
341    /// # Examples
342    ///
343    /// ```
344    /// #![feature(btree_set_entry)]
345    ///
346    /// use std::collections::btree_set::{Entry, BTreeSet};
347    ///
348    /// let mut set = BTreeSet::new();
349    ///
350    /// match set.entry("poneyland") {
351    ///     Entry::Occupied(_) => panic!(),
352    ///     Entry::Vacant(v) => assert_eq!(v.into_value(), "poneyland"),
353    /// }
354    /// ```
355    #[inline]
356    #[unstable(feature = "btree_set_entry", issue = "133549")]
357    pub fn into_value(self) -> T {
358        self.inner.into_key()
359    }
360
361    /// Sets the value of the entry with the VacantEntry's value.
362    ///
363    /// # Examples
364    ///
365    /// ```
366    /// #![feature(btree_set_entry)]
367    ///
368    /// use std::collections::BTreeSet;
369    /// use std::collections::btree_set::Entry;
370    ///
371    /// let mut set = BTreeSet::new();
372    ///
373    /// if let Entry::Vacant(o) = set.entry("poneyland") {
374    ///     o.insert();
375    /// }
376    /// assert!(set.contains("poneyland"));
377    /// ```
378    #[inline]
379    #[unstable(feature = "btree_set_entry", issue = "133549")]
380    pub fn insert(self) {
381        self.inner.insert(SetValZST);
382    }
383
384    #[inline]
385    fn insert_entry(self) -> OccupiedEntry<'a, T, A> {
386        OccupiedEntry { inner: self.inner.insert_entry(SetValZST) }
387    }
388}