aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/collections
diff options
context:
space:
mode:
authorFenrir <[email protected]>2018-02-15 21:15:14 -0700
committerFenrir <[email protected]>2018-02-15 21:15:39 -0700
commit49dc1a5e06a04c4cb6bd136f7dedb85719646e10 (patch)
treefb39e58a1734b5def44803d07f3134b706a96ba0 /ctr-std/src/collections
parentFix TcpStream::wait_timeout (diff)
downloadctru-rs-49dc1a5e06a04c4cb6bd136f7dedb85719646e10.tar.xz
ctru-rs-49dc1a5e06a04c4cb6bd136f7dedb85719646e10.zip
Updates for Rust 1.24
Diffstat (limited to 'ctr-std/src/collections')
-rw-r--r--ctr-std/src/collections/hash/map.rs73
1 files changed, 45 insertions, 28 deletions
diff --git a/ctr-std/src/collections/hash/map.rs b/ctr-std/src/collections/hash/map.rs
index b01420f..a82ff91 100644
--- a/ctr-std/src/collections/hash/map.rs
+++ b/ctr-std/src/collections/hash/map.rs
@@ -398,8 +398,9 @@ pub struct HashMap<K, V, S = RandomState> {
}
/// Search for a pre-hashed key.
+/// If you don't already know the hash, use search or search_mut instead
#[inline]
-fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> InternalEntry<K, V, M>
+fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, is_match: F) -> InternalEntry<K, V, M>
where M: Deref<Target = RawTable<K, V>>,
F: FnMut(&K) -> bool
{
@@ -410,6 +411,18 @@ fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> Inter
return InternalEntry::TableIsEmpty;
}
+ search_hashed_nonempty(table, hash, is_match)
+}
+
+/// Search for a pre-hashed key when the hash map is known to be non-empty.
+#[inline]
+fn search_hashed_nonempty<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F)
+ -> InternalEntry<K, V, M>
+ where M: Deref<Target = RawTable<K, V>>,
+ F: FnMut(&K) -> bool
+{
+ // Do not check the capacity as an extra branch could slow the lookup.
+
let size = table.size();
let mut probe = Bucket::new(table, hash);
let mut displacement = 0;
@@ -543,24 +556,36 @@ impl<K, V, S> HashMap<K, V, S>
}
/// Search for a key, yielding the index if it's found in the hashtable.
- /// If you already have the hash for the key lying around, use
- /// search_hashed.
+ /// If you already have the hash for the key lying around, or if you need an
+ /// InternalEntry, use search_hashed or search_hashed_nonempty.
#[inline]
- fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> InternalEntry<K, V, &'a RawTable<K, V>>
+ fn search<'a, Q: ?Sized>(&'a self, q: &Q)
+ -> Option<FullBucket<K, V, &'a RawTable<K, V>>>
where K: Borrow<Q>,
Q: Eq + Hash
{
+ if self.is_empty() {
+ return None;
+ }
+
let hash = self.make_hash(q);
- search_hashed(&self.table, hash, |k| q.eq(k.borrow()))
+ search_hashed_nonempty(&self.table, hash, |k| q.eq(k.borrow()))
+ .into_occupied_bucket()
}
#[inline]
- fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> InternalEntry<K, V, &'a mut RawTable<K, V>>
+ fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q)
+ -> Option<FullBucket<K, V, &'a mut RawTable<K, V>>>
where K: Borrow<Q>,
Q: Eq + Hash
{
+ if self.is_empty() {
+ return None;
+ }
+
let hash = self.make_hash(q);
- search_hashed(&mut self.table, hash, |k| q.eq(k.borrow()))
+ search_hashed_nonempty(&mut self.table, hash, |k| q.eq(k.borrow()))
+ .into_occupied_bucket()
}
// The caller should ensure that invariants by Robin Hood Hashing hold
@@ -1118,7 +1143,7 @@ impl<K, V, S> HashMap<K, V, S>
where K: Borrow<Q>,
Q: Hash + Eq
{
- self.search(k).into_occupied_bucket().map(|bucket| bucket.into_refs().1)
+ self.search(k).map(|bucket| bucket.into_refs().1)
}
/// Returns true if the map contains a value for the specified key.
@@ -1145,7 +1170,7 @@ impl<K, V, S> HashMap<K, V, S>
where K: Borrow<Q>,
Q: Hash + Eq
{
- self.search(k).into_occupied_bucket().is_some()
+ self.search(k).is_some()
}
/// Returns a mutable reference to the value corresponding to the key.
@@ -1174,7 +1199,7 @@ impl<K, V, S> HashMap<K, V, S>
where K: Borrow<Q>,
Q: Hash + Eq
{
- self.search_mut(k).into_occupied_bucket().map(|bucket| bucket.into_mut_refs().1)
+ self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
}
/// Inserts a key-value pair into the map.
@@ -1234,11 +1259,7 @@ impl<K, V, S> HashMap<K, V, S>
where K: Borrow<Q>,
Q: Hash + Eq
{
- if self.table.size() == 0 {
- return None;
- }
-
- self.search_mut(k).into_occupied_bucket().map(|bucket| pop_internal(bucket).1)
+ self.search_mut(k).map(|bucket| pop_internal(bucket).1)
}
/// Removes a key from the map, returning the stored key and value if the
@@ -1269,12 +1290,7 @@ impl<K, V, S> HashMap<K, V, S>
where K: Borrow<Q>,
Q: Hash + Eq
{
- if self.table.size() == 0 {
- return None;
- }
-
self.search_mut(k)
- .into_occupied_bucket()
.map(|bucket| {
let (k, v, _) = pop_internal(bucket);
(k, v)
@@ -1384,9 +1400,14 @@ impl<'a, K, Q: ?Sized, V, S> Index<&'a Q> for HashMap<K, V, S>
{
type Output = V;
+ /// Returns a reference to the value corresponding to the supplied key.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the key is not present in the `HashMap`.
#[inline]
- fn index(&self, index: &Q) -> &V {
- self.get(index).expect("no entry found for key")
+ fn index(&self, key: &Q) -> &V {
+ self.get(key).expect("no entry found for key")
}
}
@@ -2627,15 +2648,11 @@ impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S>
#[inline]
fn get(&self, key: &Q) -> Option<&K> {
- self.search(key).into_occupied_bucket().map(|bucket| bucket.into_refs().0)
+ self.search(key).map(|bucket| bucket.into_refs().0)
}
fn take(&mut self, key: &Q) -> Option<K> {
- if self.table.size() == 0 {
- return None;
- }
-
- self.search_mut(key).into_occupied_bucket().map(|bucket| pop_internal(bucket).0)
+ self.search_mut(key).map(|bucket| pop_internal(bucket).0)
}
#[inline]