aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/collections/hash/map.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ctr-std/src/collections/hash/map.rs')
-rw-r--r--ctr-std/src/collections/hash/map.rs60
1 files changed, 45 insertions, 15 deletions
diff --git a/ctr-std/src/collections/hash/map.rs b/ctr-std/src/collections/hash/map.rs
index a7eb002..9c77acb 100644
--- a/ctr-std/src/collections/hash/map.rs
+++ b/ctr-std/src/collections/hash/map.rs
@@ -11,7 +11,7 @@
use self::Entry::*;
use self::VacantEntryState::*;
-use alloc::{CollectionAllocErr, oom};
+use alloc::CollectionAllocErr;
use cell::Cell;
use borrow::Borrow;
use cmp::max;
@@ -23,8 +23,10 @@ use mem::{self, replace};
use ops::{Deref, Index};
use sys;
-use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash};
+use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucketMut, RawTable,
+ SafeHash};
use super::table::BucketState::{Empty, Full};
+use super::table::Fallibility::{Fallible, Infallible};
const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two
@@ -783,11 +785,11 @@ impl<K, V, S> HashMap<K, V, S>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve(&mut self, additional: usize) {
- match self.try_reserve(additional) {
+ match self.reserve_internal(additional, Infallible) {
Err(CollectionAllocErr::CapacityOverflow) => panic!("capacity overflow"),
- Err(CollectionAllocErr::AllocErr) => oom(),
+ Err(CollectionAllocErr::AllocErr) => unreachable!(),
Ok(()) => { /* yay */ }
- }
+ }
}
/// Tries to reserve capacity for at least `additional` more elements to be inserted
@@ -809,17 +811,24 @@ impl<K, V, S> HashMap<K, V, S>
/// ```
#[unstable(feature = "try_reserve", reason = "new API", issue="48043")]
pub fn try_reserve(&mut self, additional: usize) -> Result<(), CollectionAllocErr> {
+ self.reserve_internal(additional, Fallible)
+ }
+
+ fn reserve_internal(&mut self, additional: usize, fallibility: Fallibility)
+ -> Result<(), CollectionAllocErr> {
+
let remaining = self.capacity() - self.len(); // this can't overflow
if remaining < additional {
- let min_cap = self.len().checked_add(additional)
+ let min_cap = self.len()
+ .checked_add(additional)
.ok_or(CollectionAllocErr::CapacityOverflow)?;
let raw_cap = self.resize_policy.try_raw_capacity(min_cap)?;
- self.try_resize(raw_cap)?;
+ self.try_resize(raw_cap, fallibility)?;
} else if self.table.tag() && remaining <= self.len() {
// Probe sequence is too long and table is half full,
// resize early to reduce probing length.
let new_capacity = self.table.capacity() * 2;
- self.try_resize(new_capacity)?;
+ self.try_resize(new_capacity, fallibility)?;
}
Ok(())
}
@@ -831,11 +840,21 @@ impl<K, V, S> HashMap<K, V, S>
/// 2) Ensure `new_raw_cap` is a power of two or zero.
#[inline(never)]
#[cold]
- fn try_resize(&mut self, new_raw_cap: usize) -> Result<(), CollectionAllocErr> {
+ fn try_resize(
+ &mut self,
+ new_raw_cap: usize,
+ fallibility: Fallibility,
+ ) -> Result<(), CollectionAllocErr> {
assert!(self.table.size() <= new_raw_cap);
assert!(new_raw_cap.is_power_of_two() || new_raw_cap == 0);
- let mut old_table = replace(&mut self.table, RawTable::try_new(new_raw_cap)?);
+ let mut old_table = replace(
+ &mut self.table,
+ match fallibility {
+ Infallible => RawTable::new(new_raw_cap),
+ Fallible => RawTable::try_new(new_raw_cap)?,
+ }
+ );
let old_size = old_table.size();
if old_table.size() == 0 {
@@ -2142,14 +2161,13 @@ impl<'a, K, V> Entry<'a, K, V> {
}
impl<'a, K, V: Default> Entry<'a, K, V> {
- #[unstable(feature = "entry_or_default", issue = "44324")]
+ #[stable(feature = "entry_or_default", since = "1.28.0")]
/// Ensures a value is in the entry by inserting the default value if empty,
/// and returns a mutable reference to the value in the entry.
///
/// # Examples
///
/// ```
- /// #![feature(entry_or_default)]
/// # fn main() {
/// use std::collections::HashMap;
///
@@ -2165,7 +2183,6 @@ impl<'a, K, V: Default> Entry<'a, K, V> {
Vacant(entry) => entry.insert(Default::default()),
}
}
-
}
impl<'a, K, V> OccupiedEntry<'a, K, V> {
@@ -2231,6 +2248,11 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
/// Gets a mutable reference to the value in the entry.
///
+ /// If you need a reference to the `OccupiedEntry` which may outlive the
+ /// destruction of the `Entry` value, see [`into_mut`].
+ ///
+ /// [`into_mut`]: #method.into_mut
+ ///
/// # Examples
///
/// ```
@@ -2242,10 +2264,14 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
///
/// assert_eq!(map["poneyland"], 12);
/// if let Entry::Occupied(mut o) = map.entry("poneyland") {
- /// *o.get_mut() += 10;
+ /// *o.get_mut() += 10;
+ /// assert_eq!(*o.get(), 22);
+ ///
+ /// // We can use the same Entry multiple times.
+ /// *o.get_mut() += 2;
/// }
///
- /// assert_eq!(map["poneyland"], 22);
+ /// assert_eq!(map["poneyland"], 24);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn get_mut(&mut self) -> &mut V {
@@ -2255,6 +2281,10 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
/// Converts the OccupiedEntry into a mutable reference to the value in the entry
/// with a lifetime bound to the map itself.
///
+ /// If you need multiple references to the `OccupiedEntry`, see [`get_mut`].
+ ///
+ /// [`get_mut`]: #method.get_mut
+ ///
/// # Examples
///
/// ```