1 | use core::fmt::{self, Debug}; |
2 | |
3 | use Entry::*; |
4 | |
5 | use super::{SetValZST, map}; |
6 | use 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" )] |
42 | pub 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" )] |
87 | impl<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: &VacantEntry<'_, T, A>) => f.debug_tuple(name:"Entry" ).field(v).finish(), |
91 | Occupied(ref o: &OccupiedEntry<'_, T, A>) => f.debug_tuple(name:"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" )] |
133 | pub 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" )] |
142 | impl<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(name:"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" )] |
175 | pub 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" )] |
184 | impl<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(name:"VacantEntry" ).field(self.get()).finish() |
187 | } |
188 | } |
189 | |
190 | impl<'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 | |
269 | impl<'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 | |
319 | impl<'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 | } |
389 | |