]>
Commit | Line | Data |
---|---|---|
5099ac24 FG |
1 | use self::RustcEntry::*; |
2 | use crate::map::{make_insert_hash, Drain, HashMap, IntoIter, Iter, IterMut}; | |
3 | use crate::raw::{Allocator, Bucket, Global, RawTable}; | |
4 | use core::fmt::{self, Debug}; | |
5 | use core::hash::{BuildHasher, Hash}; | |
6 | use core::mem; | |
7 | ||
8 | impl<K, V, S, A> HashMap<K, V, S, A> | |
9 | where | |
10 | K: Eq + Hash, | |
11 | S: BuildHasher, | |
12 | A: Allocator + Clone, | |
13 | { | |
14 | /// Gets the given key's corresponding entry in the map for in-place manipulation. | |
15 | /// | |
16 | /// # Examples | |
17 | /// | |
18 | /// ``` | |
19 | /// use hashbrown::HashMap; | |
20 | /// | |
21 | /// let mut letters = HashMap::new(); | |
22 | /// | |
23 | /// for ch in "a short treatise on fungi".chars() { | |
24 | /// let counter = letters.rustc_entry(ch).or_insert(0); | |
25 | /// *counter += 1; | |
26 | /// } | |
27 | /// | |
28 | /// assert_eq!(letters[&'s'], 2); | |
29 | /// assert_eq!(letters[&'t'], 3); | |
30 | /// assert_eq!(letters[&'u'], 1); | |
31 | /// assert_eq!(letters.get(&'y'), None); | |
32 | /// ``` | |
33 | #[cfg_attr(feature = "inline-more", inline)] | |
34 | pub fn rustc_entry(&mut self, key: K) -> RustcEntry<'_, K, V, A> { | |
35 | let hash = make_insert_hash(&self.hash_builder, &key); | |
36 | if let Some(elem) = self.table.find(hash, |q| q.0.eq(&key)) { | |
37 | RustcEntry::Occupied(RustcOccupiedEntry { | |
38 | key: Some(key), | |
39 | elem, | |
40 | table: &mut self.table, | |
41 | }) | |
42 | } else { | |
43 | // Ideally we would put this in VacantEntry::insert, but Entry is not | |
44 | // generic over the BuildHasher and adding a generic parameter would be | |
45 | // a breaking change. | |
46 | self.reserve(1); | |
47 | ||
48 | RustcEntry::Vacant(RustcVacantEntry { | |
49 | hash, | |
50 | key, | |
51 | table: &mut self.table, | |
52 | }) | |
53 | } | |
54 | } | |
55 | } | |
56 | ||
57 | /// A view into a single entry in a map, which may either be vacant or occupied. | |
58 | /// | |
59 | /// This `enum` is constructed from the [`entry`] method on [`HashMap`]. | |
60 | /// | |
61 | /// [`HashMap`]: struct.HashMap.html | |
62 | /// [`entry`]: struct.HashMap.html#method.rustc_entry | |
63 | pub enum RustcEntry<'a, K, V, A = Global> | |
64 | where | |
65 | A: Allocator + Clone, | |
66 | { | |
67 | /// An occupied entry. | |
68 | Occupied(RustcOccupiedEntry<'a, K, V, A>), | |
69 | ||
70 | /// A vacant entry. | |
71 | Vacant(RustcVacantEntry<'a, K, V, A>), | |
72 | } | |
73 | ||
74 | impl<K: Debug, V: Debug, A: Allocator + Clone> Debug for RustcEntry<'_, K, V, A> { | |
75 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
76 | match *self { | |
77 | Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(), | |
78 | Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(), | |
79 | } | |
80 | } | |
81 | } | |
82 | ||
83 | /// A view into an occupied entry in a `HashMap`. | |
84 | /// It is part of the [`RustcEntry`] enum. | |
85 | /// | |
86 | /// [`RustcEntry`]: enum.RustcEntry.html | |
87 | pub struct RustcOccupiedEntry<'a, K, V, A = Global> | |
88 | where | |
89 | A: Allocator + Clone, | |
90 | { | |
91 | key: Option<K>, | |
92 | elem: Bucket<(K, V)>, | |
93 | table: &'a mut RawTable<(K, V), A>, | |
94 | } | |
95 | ||
96 | unsafe impl<K, V, A> Send for RustcOccupiedEntry<'_, K, V, A> | |
97 | where | |
98 | K: Send, | |
99 | V: Send, | |
100 | A: Allocator + Clone + Send, | |
101 | { | |
102 | } | |
103 | unsafe impl<K, V, A> Sync for RustcOccupiedEntry<'_, K, V, A> | |
104 | where | |
105 | K: Sync, | |
106 | V: Sync, | |
107 | A: Allocator + Clone + Sync, | |
108 | { | |
109 | } | |
110 | ||
111 | impl<K: Debug, V: Debug, A: Allocator + Clone> Debug for RustcOccupiedEntry<'_, K, V, A> { | |
112 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
113 | f.debug_struct("OccupiedEntry") | |
114 | .field("key", self.key()) | |
115 | .field("value", self.get()) | |
116 | .finish() | |
117 | } | |
118 | } | |
119 | ||
120 | /// A view into a vacant entry in a `HashMap`. | |
121 | /// It is part of the [`RustcEntry`] enum. | |
122 | /// | |
123 | /// [`RustcEntry`]: enum.RustcEntry.html | |
124 | pub struct RustcVacantEntry<'a, K, V, A = Global> | |
125 | where | |
126 | A: Allocator + Clone, | |
127 | { | |
128 | hash: u64, | |
129 | key: K, | |
130 | table: &'a mut RawTable<(K, V), A>, | |
131 | } | |
132 | ||
133 | impl<K: Debug, V, A: Allocator + Clone> Debug for RustcVacantEntry<'_, K, V, A> { | |
134 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | |
135 | f.debug_tuple("VacantEntry").field(self.key()).finish() | |
136 | } | |
137 | } | |
138 | ||
139 | impl<'a, K, V, A: Allocator + Clone> RustcEntry<'a, K, V, A> { | |
140 | /// Sets the value of the entry, and returns a RustcOccupiedEntry. | |
141 | /// | |
142 | /// # Examples | |
143 | /// | |
144 | /// ``` | |
145 | /// use hashbrown::HashMap; | |
146 | /// | |
147 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
148 | /// let entry = map.entry("horseyland").insert(37); | |
149 | /// | |
150 | /// assert_eq!(entry.key(), &"horseyland"); | |
151 | /// ``` | |
152 | pub fn insert(self, value: V) -> RustcOccupiedEntry<'a, K, V, A> { | |
153 | match self { | |
154 | Vacant(entry) => entry.insert_entry(value), | |
155 | Occupied(mut entry) => { | |
156 | entry.insert(value); | |
157 | entry | |
158 | } | |
159 | } | |
160 | } | |
161 | ||
162 | /// Ensures a value is in the entry by inserting the default if empty, and returns | |
163 | /// a mutable reference to the value in the entry. | |
164 | /// | |
165 | /// # Examples | |
166 | /// | |
167 | /// ``` | |
168 | /// use hashbrown::HashMap; | |
169 | /// | |
170 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
171 | /// | |
172 | /// map.rustc_entry("poneyland").or_insert(3); | |
173 | /// assert_eq!(map["poneyland"], 3); | |
174 | /// | |
175 | /// *map.rustc_entry("poneyland").or_insert(10) *= 2; | |
176 | /// assert_eq!(map["poneyland"], 6); | |
177 | /// ``` | |
178 | #[cfg_attr(feature = "inline-more", inline)] | |
179 | pub fn or_insert(self, default: V) -> &'a mut V | |
180 | where | |
181 | K: Hash, | |
182 | { | |
183 | match self { | |
184 | Occupied(entry) => entry.into_mut(), | |
185 | Vacant(entry) => entry.insert(default), | |
186 | } | |
187 | } | |
188 | ||
189 | /// Ensures a value is in the entry by inserting the result of the default function if empty, | |
190 | /// and returns a mutable reference to the value in the entry. | |
191 | /// | |
192 | /// # Examples | |
193 | /// | |
194 | /// ``` | |
195 | /// use hashbrown::HashMap; | |
196 | /// | |
197 | /// let mut map: HashMap<&str, String> = HashMap::new(); | |
198 | /// let s = "hoho".to_string(); | |
199 | /// | |
200 | /// map.rustc_entry("poneyland").or_insert_with(|| s); | |
201 | /// | |
202 | /// assert_eq!(map["poneyland"], "hoho".to_string()); | |
203 | /// ``` | |
204 | #[cfg_attr(feature = "inline-more", inline)] | |
205 | pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V | |
206 | where | |
207 | K: Hash, | |
208 | { | |
209 | match self { | |
210 | Occupied(entry) => entry.into_mut(), | |
211 | Vacant(entry) => entry.insert(default()), | |
212 | } | |
213 | } | |
214 | ||
215 | /// Returns a reference to this entry's key. | |
216 | /// | |
217 | /// # Examples | |
218 | /// | |
219 | /// ``` | |
220 | /// use hashbrown::HashMap; | |
221 | /// | |
222 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
223 | /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); | |
224 | /// ``` | |
225 | #[cfg_attr(feature = "inline-more", inline)] | |
226 | pub fn key(&self) -> &K { | |
227 | match *self { | |
228 | Occupied(ref entry) => entry.key(), | |
229 | Vacant(ref entry) => entry.key(), | |
230 | } | |
231 | } | |
232 | ||
233 | /// Provides in-place mutable access to an occupied entry before any | |
234 | /// potential inserts into the map. | |
235 | /// | |
236 | /// # Examples | |
237 | /// | |
238 | /// ``` | |
239 | /// use hashbrown::HashMap; | |
240 | /// | |
241 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
242 | /// | |
243 | /// map.rustc_entry("poneyland") | |
244 | /// .and_modify(|e| { *e += 1 }) | |
245 | /// .or_insert(42); | |
246 | /// assert_eq!(map["poneyland"], 42); | |
247 | /// | |
248 | /// map.rustc_entry("poneyland") | |
249 | /// .and_modify(|e| { *e += 1 }) | |
250 | /// .or_insert(42); | |
251 | /// assert_eq!(map["poneyland"], 43); | |
252 | /// ``` | |
253 | #[cfg_attr(feature = "inline-more", inline)] | |
254 | pub fn and_modify<F>(self, f: F) -> Self | |
255 | where | |
256 | F: FnOnce(&mut V), | |
257 | { | |
258 | match self { | |
259 | Occupied(mut entry) => { | |
260 | f(entry.get_mut()); | |
261 | Occupied(entry) | |
262 | } | |
263 | Vacant(entry) => Vacant(entry), | |
264 | } | |
265 | } | |
266 | } | |
267 | ||
268 | impl<'a, K, V: Default, A: Allocator + Clone> RustcEntry<'a, K, V, A> { | |
269 | /// Ensures a value is in the entry by inserting the default value if empty, | |
270 | /// and returns a mutable reference to the value in the entry. | |
271 | /// | |
272 | /// # Examples | |
273 | /// | |
274 | /// ``` | |
275 | /// # fn main() { | |
276 | /// use hashbrown::HashMap; | |
277 | /// | |
278 | /// let mut map: HashMap<&str, Option<u32>> = HashMap::new(); | |
279 | /// map.rustc_entry("poneyland").or_default(); | |
280 | /// | |
281 | /// assert_eq!(map["poneyland"], None); | |
282 | /// # } | |
283 | /// ``` | |
284 | #[cfg_attr(feature = "inline-more", inline)] | |
285 | pub fn or_default(self) -> &'a mut V | |
286 | where | |
287 | K: Hash, | |
288 | { | |
289 | match self { | |
290 | Occupied(entry) => entry.into_mut(), | |
291 | Vacant(entry) => entry.insert(Default::default()), | |
292 | } | |
293 | } | |
294 | } | |
295 | ||
296 | impl<'a, K, V, A: Allocator + Clone> RustcOccupiedEntry<'a, K, V, A> { | |
297 | /// Gets a reference to the key in the entry. | |
298 | /// | |
299 | /// # Examples | |
300 | /// | |
301 | /// ``` | |
302 | /// use hashbrown::HashMap; | |
303 | /// | |
304 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
305 | /// map.rustc_entry("poneyland").or_insert(12); | |
306 | /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); | |
307 | /// ``` | |
308 | #[cfg_attr(feature = "inline-more", inline)] | |
309 | pub fn key(&self) -> &K { | |
310 | unsafe { &self.elem.as_ref().0 } | |
311 | } | |
312 | ||
313 | /// Take the ownership of the key and value from the map. | |
314 | /// | |
315 | /// # Examples | |
316 | /// | |
317 | /// ``` | |
318 | /// use hashbrown::HashMap; | |
319 | /// use hashbrown::hash_map::RustcEntry; | |
320 | /// | |
321 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
322 | /// map.rustc_entry("poneyland").or_insert(12); | |
323 | /// | |
324 | /// if let RustcEntry::Occupied(o) = map.rustc_entry("poneyland") { | |
325 | /// // We delete the entry from the map. | |
326 | /// o.remove_entry(); | |
327 | /// } | |
328 | /// | |
329 | /// assert_eq!(map.contains_key("poneyland"), false); | |
330 | /// ``` | |
331 | #[cfg_attr(feature = "inline-more", inline)] | |
332 | pub fn remove_entry(self) -> (K, V) { | |
333 | unsafe { self.table.remove(self.elem) } | |
334 | } | |
335 | ||
336 | /// Gets a reference to the value in the entry. | |
337 | /// | |
338 | /// # Examples | |
339 | /// | |
340 | /// ``` | |
341 | /// use hashbrown::HashMap; | |
342 | /// use hashbrown::hash_map::RustcEntry; | |
343 | /// | |
344 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
345 | /// map.rustc_entry("poneyland").or_insert(12); | |
346 | /// | |
347 | /// if let RustcEntry::Occupied(o) = map.rustc_entry("poneyland") { | |
348 | /// assert_eq!(o.get(), &12); | |
349 | /// } | |
350 | /// ``` | |
351 | #[cfg_attr(feature = "inline-more", inline)] | |
352 | pub fn get(&self) -> &V { | |
353 | unsafe { &self.elem.as_ref().1 } | |
354 | } | |
355 | ||
356 | /// Gets a mutable reference to the value in the entry. | |
357 | /// | |
358 | /// If you need a reference to the `RustcOccupiedEntry` which may outlive the | |
359 | /// destruction of the `RustcEntry` value, see [`into_mut`]. | |
360 | /// | |
361 | /// [`into_mut`]: #method.into_mut | |
362 | /// | |
363 | /// # Examples | |
364 | /// | |
365 | /// ``` | |
366 | /// use hashbrown::HashMap; | |
367 | /// use hashbrown::hash_map::RustcEntry; | |
368 | /// | |
369 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
370 | /// map.rustc_entry("poneyland").or_insert(12); | |
371 | /// | |
372 | /// assert_eq!(map["poneyland"], 12); | |
373 | /// if let RustcEntry::Occupied(mut o) = map.rustc_entry("poneyland") { | |
374 | /// *o.get_mut() += 10; | |
375 | /// assert_eq!(*o.get(), 22); | |
376 | /// | |
377 | /// // We can use the same RustcEntry multiple times. | |
378 | /// *o.get_mut() += 2; | |
379 | /// } | |
380 | /// | |
381 | /// assert_eq!(map["poneyland"], 24); | |
382 | /// ``` | |
383 | #[cfg_attr(feature = "inline-more", inline)] | |
384 | pub fn get_mut(&mut self) -> &mut V { | |
385 | unsafe { &mut self.elem.as_mut().1 } | |
386 | } | |
387 | ||
388 | /// Converts the RustcOccupiedEntry into a mutable reference to the value in the entry | |
389 | /// with a lifetime bound to the map itself. | |
390 | /// | |
391 | /// If you need multiple references to the `RustcOccupiedEntry`, see [`get_mut`]. | |
392 | /// | |
393 | /// [`get_mut`]: #method.get_mut | |
394 | /// | |
395 | /// # Examples | |
396 | /// | |
397 | /// ``` | |
398 | /// use hashbrown::HashMap; | |
399 | /// use hashbrown::hash_map::RustcEntry; | |
400 | /// | |
401 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
402 | /// map.rustc_entry("poneyland").or_insert(12); | |
403 | /// | |
404 | /// assert_eq!(map["poneyland"], 12); | |
405 | /// if let RustcEntry::Occupied(o) = map.rustc_entry("poneyland") { | |
406 | /// *o.into_mut() += 10; | |
407 | /// } | |
408 | /// | |
409 | /// assert_eq!(map["poneyland"], 22); | |
410 | /// ``` | |
411 | #[cfg_attr(feature = "inline-more", inline)] | |
412 | pub fn into_mut(self) -> &'a mut V { | |
413 | unsafe { &mut self.elem.as_mut().1 } | |
414 | } | |
415 | ||
416 | /// Sets the value of the entry, and returns the entry's old value. | |
417 | /// | |
418 | /// # Examples | |
419 | /// | |
420 | /// ``` | |
421 | /// use hashbrown::HashMap; | |
422 | /// use hashbrown::hash_map::RustcEntry; | |
423 | /// | |
424 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
425 | /// map.rustc_entry("poneyland").or_insert(12); | |
426 | /// | |
427 | /// if let RustcEntry::Occupied(mut o) = map.rustc_entry("poneyland") { | |
428 | /// assert_eq!(o.insert(15), 12); | |
429 | /// } | |
430 | /// | |
431 | /// assert_eq!(map["poneyland"], 15); | |
432 | /// ``` | |
433 | #[cfg_attr(feature = "inline-more", inline)] | |
434 | pub fn insert(&mut self, mut value: V) -> V { | |
435 | let old_value = self.get_mut(); | |
436 | mem::swap(&mut value, old_value); | |
437 | value | |
438 | } | |
439 | ||
440 | /// Takes the value out of the entry, and returns it. | |
441 | /// | |
442 | /// # Examples | |
443 | /// | |
444 | /// ``` | |
445 | /// use hashbrown::HashMap; | |
446 | /// use hashbrown::hash_map::RustcEntry; | |
447 | /// | |
448 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
449 | /// map.rustc_entry("poneyland").or_insert(12); | |
450 | /// | |
451 | /// if let RustcEntry::Occupied(o) = map.rustc_entry("poneyland") { | |
452 | /// assert_eq!(o.remove(), 12); | |
453 | /// } | |
454 | /// | |
455 | /// assert_eq!(map.contains_key("poneyland"), false); | |
456 | /// ``` | |
457 | #[cfg_attr(feature = "inline-more", inline)] | |
458 | pub fn remove(self) -> V { | |
459 | self.remove_entry().1 | |
460 | } | |
461 | ||
462 | /// Replaces the entry, returning the old key and value. The new key in the hash map will be | |
463 | /// the key used to create this entry. | |
464 | /// | |
465 | /// # Examples | |
466 | /// | |
467 | /// ``` | |
468 | /// use hashbrown::hash_map::{RustcEntry, HashMap}; | |
469 | /// use std::rc::Rc; | |
470 | /// | |
471 | /// let mut map: HashMap<Rc<String>, u32> = HashMap::new(); | |
472 | /// map.insert(Rc::new("Stringthing".to_string()), 15); | |
473 | /// | |
474 | /// let my_key = Rc::new("Stringthing".to_string()); | |
475 | /// | |
476 | /// if let RustcEntry::Occupied(entry) = map.rustc_entry(my_key) { | |
477 | /// // Also replace the key with a handle to our other key. | |
478 | /// let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16); | |
479 | /// } | |
480 | /// | |
481 | /// ``` | |
482 | #[cfg_attr(feature = "inline-more", inline)] | |
483 | pub fn replace_entry(self, value: V) -> (K, V) { | |
484 | let entry = unsafe { self.elem.as_mut() }; | |
485 | ||
486 | let old_key = mem::replace(&mut entry.0, self.key.unwrap()); | |
487 | let old_value = mem::replace(&mut entry.1, value); | |
488 | ||
489 | (old_key, old_value) | |
490 | } | |
491 | ||
492 | /// Replaces the key in the hash map with the key used to create this entry. | |
493 | /// | |
494 | /// # Examples | |
495 | /// | |
496 | /// ``` | |
497 | /// use hashbrown::hash_map::{RustcEntry, HashMap}; | |
498 | /// use std::rc::Rc; | |
499 | /// | |
500 | /// let mut map: HashMap<Rc<String>, u32> = HashMap::new(); | |
501 | /// let mut known_strings: Vec<Rc<String>> = Vec::new(); | |
502 | /// | |
503 | /// // Initialise known strings, run program, etc. | |
504 | /// | |
505 | /// reclaim_memory(&mut map, &known_strings); | |
506 | /// | |
507 | /// fn reclaim_memory(map: &mut HashMap<Rc<String>, u32>, known_strings: &[Rc<String>] ) { | |
508 | /// for s in known_strings { | |
509 | /// if let RustcEntry::Occupied(entry) = map.rustc_entry(s.clone()) { | |
510 | /// // Replaces the entry's key with our version of it in `known_strings`. | |
511 | /// entry.replace_key(); | |
512 | /// } | |
513 | /// } | |
514 | /// } | |
515 | /// ``` | |
516 | #[cfg_attr(feature = "inline-more", inline)] | |
517 | pub fn replace_key(self) -> K { | |
518 | let entry = unsafe { self.elem.as_mut() }; | |
519 | mem::replace(&mut entry.0, self.key.unwrap()) | |
520 | } | |
521 | } | |
522 | ||
523 | impl<'a, K, V, A: Allocator + Clone> RustcVacantEntry<'a, K, V, A> { | |
524 | /// Gets a reference to the key that would be used when inserting a value | |
525 | /// through the `RustcVacantEntry`. | |
526 | /// | |
527 | /// # Examples | |
528 | /// | |
529 | /// ``` | |
530 | /// use hashbrown::HashMap; | |
531 | /// | |
532 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
533 | /// assert_eq!(map.rustc_entry("poneyland").key(), &"poneyland"); | |
534 | /// ``` | |
535 | #[cfg_attr(feature = "inline-more", inline)] | |
536 | pub fn key(&self) -> &K { | |
537 | &self.key | |
538 | } | |
539 | ||
540 | /// Take ownership of the key. | |
541 | /// | |
542 | /// # Examples | |
543 | /// | |
544 | /// ``` | |
545 | /// use hashbrown::HashMap; | |
546 | /// use hashbrown::hash_map::RustcEntry; | |
547 | /// | |
548 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
549 | /// | |
550 | /// if let RustcEntry::Vacant(v) = map.rustc_entry("poneyland") { | |
551 | /// v.into_key(); | |
552 | /// } | |
553 | /// ``` | |
554 | #[cfg_attr(feature = "inline-more", inline)] | |
555 | pub fn into_key(self) -> K { | |
556 | self.key | |
557 | } | |
558 | ||
559 | /// Sets the value of the entry with the RustcVacantEntry's key, | |
560 | /// and returns a mutable reference to it. | |
561 | /// | |
562 | /// # Examples | |
563 | /// | |
564 | /// ``` | |
565 | /// use hashbrown::HashMap; | |
566 | /// use hashbrown::hash_map::RustcEntry; | |
567 | /// | |
568 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
569 | /// | |
570 | /// if let RustcEntry::Vacant(o) = map.rustc_entry("poneyland") { | |
571 | /// o.insert(37); | |
572 | /// } | |
573 | /// assert_eq!(map["poneyland"], 37); | |
574 | /// ``` | |
575 | #[cfg_attr(feature = "inline-more", inline)] | |
576 | pub fn insert(self, value: V) -> &'a mut V { | |
577 | let bucket = self.table.insert_no_grow(self.hash, (self.key, value)); | |
578 | unsafe { &mut bucket.as_mut().1 } | |
579 | } | |
580 | ||
581 | /// Sets the value of the entry with the RustcVacantEntry's key, | |
582 | /// and returns a RustcOccupiedEntry. | |
583 | /// | |
584 | /// # Examples | |
585 | /// | |
586 | /// ``` | |
587 | /// use hashbrown::HashMap; | |
588 | /// use hashbrown::hash_map::RustcEntry; | |
589 | /// | |
590 | /// let mut map: HashMap<&str, u32> = HashMap::new(); | |
591 | /// | |
592 | /// if let RustcEntry::Vacant(v) = map.rustc_entry("poneyland") { | |
593 | /// let o = v.insert_entry(37); | |
594 | /// assert_eq!(o.get(), &37); | |
595 | /// } | |
596 | /// ``` | |
597 | #[cfg_attr(feature = "inline-more", inline)] | |
598 | pub fn insert_entry(self, value: V) -> RustcOccupiedEntry<'a, K, V, A> { | |
599 | let bucket = self.table.insert_no_grow(self.hash, (self.key, value)); | |
600 | RustcOccupiedEntry { | |
601 | key: None, | |
602 | elem: bucket, | |
603 | table: self.table, | |
604 | } | |
605 | } | |
606 | } | |
607 | ||
608 | impl<K, V> IterMut<'_, K, V> { | |
609 | /// Returns a iterator of references over the remaining items. | |
610 | #[cfg_attr(feature = "inline-more", inline)] | |
611 | pub fn rustc_iter(&self) -> Iter<'_, K, V> { | |
612 | self.iter() | |
613 | } | |
614 | } | |
615 | ||
616 | impl<K, V> IntoIter<K, V> { | |
617 | /// Returns a iterator of references over the remaining items. | |
618 | #[cfg_attr(feature = "inline-more", inline)] | |
619 | pub fn rustc_iter(&self) -> Iter<'_, K, V> { | |
620 | self.iter() | |
621 | } | |
622 | } | |
623 | ||
624 | impl<K, V> Drain<'_, K, V> { | |
625 | /// Returns a iterator of references over the remaining items. | |
626 | #[cfg_attr(feature = "inline-more", inline)] | |
627 | pub fn rustc_iter(&self) -> Iter<'_, K, V> { | |
628 | self.iter() | |
629 | } | |
630 | } |