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