macro_rules! do_impl {
(Get for $name:ident, $impl_for:ty, $contains:ident; $($gen:tt)*) => {
impl<'a, $($gen)*> $crate::get::Get for $impl_for {
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
$name::get(self, key)
}
fn contains_key(&self, key: &Self::Key) -> bool {
$name::$contains(self, key)
}
}
};
(deref Get for $name:ident, $impl_for:ty; $($gen:tt)*) => {
impl<'a, $($gen)*> $crate::get::Get for $impl_for {
fn get(&self, key: &Self::Key) -> Option<&Self::Value> {
$name::get(self, *key)
}
}
};
(GetMut for $name:ident, $impl_for:ty, $contains:ident; $($gen:tt)*) => {
do_impl!(Get for $name, $impl_for, $contains; $($gen)*);
impl<'a, $($gen)*> $crate::get::GetMut for $impl_for {
fn get_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value> {
$name::get_mut(self, key)
}
}
};
(deref GetMut for $name:ident, $impl_for:ty; $($gen:tt)*) => {
do_impl!(deref Get for $name, $impl_for; $($gen)*);
impl<'a, $($gen)*> $crate::get::GetMut for $impl_for {
fn get_mut(&mut self, key: &Self::Key) -> Option<&mut Self::Value> {
$name::get_mut(self, *key)
}
}
};
(GetEntry for $name:ident, $impl_for:ty, $entry:ident, $occupied:ty, $vacant:ty; $($gen:tt)*) => {
do_impl!(GetMut for $name, $impl_for, contains_key; $($gen)*);
impl<'a, $($gen)*> $crate::entry::GetEntry<'a> for $impl_for {
type Occupied = $occupied;
type Vacant = $vacant;
fn entry(&'a mut self, key: Self::Key) -> $crate::entry::Entry<'a, Self> {
match $name::entry(self, key) {
$entry::Occupied(ent) => $crate::entry::Entry::Occupied(ent),
$entry::Vacant(ent) => $crate::entry::Entry::Vacant(ent),
}
}
}
};
(OccupiedEntry for $name:ident, $impl_for:ty, $map:ty; $($gen:tt)*) => {
impl<'a, $($gen)*> $crate::entry::OccupiedEntry<'a, $map> for $impl_for {
fn key(&self) -> &<$map as ::iter_trait::HasMapData>::Key {
$name::key(self)
}
fn get(&self) -> &<$map as ::iter_trait::HasMapData>::Value {
$name::get(self)
}
fn get_mut(&mut self) -> &mut <$map as ::iter_trait::HasMapData>::Value {
$name::get_mut(self)
}
fn insert(&mut self, value: <$map as ::iter_trait::HasMapData>::Value) -> <$map as ::iter_trait::HasMapData>::Value {
$name::insert(self, value)
}
fn into_mut(self) -> &'a mut <$map as ::iter_trait::HasMapData>::Value {
$name::into_mut(self)
}
fn remove_entry(self) -> (<$map as ::iter_trait::HasMapData>::Key, <$map as ::iter_trait::HasMapData>::Value) {
$name::remove_entry(self)
}
}
};
(VacantEntry for $name:ident, $impl_for:ty, $map:ty; $($gen:tt)*) => {
impl<'a, $($gen)*> $crate::entry::VacantEntry<'a, $map> for $impl_for {
fn key(&self) -> &<$map as ::iter_trait::HasMapData>::Key {
$name::key(self)
}
fn into_key(self) -> <$map as ::iter_trait::HasMapData>::Key {
$name::into_key(self)
}
fn insert(self, value: <$map as ::iter_trait::HasMapData>::Value) -> &'a mut <$map as ::iter_trait::HasMapData>::Value {
$name::insert(self, value)
}
}
};
}
cfg_if! {
if #[cfg(feature = "std")] {
type Slice<T> = [T];
} else {
use core::slice::SliceExt as Slice;
}
}
do_impl!(deref GetMut for Slice, [T]; T);
cfg_if! {
if #[cfg(feature = "alloc")] {
cfg_if! {
if #[cfg(feature = "std")] {
use std::collections;
} else {
use alloc::{self as collections, Vec};
}
}
use self::collections::{BTreeMap, BTreeSet, VecDeque};
use self::collections::btree_map::{Entry as BEnt, OccupiedEntry as BOcc, VacantEntry as BVac};
do_impl!(Get for BTreeSet, BTreeSet<T>, contains; T: Ord);
do_impl!(deref GetMut for Slice, Vec<T>; T);
do_impl!(deref GetMut for VecDeque, VecDeque<T>; T);
do_impl!(GetEntry for BTreeMap, BTreeMap<K, V>,
BEnt, BOcc<'a, K, V>, BVac<'a, K, V>; K: 'a + Ord, V: 'a);
do_impl!(OccupiedEntry for BOcc, BOcc<'a, K, V>, BTreeMap<K, V>; K: 'a + Ord, V: 'a);
do_impl!(VacantEntry for BVac, BVac<'a, K, V>, BTreeMap<K, V>; K: 'a + Ord, V: 'a);
}
}
cfg_if! {
if #[cfg(feature = "std")] {
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::{Entry as HEnt, OccupiedEntry as HOcc, VacantEntry as HVac};
use std::hash::Hash;
do_impl!(Get for HashSet, HashSet<T>, contains; T: Hash + Eq);
do_impl!(GetEntry for HashMap, HashMap<K, V>,
HEnt, HOcc<'a, K, V>, HVac<'a, K, V>; K: 'a + Hash + Eq, V: 'a);
do_impl!(OccupiedEntry for HOcc, HOcc<'a, K, V>, HashMap<K, V>; K: 'a + Hash + Eq, V: 'a);
do_impl!(VacantEntry for HVac, HVac<'a, K, V>, HashMap<K, V>; K: 'a + Hash + Eq, V: 'a);
}
}