Skip to content

Commit 88fda75

Browse files
committed
Add key_mut method to BTreeMap entries
1 parent a48861a commit 88fda75

File tree

1 file changed

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

1 file changed

+172
-0
lines changed

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
@@ -404,6 +522,60 @@ impl<'a, K: Ord, V, A: Allocator + Clone> OccupiedEntry<'a, K, V, A> {
404522
self.handle.reborrow().into_kv().0
405523
}
406524

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

0 commit comments

Comments
 (0)