blob: 53cd73ccb34b0df429b5e2e70e976a9435f4249c [file] [log] [blame]
use std::borrow::Borrow;
use std::collections::{hash_map, HashMap};
use std::fmt::{self, Debug};
use std::hash::{BuildHasher, Hash};
use std::iter::FromIterator;
use std::ops::{Deref, DerefMut, Index};
use std::panic::UnwindSafe;
use crate::{RandomState};
/// A [`HashMap`](std::collections::HashMap) using [`RandomState`](crate::RandomState) to hash the items.
/// (Requires the `std` feature to be enabled.)
#[derive(Clone)]
pub struct AHashMap<K, V, S = crate::RandomState>(HashMap<K, V, S>);
impl<K, V> From<HashMap<K, V, crate::RandomState>> for AHashMap<K, V> {
fn from(item: HashMap<K, V, crate::RandomState>) -> Self {
AHashMap(item)
}
}
impl<K, V> Into<HashMap<K, V, crate::RandomState>> for AHashMap<K, V> {
fn into(self) -> HashMap<K, V, crate::RandomState> {
self.0
}
}
impl<K, V> AHashMap<K, V, RandomState> {
pub fn new() -> Self {
AHashMap(HashMap::with_hasher(RandomState::default()))
}
pub fn with_capacity(capacity: usize) -> Self {
AHashMap(HashMap::with_capacity_and_hasher(capacity, RandomState::default()))
}
}
impl<K, V, S> AHashMap<K, V, S> where S: BuildHasher {
pub fn with_hasher(hash_builder: S) -> Self {
AHashMap(HashMap::with_hasher(hash_builder))
}
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
AHashMap(HashMap::with_capacity_and_hasher(capacity, hash_builder))
}
}
impl<K, V, S> AHashMap<K, V, S>
where
K: Hash + Eq,
S: BuildHasher
{
/// Returns a reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// map.insert(1, "a");
/// assert_eq!(map.get(&1), Some(&"a"));
/// assert_eq!(map.get(&2), None);
/// ```
#[inline]
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.0.get(k)
}
/// Returns the key-value pair corresponding to the supplied key.
///
/// The supplied key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// map.insert(1, "a");
/// assert_eq!(map.get_key_value(&1), Some((&1, &"a")));
/// assert_eq!(map.get_key_value(&2), None);
/// ```
#[inline]
pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.0.get_key_value(k)
}
/// Returns a mutable reference to the value corresponding to the key.
///
/// The key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// map.insert(1, "a");
/// if let Some(x) = map.get_mut(&1) {
/// *x = "b";
/// }
/// assert_eq!(map[&1], "b");
/// ```
#[inline]
pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.0.get_mut(k)
}
/// Inserts a key-value pair into the map.
///
/// If the map did not have this key present, [`None`] is returned.
///
/// If the map did have this key present, the value is updated, and the old
/// value is returned. The key is not updated, though; this matters for
/// types that can be `==` without being identical. See the [module-level
/// documentation] for more.
///
/// [module-level documentation]: crate::collections#insert-and-complex-keys
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// assert_eq!(map.insert(37, "a"), None);
/// assert_eq!(map.is_empty(), false);
///
/// map.insert(37, "b");
/// assert_eq!(map.insert(37, "c"), Some("b"));
/// assert_eq!(map[&37], "c");
/// ```
#[inline]
pub fn insert(&mut self, k: K, v: V) -> Option<V> {
self.0.insert(k, v)
}
/// Removes a key from the map, returning the value at the key if the key
/// was previously in the map.
///
/// The key may be any borrowed form of the map's key type, but
/// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
/// the key type.
///
/// # Examples
///
/// ```
/// use std::collections::HashMap;
///
/// let mut map = HashMap::new();
/// map.insert(1, "a");
/// assert_eq!(map.remove(&1), Some("a"));
/// assert_eq!(map.remove(&1), None);
/// ```
#[inline]
pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.0.remove(k)
}
}
impl<K, V, S> Deref for AHashMap<K, V, S> {
type Target = HashMap<K, V, S>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<K, V, S> DerefMut for AHashMap<K, V, S> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<K, V, S> UnwindSafe for AHashMap<K, V, S>
where
K: UnwindSafe,
V: UnwindSafe,
{
}
impl<K, V, S> PartialEq for AHashMap<K, V, S>
where
K: Eq + Hash,
V: PartialEq,
S: BuildHasher,
{
fn eq(&self, other: &AHashMap<K, V, S>) -> bool {
self.0.eq(&other.0)
}
}
impl<K, V, S> Eq for AHashMap<K, V, S>
where
K: Eq + Hash,
V: Eq,
S: BuildHasher,
{
}
impl<K, Q: ?Sized, V, S> Index<&Q> for AHashMap<K, V, S>
where
K: Eq + Hash + Borrow<Q>,
Q: Eq + Hash,
S: BuildHasher,
{
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, key: &Q) -> &V {
self.0.index(key)
}
}
impl<K, V, S> Debug for AHashMap<K, V, S>
where
K: Debug,
V: Debug,
S: BuildHasher,
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(fmt)
}
}
impl<K, V, S> FromIterator<(K, V)> for AHashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher + Default,
{
fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
AHashMap(HashMap::from_iter(iter))
}
}
impl<'a, K, V, S> IntoIterator for &'a AHashMap<K, V, S> {
type Item = (&'a K, &'a V);
type IntoIter = hash_map::Iter<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
(&self.0).iter()
}
}
impl<'a, K, V, S> IntoIterator for &'a mut AHashMap<K, V, S> {
type Item = (&'a K, &'a mut V);
type IntoIter = hash_map::IterMut<'a, K, V>;
fn into_iter(self) -> Self::IntoIter {
(&mut self.0).iter_mut()
}
}
impl<K, V, S> IntoIterator for AHashMap<K, V, S> {
type Item = (K, V);
type IntoIter = hash_map::IntoIter<K, V>;
fn into_iter(self) -> Self::IntoIter {
self.0.into_iter()
}
}
impl<K, V, S> Extend<(K, V)> for AHashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
#[inline]
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
self.0.extend(iter)
}
}
impl<'a, K, V, S> Extend<(&'a K, &'a V)> for AHashMap<K, V, S>
where
K: Eq + Hash + Copy + 'a,
V: Copy + 'a,
S: BuildHasher,
{
#[inline]
fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
self.0.extend(iter)
}
}
impl<K, V> Default for AHashMap<K, V, RandomState> {
#[inline]
fn default() -> AHashMap<K, V, RandomState> {
AHashMap::new()
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_borrow() {
let mut map: AHashMap<String, String> = AHashMap::new();
map.insert("foo".to_string(), "Bar".to_string());
map.insert("Bar".to_string(), map.get("foo").unwrap().to_owned());
}
}