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}