1use core::fmt::Debug;
2use core::mem::ManuallyDrop;
3use core::ops::Add;
4use core::ops::Mul;
5use core::ptr::NonNull;
6
7use allocated::AllocResult;
8use allocator_api2::alloc::Allocator;
9use generic_array::ArrayLength;
10use typenum::Prod;
11use typenum::Sum;
12use typenum::U1;
13use typenum::U2;
14
15use super::node::InsertOption;
16use super::node::InteriorNode;
17use super::node::MutNodeRef;
18use super::node::Node;
19use super::node::NodeEntry;
20use super::node::OccupiedNodeEntry;
21use super::node::VacantNodeEntry;
22use super::AllocatedBTreeMap;
23
24#[allow(clippy::module_name_repetitions)]
29pub enum Entry<'a, 's, A: Allocator, K: core::cmp::PartialOrd + core::fmt::Debug, V, B: ArrayLength>
30where
31 U2: Mul<B>,
32 Prod<U2, B>: ArrayLength,
33 U1: Add<Prod<U2, B>>,
34 Sum<U1, Prod<U2, B>>: ArrayLength,
35{
36 Vacant(VacantEntry<'a, 's, A, K, V, B>),
38 Occupied(OccupiedEntry<'a, 's, A, K, V, B>),
40}
41
42#[allow(clippy::module_name_repetitions)]
45pub struct VacantEntry<
46 'a,
47 's,
48 A: Allocator,
49 K: core::cmp::PartialOrd + core::fmt::Debug,
50 V,
51 B: ArrayLength,
52> where
53 U2: Mul<B>,
54 Prod<U2, B>: ArrayLength,
55 U1: Add<Prod<U2, B>>,
56 Sum<U1, Prod<U2, B>>: ArrayLength,
57{
58 alloc: &'a A,
59 inner: VacantNodeEntry<'s, K, K, V, B, MutNodeRef<'s, K, V, B>>,
60 map: NonNull<AllocatedBTreeMap<K, V, B>>,
61}
62
63#[allow(clippy::module_name_repetitions)]
66pub struct OccupiedEntry<
67 'a,
68 's,
69 A: Allocator,
70 K: core::cmp::PartialOrd + core::fmt::Debug,
71 V,
72 B: ArrayLength,
73> where
74 U2: Mul<B>,
75 Prod<U2, B>: ArrayLength,
76 U1: Add<Prod<U2, B>>,
77 Sum<U1, Prod<U2, B>>: ArrayLength,
78{
79 alloc: &'a A,
80 inner: OccupiedNodeEntry<'s, K, V, B, MutNodeRef<'s, K, V, B>>,
81 map: NonNull<AllocatedBTreeMap<K, V, B>>,
82}
83
84impl<'a, 's, A: Allocator, K: core::cmp::PartialOrd + core::fmt::Debug, V, B: ArrayLength>
85 VacantEntry<'a, 's, A, K, V, B>
86where
87 U2: Mul<B>,
88 Prod<U2, B>: ArrayLength,
89 U1: Add<Prod<U2, B>>,
90 Sum<U1, Prod<U2, B>>: ArrayLength,
91{
92 pub fn key(&self) -> &K {
94 self.inner.key()
95 }
96
97 pub fn into_key(self) -> K {
99 self.inner.into_key()
100 }
101
102 pub fn insert(mut self, value: V) -> AllocResult<Option<V>> {
108 let alloc = self.alloc;
109 let io = self.inner.insert_in(alloc, value)?;
110 match io {
111 InsertOption::NewKey(_) => {
112 unsafe { self.map.as_mut() }.n += 1;
114 Ok(None)
115 }
116 InsertOption::Split((k, v, n)) => {
117 let map = unsafe { self.map.as_mut() };
119
120 let root =
121 InteriorNode::root(alloc, k, v, map.root.take().unwrap(), n.into_inner())?;
122 map.root
123 .replace(ManuallyDrop::new(Node::Interior(ManuallyDrop::into_inner(
124 root.into_inner(),
125 ))));
126 map.n += 1;
127
128 Ok(None)
129 }
130 }
131 }
132}
133
134impl<'a, 's, A: Allocator, K: core::cmp::PartialOrd + core::fmt::Debug, V, B: ArrayLength>
135 OccupiedEntry<'a, 's, A, K, V, B>
136where
137 U2: Mul<B>,
138 Prod<U2, B>: ArrayLength,
139 U1: Add<Prod<U2, B>>,
140 Sum<U1, Prod<U2, B>>: ArrayLength,
141{
142 pub(crate) unsafe fn new(
146 alloc: &'a A,
147 inner: OccupiedNodeEntry<'s, K, V, B, MutNodeRef<'s, K, V, B>>,
148 map: NonNull<AllocatedBTreeMap<K, V, B>>,
149 ) -> Self {
150 OccupiedEntry { alloc, inner, map }
151 }
152
153 #[must_use]
155 pub fn key(&self) -> &K {
156 self.inner.key()
157 }
158
159 #[must_use]
161 pub fn get(&self) -> &V {
162 self.inner.get()
163 }
164
165 pub fn get_mut(&mut self) -> &mut V {
167 self.inner.get_mut()
168 }
169
170 #[must_use]
172 pub fn into_mut(self) -> &'s mut V {
173 self.inner.into_mut()
174 }
175
176 pub fn insert(&mut self, value: V) -> V {
178 self.inner.insert(value)
179 }
180
181 #[must_use]
183 pub fn remove(self) -> V {
184 self.remove_entry().1
185 }
186
187 #[must_use]
189 pub fn remove_entry(mut self) -> (K, V) {
190 let (entry, check_underflow) = unsafe { self.inner.remove(self.alloc) };
192
193 unsafe { self.map.as_mut() }.n -= 1;
195
196 if check_underflow {
197 let map: &mut AllocatedBTreeMap<K, V, B> = unsafe { self.map.as_mut() };
199 let root = map.root.as_mut().unwrap();
200 if root.n_keys() == 0 {
201 let old_root = map.root.take().unwrap();
202 let new_root = match ManuallyDrop::into_inner(old_root) {
203 Node::Interior(mut n) => n.take_child_at_in(self.alloc, 0),
204 Node::Leaf(n) => Node::Leaf(n),
205 };
206 map.root.replace(ManuallyDrop::new(new_root));
207 }
208 }
209
210 entry
211 }
212}
213
214impl<'a, 's, A: Allocator, K: core::cmp::PartialOrd + Debug, V, B: ArrayLength>
215 Entry<'a, 's, A, K, V, B>
216where
217 U2: Mul<B>,
218 Prod<U2, B>: ArrayLength,
219 U1: Add<Prod<U2, B>>,
220 Sum<U1, Prod<U2, B>>: ArrayLength,
221{
222 pub(super) fn new(
223 alloc: &'a A,
224 inner: NodeEntry<'s, K, K, V, B, MutNodeRef<'s, K, V, B>>,
225 map: NonNull<AllocatedBTreeMap<K, V, B>>,
226 ) -> Self {
227 match inner {
228 NodeEntry::Vacant(inner) => Entry::Vacant(VacantEntry { alloc, inner, map }),
229 NodeEntry::Occupied(inner) => Entry::Occupied(OccupiedEntry { alloc, inner, map }),
230 }
231 }
232
233 #[must_use]
235 pub fn and_modify<F>(self, f: F) -> Self
236 where
237 F: FnOnce(&mut V),
238 {
239 match self {
240 Self::Occupied(mut o) => {
241 f(o.get_mut());
242 Self::Occupied(o)
243 }
244 Self::Vacant(v) => Self::Vacant(v),
245 }
246 }
247
248 #[inline]
250 pub fn key(&self) -> &K {
251 match self {
252 Self::Occupied(o) => o.key(),
253 Self::Vacant(v) => v.key(),
254 }
255 }
256
257 pub fn insert(self, v: V) -> AllocResult<Option<V>> {
264 match self {
265 Self::Occupied(mut o) => Ok(Some(o.insert(v))),
266 Self::Vacant(o) => {
267 o.insert(v)?;
268 Ok(None)
269 }
270 }
271 }
272
273 pub fn unwrap_occupied(self) -> OccupiedEntry<'a, 's, A, K, V, B> {
275 match self {
276 Self::Occupied(o) => o,
277 Self::Vacant(_) => panic!("Expected Occupied(_)"),
278 }
279 }
280}