use hashers::null::PassThroughHasher;
#[cfg(feature = "serialize")]
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
use std::collections::hash_map::{self, HashMap};
use std::hash::{BuildHasherDefault, Hash, Hasher};
use std::marker::PhantomData;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]
pub struct RandMap<V>(
HashMap<Handle<V>, V, BuildHasherDefault<PassThroughHasher>>
);
impl<V> RandMap<V> {
#[inline]
pub fn new() -> Self {
Self(HashMap::default())
}
#[inline]
pub fn as_hash_map(
&self,
) -> &HashMap<Handle<V>, V, BuildHasherDefault<PassThroughHasher>> {
&self.0
}
#[inline]
pub fn clear(&mut self) {
self.0.clear()
}
#[inline]
pub fn get(&self, handle: Handle<V>) -> Option<&V> {
self.0.get(&handle)
}
#[inline]
pub fn get_mut(&mut self, handle: Handle<V>) -> Option<&mut V> {
self.0.get_mut(&handle)
}
pub fn insert(&mut self, value: V) -> Handle<V> {
use rand::{rng, Rng};
let key: Handle<V> = rng().random();
self.0.insert(key, value);
key
}
pub fn insert_key_value(&mut self, key: Handle<V>, value: V) {
self.0.insert(key, value);
}
#[inline]
pub fn iter(&self) -> Iter<'_, V> {
Iter(self.0.iter())
}
#[inline]
pub fn iter_mut(&mut self) -> IterMut<'_, V> {
IterMut(self.0.iter_mut())
}
#[inline]
pub fn len(&self) -> usize {
self.0.len()
}
#[inline]
pub fn remove(&mut self, handle: Handle<V>) -> Option<V> {
self.0.remove(&handle)
}
}
impl<'a, V> IntoIterator for &'a RandMap<V> {
type Item = (Handle<V>, &'a V);
type IntoIter = Iter<'a, V>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<V> PartialEq for RandMap<V>
where
V: PartialEq,
{
fn eq(&self, other: &RandMap<V>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter()
.all(|(key, val)| other.get(key).map_or(false, |v| *val == *v))
}
}
pub struct Iter<'a, V>(hash_map::Iter<'a, Handle<V>, V>);
impl<'a, V> Iterator for Iter<'a, V> {
type Item = (Handle<V>, &'a V);
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(k, v)| (*k, v))
}
}
pub struct IterMut<'a, V>(hash_map::IterMut<'a, Handle<V>, V>);
impl<'a, V> Iterator for IterMut<'a, V> {
type Item = (Handle<V>, &'a mut V);
fn next(&mut self) -> Option<Self::Item> {
self.0.next().map(|(k, v)| (*k, v))
}
}
#[derive(Debug)]
pub struct Handle<V>(u64, PhantomData<fn() -> V>);
impl<V> Handle<V> {
#[inline]
pub fn from_u64(u: u64) -> Self {
Self(u, PhantomData)
}
#[inline]
pub fn as_u64(&self) -> u64 {
self.0
}
}
impl<V> Clone for Handle<V> {
fn clone(&self) -> Self {
*self
}
}
impl<V> Copy for Handle<V> { }
impl<V> Eq for Handle<V> {}
impl<V> From<u64> for Handle<V> {
fn from(item: u64) -> Handle<V> {
Self(item, PhantomData)
}
}
impl<V> From<Handle<V>> for u64 {
fn from(item: Handle<V>) -> u64 {
item.as_u64()
}
}
impl<V> Hash for Handle<V> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state);
}
}
impl<V> Ord for Handle<V> {
fn cmp(&self, other: &Self) -> Ordering {
self.0.cmp(&other.0)
}
}
impl<V> PartialEq for Handle<V> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<V> PartialOrd for Handle<V> {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<V> rand::distr::Distribution<Handle<V>>
for rand::distr::StandardUniform {
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Handle<V> {
Handle(rng.random(), PhantomData)
}
}