Skip to content

Commit be92783

Browse files
committed
Add key_mut method to BTreeMap entries
1 parent 547ace8 commit be92783

File tree

1 file changed

+172
-0
lines changed
  • library/alloc/src/collections/btree/map

1 file changed

+172
-0
lines changed

Diff for: library/alloc/src/collections/btree/map/entry.rs

+172
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,67 @@ impl<'a, K: Ord, V, A: Allocator + Clone> Entry<'a, K, V, A> {
236236
}
237237
}
238238

239+
/// Offers a mutable reference to this entry's key.
240+
///
241+
/// # Safety
242+
///
243+
/// Mutating this key *does not* change the position of the entry, meaning that any mutation
244+
/// should preserve the ordering of the key with respect to all the others in the map.
245+
///
246+
/// This means that you must assert either that any portions of the key you mutate are
247+
/// completely independent from its [`Ord`] implementation, or that you know the values of all
248+
/// keys in the map before and after the current one and that the mutation does not change the
249+
/// ordering with relation to these keys.
250+
///
251+
/// Even if this entry is vacant, this must be upheld even if no value is actually inserted.
252+
/// While a current implementation may allow for improperly ordered keys if the entry is
253+
/// discarded before insertion, the API may change to render this unsafe at any time, and so it
254+
/// must be upheld regardless.
255+
///
256+
/// # Examples
257+
///
258+
/// ```
259+
/// #![feature(btree_entry_key_mut)]
260+
/// use std::collections::BTreeMap;
261+
/// use std::cmp::Ordering;
262+
///
263+
/// struct MyKey<'a> {
264+
/// value: &'a str,
265+
/// tag: &'a str,
266+
/// }
267+
/// impl PartialEq for MyKey<'_> {
268+
/// fn eq(&self, rhs: &MyKey<'_>) -> bool {
269+
/// self.value == rhs.value
270+
/// }
271+
/// }
272+
/// impl Eq for MyKey<'_> {}
273+
/// impl PartialOrd for MyKey<'_> {
274+
/// fn partial_cmp(&self, rhs: &MyKey<'_>) -> Option<Ordering> {
275+
/// self.value.partial_cmp(&rhs.value)
276+
/// }
277+
/// }
278+
/// impl Ord for MyKey<'_> {
279+
/// fn cmp(&self, rhs: &MyKey<'_>) -> Ordering {
280+
/// self.value.cmp(&rhs.value)
281+
/// }
282+
/// }
283+
///
284+
/// let mut map: BTreeMap<MyKey<'_>, usize> = BTreeMap::new();
285+
/// let mut entry = map.entry(MyKey { value: "key", tag: "" });
286+
/// assert_eq!(entry.key().tag, "");
287+
/// unsafe { entry.key_mut().tag = "tagged"; }
288+
/// assert_eq!(entry.key().tag, "tagged");
289+
/// ```
290+
#[unstable(feature = "btree_entry_key_mut", issue = "107540")]
291+
pub unsafe fn key_mut(&mut self) -> &mut K {
292+
match *self {
293+
// SAFETY: Inherited by caller.
294+
Occupied(ref mut entry) => unsafe { entry.key_mut() },
295+
// SAFETY: Inherited by caller.
296+
Vacant(ref mut entry) => unsafe { entry.key_mut() },
297+
}
298+
}
299+
239300
/// Provides in-place mutable access to an occupied entry before any
240301
/// potential inserts into the map.
241302
///
@@ -311,6 +372,63 @@ impl<'a, K: Ord, V, A: Allocator + Clone> VacantEntry<'a, K, V, A> {
311372
&self.key
312373
}
313374

375+
/// Offers a mutable reference to this entry's key.
376+
///
377+
/// # Safety
378+
///
379+
/// Mutating this key *does not* change the position of the entry, meaning that any mutation
380+
/// should preserve the ordering of the key with respect to all the others in the map.
381+
///
382+
/// This means that you must assert either that any portions of the key you mutate are
383+
/// completely independent from its [`Ord`] implementation, or that you know the values of all
384+
/// keys in the map before and after the current one and that the mutation does not change the
385+
/// ordering with relation to these keys.
386+
///
387+
/// Even though this entry is vacant, this must be upheld even if no value is actually inserted.
388+
/// While a current implementation may allow for improperly ordered keys if the entry is
389+
/// discarded before insertion, the API may change to render this unsafe at any time, and so it
390+
/// must be upheld regardless.
391+
///
392+
/// # Examples
393+
///
394+
/// ```
395+
/// #![feature(btree_entry_key_mut)]
396+
/// use std::collections::btree_map::{BTreeMap, Entry};
397+
/// use std::cmp::Ordering;
398+
///
399+
/// struct MyKey<'a> {
400+
/// value: &'a str,
401+
/// tag: &'a str,
402+
/// }
403+
/// impl PartialEq for MyKey<'_> {
404+
/// fn eq(&self, rhs: &MyKey<'_>) -> bool {
405+
/// self.value == rhs.value
406+
/// }
407+
/// }
408+
/// impl Eq for MyKey<'_> {}
409+
/// impl PartialOrd for MyKey<'_> {
410+
/// fn partial_cmp(&self, rhs: &MyKey<'_>) -> Option<Ordering> {
411+
/// self.value.partial_cmp(&rhs.value)
412+
/// }
413+
/// }
414+
/// impl Ord for MyKey<'_> {
415+
/// fn cmp(&self, rhs: &MyKey<'_>) -> Ordering {
416+
/// self.value.cmp(&rhs.value)
417+
/// }
418+
/// }
419+
///
420+
/// let mut map: BTreeMap<MyKey<'_>, usize> = BTreeMap::new();
421+
/// if let Entry::Vacant(mut entry) = map.entry(MyKey { value: "key", tag: "" }) {
422+
/// assert_eq!(entry.key().tag, "");
423+
/// unsafe { entry.key_mut().tag = "tagged"; }
424+
/// assert_eq!(entry.key().tag, "tagged");
425+
/// }
426+
/// ```
427+
#[unstable(feature = "btree_entry_key_mut", issue = "107540")]
428+
pub unsafe fn key_mut(&mut self) -> &mut K {
429+
&mut self.key
430+
}
431+
314432
/// Take ownership of the key.
315433
///
316434
/// # Examples
@@ -403,6 +521,60 @@ impl<'a, K: Ord, V, A: Allocator + Clone> OccupiedEntry<'a, K, V, A> {
403521
self.handle.reborrow().into_kv().0
404522
}
405523

524+
/// Offers a mutable reference to this entry's key.
525+
///
526+
/// # Safety
527+
///
528+
/// Mutating this key *does not* change the position of the entry, meaning that any mutation
529+
/// should preserve the ordering of the key with respect to all the others in the map.
530+
///
531+
/// This means that you must assert either that any portions of the key you mutate are
532+
/// completely independent from its [`Ord`] implementation, or that you know the values of all
533+
/// keys in the map before and after the current one and that the mutation does not change the
534+
/// ordering with relation to these keys.
535+
///
536+
/// # Examples
537+
///
538+
/// ```
539+
/// #![feature(btree_entry_key_mut)]
540+
/// use std::collections::btree_map::{BTreeMap, Entry};
541+
/// use std::cmp::Ordering;
542+
///
543+
/// struct MyKey<'a> {
544+
/// value: &'a str,
545+
/// tag: &'a str,
546+
/// }
547+
/// impl PartialEq for MyKey<'_> {
548+
/// fn eq(&self, rhs: &MyKey<'_>) -> bool {
549+
/// self.value == rhs.value
550+
/// }
551+
/// }
552+
/// impl Eq for MyKey<'_> {}
553+
/// impl PartialOrd for MyKey<'_> {
554+
/// fn partial_cmp(&self, rhs: &MyKey<'_>) -> Option<Ordering> {
555+
/// self.value.partial_cmp(&rhs.value)
556+
/// }
557+
/// }
558+
/// impl Ord for MyKey<'_> {
559+
/// fn cmp(&self, rhs: &MyKey<'_>) -> Ordering {
560+
/// self.value.cmp(&rhs.value)
561+
/// }
562+
/// }
563+
///
564+
/// let mut map: BTreeMap<MyKey<'_>, usize> = BTreeMap::new();
565+
/// map.entry(MyKey { value: "key", tag: "inserted" }).or_insert(12);
566+
/// if let Entry::Occupied(mut entry) = map.entry(MyKey { value: "key", tag: "first" }) {
567+
/// assert_eq!(entry.key().tag, "inserted");
568+
/// unsafe { entry.key_mut().tag = "modified"; }
569+
/// assert_eq!(entry.key().tag, "modified");
570+
/// }
571+
/// assert_eq!(map.entry(MyKey { value: "key", tag: "second" }).key().tag, "modified");
572+
/// ```
573+
#[unstable(feature = "btree_entry_key_mut", issue = "107540")]
574+
pub unsafe fn key_mut(&mut self) -> &mut K {
575+
self.handle.key_mut()
576+
}
577+
406578
/// Take ownership of the key and value from the map.
407579
///
408580
/// # Examples

0 commit comments

Comments
 (0)