use core::fmt::{self, Debug};
use core::marker::PhantomData;
use core::mem;
use crate::{
default::{OrdStoredKey, OrdTotalOrder},
polyfill::*,
};
use super::super::borrow::DormantMutRef;
use super::super::node::{marker, Handle, NodeRef};
use super::BTreeMap;
use Entry::*;
pub enum Entry<'a, K: 'a, V: 'a, O, A: Allocator + Clone = Global> {
Vacant(VacantEntry<'a, K, V, O, A>),
Occupied(OccupiedEntry<'a, K, V, O, A>),
}
impl<K: Debug, V: Debug, O, A: Allocator + Clone> Debug for Entry<'_, K, V, O, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Vacant(ref v) => f.debug_tuple("Entry").field(v).finish(),
Occupied(ref o) => f.debug_tuple("Entry").field(o).finish(),
}
}
}
pub struct VacantEntry<
'a,
K,
V,
O = OrdTotalOrder<<K as OrdStoredKey>::OrdKeyType>,
A: Allocator + Clone = Global,
> {
pub(super) key: K,
pub(super) handle: Option<Handle<NodeRef<marker::Mut<'a>, K, V, marker::Leaf>, marker::Edge>>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, O, A>>,
pub(super) alloc: A,
pub(super) _marker: PhantomData<&'a mut (K, V)>,
}
impl<K: Debug, V, O, A: Allocator + Clone> Debug for VacantEntry<'_, K, V, O, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("VacantEntry").field(self.key()).finish()
}
}
pub struct OccupiedEntry<
'a,
K,
V,
O = OrdTotalOrder<<K as OrdStoredKey>::OrdKeyType>,
A: Allocator + Clone = Global,
> {
pub(super) handle: Handle<NodeRef<marker::Mut<'a>, K, V, marker::LeafOrInternal>, marker::KV>,
pub(super) dormant_map: DormantMutRef<'a, BTreeMap<K, V, O, A>>,
pub(super) alloc: A,
pub(super) _marker: PhantomData<&'a mut (K, V)>,
}
impl<K: Debug, V: Debug, O, A: Allocator + Clone> Debug for OccupiedEntry<'_, K, V, O, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedEntry").field("key", self.key()).field("value", self.get()).finish()
}
}
#[cfg(feature = "map_try_insert")]
pub struct OccupiedError<
'a,
K: 'a,
V: 'a,
O = OrdTotalOrder<<K as OrdStoredKey>::OrdKeyType>,
A: Allocator + Clone = Global,
> {
pub entry: OccupiedEntry<'a, K, V, O, A>,
pub value: V,
}
#[cfg(feature = "map_try_insert")]
impl<K: Debug, V: Debug, O, A: Allocator + Clone> Debug for OccupiedError<'_, K, V, O, A> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("OccupiedError")
.field("key", self.entry.key())
.field("old_value", self.entry.get())
.field("new_value", &self.value)
.finish()
}
}
#[cfg(feature = "map_try_insert")]
impl<'a, K: Debug, V: Debug, O, A: Allocator + Clone> fmt::Display
for OccupiedError<'a, K, V, O, A>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"failed to insert {:?}, key {:?} already exists with value {:?}",
self.value,
self.entry.key(),
self.entry.get(),
)
}
}
#[cfg(feature = "map_try_insert")]
#[cfg(feature = "error_in_core")]
impl<'a, K: core::fmt::Debug, V: core::fmt::Debug, O> core::error::Error
for OccupiedError<'a, K, V, O>
{
#[allow(deprecated)]
fn description(&self) -> &str {
"key already exists"
}
}
impl<'a, K, V, O, A: Allocator + Clone> Entry<'a, K, V, O, A> {
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default),
}
}
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default()),
}
}
#[inline]
pub fn or_insert_with_key<F: FnOnce(&K) -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => {
let value = default(entry.key());
entry.insert(value)
}
}
}
pub fn key(&self) -> &K {
match *self {
Occupied(ref entry) => entry.key(),
Vacant(ref entry) => entry.key(),
}
}
pub fn and_modify<F>(self, f: F) -> Self
where
F: FnOnce(&mut V),
{
match self {
Occupied(mut entry) => {
f(entry.get_mut());
Occupied(entry)
}
Vacant(entry) => Vacant(entry),
}
}
}
impl<'a, K, V: Default, O, A: Allocator + Clone> Entry<'a, K, V, O, A> {
pub fn or_default(self) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(Default::default()),
}
}
}
impl<'a, K, V, O, A: Allocator + Clone> VacantEntry<'a, K, V, O, A> {
pub fn key(&self) -> &K {
&self.key
}
pub fn into_key(self) -> K {
self.key
}
pub fn insert(self, value: V) -> &'a mut V {
let out_ptr = match self.handle {
None => {
let map = unsafe { self.dormant_map.awaken() };
let mut root = NodeRef::new_leaf(self.alloc.clone());
let val_ptr = root.borrow_mut().push(self.key, value) as *mut V;
map.root = Some(root.forget_type());
map.length = 1;
val_ptr
}
Some(handle) => match handle.insert_recursing(self.key, value, self.alloc.clone()) {
(None, val_ptr) => {
let map = unsafe { self.dormant_map.awaken() };
map.length += 1;
val_ptr
}
(Some(ins), val_ptr) => {
drop(ins.left);
let map = unsafe { self.dormant_map.awaken() };
let root = map.root.as_mut().unwrap(); root.push_internal_level(self.alloc).push(ins.kv.0, ins.kv.1, ins.right);
map.length += 1;
val_ptr
}
},
};
unsafe { &mut *out_ptr }
}
}
impl<'a, K, V, O, A: Allocator + Clone> OccupiedEntry<'a, K, V, O, A> {
#[must_use]
pub fn key(&self) -> &K {
self.handle.reborrow().into_kv().0
}
pub fn remove_entry(self) -> (K, V) {
self.remove_kv()
}
#[must_use]
pub fn get(&self) -> &V {
self.handle.reborrow().into_kv().1
}
pub fn get_mut(&mut self) -> &mut V {
self.handle.kv_mut().1
}
#[must_use = "`self` will be dropped if the result is not used"]
pub fn into_mut(self) -> &'a mut V {
self.handle.into_val_mut()
}
pub fn insert(&mut self, value: V) -> V {
mem::replace(self.get_mut(), value)
}
pub fn remove(self) -> V {
self.remove_kv().1
}
pub(super) fn remove_kv(self) -> (K, V) {
let mut emptied_internal_root = false;
let (old_kv, _) =
self.handle.remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
let map = unsafe { self.dormant_map.awaken() };
map.length -= 1;
if emptied_internal_root {
let root = map.root.as_mut().unwrap();
root.pop_internal_level(self.alloc);
}
old_kv
}
}