mirror of
https://github.com/italicsjenga/agb.git
synced 2025-01-11 01:21:34 +11:00
Add documentation example and add Borrow stuff for easier contains_key
This commit is contained in:
parent
d594e9e078
commit
150b1a3078
|
@ -20,6 +20,7 @@ extern crate alloc;
|
||||||
use alloc::{alloc::Global, vec::Vec};
|
use alloc::{alloc::Global, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
alloc::Allocator,
|
alloc::Allocator,
|
||||||
|
borrow::Borrow,
|
||||||
hash::{BuildHasher, BuildHasherDefault, Hash, Hasher},
|
hash::{BuildHasher, BuildHasherDefault, Hash, Hasher},
|
||||||
iter::FromIterator,
|
iter::FromIterator,
|
||||||
mem::{self, MaybeUninit},
|
mem::{self, MaybeUninit},
|
||||||
|
@ -99,6 +100,38 @@ type HashType = u32;
|
||||||
///
|
///
|
||||||
/// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
|
/// [`Eq`]: https://doc.rust-lang.org/core/cmp/trait.Eq.html
|
||||||
/// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
|
/// [`Hash`]: https://doc.rust-lang.org/core/hash/trait.Hash.html
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
/// ```
|
||||||
|
/// use agb_hashmap::HashMap;
|
||||||
|
///
|
||||||
|
/// // Type inference lets you omit the type signature (which would be HashMap<String, String> in this example)
|
||||||
|
/// let mut game_reviews = HashMap::new();
|
||||||
|
///
|
||||||
|
/// // Review some games
|
||||||
|
/// game_reviews.insert(
|
||||||
|
/// "Pokemon Emerald".to_string(),
|
||||||
|
/// "Best post-game battle experience of any generation.".to_string(),
|
||||||
|
/// );
|
||||||
|
/// game_reviews.insert(
|
||||||
|
/// "Golden Sun".to_string(),
|
||||||
|
/// "Some of the best music on the console".to_string(),
|
||||||
|
/// );
|
||||||
|
/// game_reviews.insert(
|
||||||
|
/// "Super Dodge Ball Advance".to_string(),
|
||||||
|
/// "Really great launch title".to_string(),
|
||||||
|
/// );
|
||||||
|
///
|
||||||
|
/// // Check for a specific entry
|
||||||
|
/// if !game_reviews.contains_key("Legend of Zelda: The Minish Cap") {
|
||||||
|
/// println!("We've got {} reviews, but The Minish Cap ain't one", game_reviews.len());
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// // Iterate over everything
|
||||||
|
/// for (game, review) in &game_reviews {
|
||||||
|
/// println!("{game}: \"{review}\"");
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
pub struct HashMap<K, V, ALLOCATOR: Allocator = Global> {
|
pub struct HashMap<K, V, ALLOCATOR: Allocator = Global> {
|
||||||
nodes: NodeStorage<K, V, ALLOCATOR>,
|
nodes: NodeStorage<K, V, ALLOCATOR>,
|
||||||
|
|
||||||
|
@ -299,7 +332,11 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns `true` if the map contains a value for the specified key.
|
/// Returns `true` if the map contains a value for the specified key.
|
||||||
pub fn contains_key(&self, k: &K) -> bool {
|
pub fn contains_key<Q>(&self, k: &Q) -> bool
|
||||||
|
where
|
||||||
|
K: Borrow<Q>,
|
||||||
|
Q: Hash + Eq + ?Sized,
|
||||||
|
{
|
||||||
let hash = self.hash(k);
|
let hash = self.hash(k);
|
||||||
self.nodes.location(k, hash).is_some()
|
self.nodes.location(k, hash).is_some()
|
||||||
}
|
}
|
||||||
|
@ -346,7 +383,11 @@ impl<K, V, ALLOCATOR: ClonableAllocator> HashMap<K, V, ALLOCATOR>
|
||||||
where
|
where
|
||||||
K: Hash,
|
K: Hash,
|
||||||
{
|
{
|
||||||
fn hash(&self, key: &K) -> HashType {
|
fn hash<Q>(&self, key: &Q) -> HashType
|
||||||
|
where
|
||||||
|
K: Borrow<Q>,
|
||||||
|
Q: Hash + ?Sized,
|
||||||
|
{
|
||||||
let mut hasher = self.hasher.build_hasher();
|
let mut hasher = self.hasher.build_hasher();
|
||||||
key.hash(&mut hasher);
|
key.hash(&mut hasher);
|
||||||
hasher.finish() as HashType
|
hasher.finish() as HashType
|
||||||
|
@ -828,9 +869,10 @@ impl<K, V, ALLOCATOR: ClonableAllocator> NodeStorage<K, V, ALLOCATOR> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn location(&self, key: &K, hash: HashType) -> Option<usize>
|
fn location<Q>(&self, key: &Q, hash: HashType) -> Option<usize>
|
||||||
where
|
where
|
||||||
K: Eq,
|
K: Borrow<Q>,
|
||||||
|
Q: Eq + ?Sized,
|
||||||
{
|
{
|
||||||
for distance_to_initial_bucket in 0..(self.max_distance_to_initial_bucket + 1) {
|
for distance_to_initial_bucket in 0..(self.max_distance_to_initial_bucket + 1) {
|
||||||
let location = fast_mod(
|
let location = fast_mod(
|
||||||
|
@ -840,7 +882,7 @@ impl<K, V, ALLOCATOR: ClonableAllocator> NodeStorage<K, V, ALLOCATOR> {
|
||||||
|
|
||||||
let node = &self.nodes[location];
|
let node = &self.nodes[location];
|
||||||
if let Some(node_key_ref) = node.key_ref() {
|
if let Some(node_key_ref) = node.key_ref() {
|
||||||
if node_key_ref == key {
|
if node_key_ref.borrow() == key {
|
||||||
return Some(location);
|
return Some(location);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue