1use super::*;
2use core::fmt::Debug;
3use core::ops::Deref;
4use pointers::{CloneablePointer, Pointer};
5
6pub enum Entry<'a, P, Tag, K>
8where
9 P: Pointer,
10 P::Target: AvlItem<Tag>,
11{
12 Vacant(VacantEntry<'a, P, Tag, K>),
13 Occupied(OccupiedEntry<'a, P, Tag>),
14}
15
16impl<'a, P, Tag, K> Entry<'a, P, Tag, K>
17where
18 P: Pointer,
19 P::Target: AvlItem<Tag>,
20{
21 #[inline]
22 pub fn unwrap_occupied(self) -> OccupiedEntry<'a, P, Tag>
23 where
24 K: Debug,
25 {
26 match self {
27 Self::Occupied(ent) => ent,
28 Self::Vacant(ent) => {
29 panic!("called unwrap_occupied on vacent entry {:?}", ent.key);
30 }
31 }
32 }
33
34 #[inline]
35 pub fn unwrap_vacant(self) -> VacantEntry<'a, P, Tag, K>
36 where
37 P::Target: Debug,
38 {
39 match self {
40 Self::Vacant(ent) => ent,
41 Self::Occupied(ent) => {
42 panic!("called unwrap_occupied on vacent entry {:?}", ent.as_ref());
43 }
44 }
45 }
46}
47
48pub struct OccupiedEntry<'a, P, Tag>
49where
50 P: Pointer,
51 P::Target: AvlItem<Tag>,
52{
53 pub(crate) node: NonNull<P::Target>,
55 pub(crate) tree: &'a mut AvlTree<P, Tag>,
56}
57
58impl<'a, P, Tag> OccupiedEntry<'a, P, Tag>
59where
60 P: Pointer,
61 P::Target: AvlItem<Tag>,
62{
63 #[inline]
64 pub fn get(&self) -> &'a P::Target {
65 unsafe { self.node.as_ref() }
66 }
67
68 #[inline]
69 pub fn clone_ref(&self) -> P
70 where
71 P: CloneablePointer,
72 {
73 unsafe { CloneablePointer::from_raw_and_clone(self.node.as_ptr()) }
74 }
75
76 #[inline]
78 pub fn remove(self) -> P {
79 let p = self.node.as_ptr();
80 unsafe {
81 self.tree._remove(p);
82 P::from_raw(p)
83 }
84 }
85
86 #[inline]
88 pub fn remove_prev(&mut self) -> Option<P> {
89 if let Some(prev) = self.tree._walk_dir(self.node, DIR_LEFT) {
90 unsafe {
91 self.tree._remove(prev.as_ptr());
92 return Some(P::from_raw(prev.as_ptr()));
93 }
94 }
95 None
96 }
97
98 #[inline]
100 pub fn remove_next(&mut self) -> Option<P> {
101 if let Some(next) = self.tree._walk_dir(self.node, DIR_RIGHT) {
102 unsafe {
103 self.tree._remove(next.as_ptr());
104 return Some(P::from_raw(next.as_ptr()));
105 }
106 }
107 None
108 }
109
110 #[inline]
111 pub fn peek_prev(&self) -> Option<&'a P::Target> {
112 if let Some(p) = self.tree._walk_dir(self.node, DIR_LEFT) {
113 Some(unsafe { p.as_ref() })
114 } else {
115 None
116 }
117 }
118
119 #[inline]
120 pub fn peek_next(&self) -> Option<&'a P::Target> {
121 if let Some(p) = self.tree._walk_dir(self.node, DIR_RIGHT) {
122 Some(unsafe { p.as_ref() })
123 } else {
124 None
125 }
126 }
127
128 #[inline]
129 pub fn move_prev(mut self) -> Option<Self> {
130 if let Some(p) = self.tree._walk_dir(self.node, DIR_LEFT) {
131 self.node = p;
132 Some(self)
133 } else {
134 None
135 }
136 }
137
138 #[inline]
139 pub fn move_next(mut self) -> Option<Self> {
140 if let Some(p) = self.tree._walk_dir(self.node, DIR_RIGHT) {
141 self.node = p;
142 Some(self)
143 } else {
144 None
145 }
146 }
147
148 #[inline]
158 pub unsafe fn insert_prev_unchecked(&mut self, new_node: P) {
159 unsafe {
160 let new_ptr = new_node.into_raw() as *mut P::Target;
161 self.tree._insert_here(new_ptr, self.node, DIR_LEFT);
162 }
163 }
164
165 #[inline]
175 pub unsafe fn insert_move_prev_unchecked(self, new_node: P) -> Self {
176 unsafe {
177 let new_ptr = new_node.into_raw() as *mut P::Target;
178 self.tree._insert_here(new_ptr, self.node, DIR_LEFT);
179 Self { node: NonNull::new_unchecked(new_ptr), tree: self.tree }
180 }
181 }
182
183 #[inline]
193 pub unsafe fn insert_next_unchecked(&mut self, new_node: P) {
194 unsafe {
195 let new_ptr = new_node.into_raw() as *mut P::Target;
196 self.tree._insert_here(new_ptr, self.node, DIR_RIGHT);
197 }
198 }
199
200 #[inline]
210 pub unsafe fn insert_move_next_unchecked(self, new_node: P) -> Self {
211 unsafe {
212 let new_ptr = new_node.into_raw() as *mut P::Target;
213 self.tree._insert_here(new_ptr, self.node, DIR_RIGHT);
214 Self { node: NonNull::new_unchecked(new_ptr), tree: self.tree }
215 }
216 }
217}
218
219impl<'a, P, Tag> Deref for OccupiedEntry<'a, P, Tag>
220where
221 P: Pointer,
222 P::Target: AvlItem<Tag>,
223{
224 type Target = P::Target;
225
226 #[inline]
227 fn deref(&self) -> &Self::Target {
228 self.as_ref()
229 }
230}
231
232impl<'a, P, Tag> AsRef<P::Target> for OccupiedEntry<'a, P, Tag>
233where
234 P: Pointer,
235 P::Target: AvlItem<Tag>,
236{
237 #[inline]
238 fn as_ref(&self) -> &P::Target {
239 Self::get(self)
240 }
241}
242
243pub struct VacantEntry<'a, P, Tag, K>
279where
280 P: Pointer,
281 P::Target: AvlItem<Tag>,
282{
283 pub(crate) node: *mut P::Target,
284 pub(crate) direction: Dir,
285 pub(crate) tree: &'a mut AvlTree<P, Tag>,
286 pub(crate) key: K,
287}
288
289impl<'a, P, Tag, K> VacantEntry<'a, P, Tag, K>
290where
291 P: Pointer,
292 P::Target: AvlItem<Tag>,
293{
294 #[inline(always)]
296 pub fn nearest(&self) -> Option<&P::Target> {
297 if !self.node.is_null() { unsafe { self.node.as_ref() } } else { None }
298 }
299
300 #[inline]
301 pub fn peek_prev(&self) -> Option<&P::Target> {
302 if !self.node.is_null() {
303 unsafe {
304 if self.direction == DIR_RIGHT {
305 return Some(&*self.node);
306 } else if let Some(node) =
307 self.tree._walk_dir(NonNull::new_unchecked(self.node), DIR_LEFT)
308 {
309 return Some(node.as_ref());
310 }
311 }
312 }
313 None
314 }
315
316 #[inline]
317 pub fn key(&self) -> &K {
318 &self.key
319 }
320
321 #[inline]
322 pub fn peek_next(&self) -> Option<&P::Target> {
323 if !self.node.is_null() {
324 unsafe {
325 if self.direction == DIR_LEFT {
326 return Some(&*self.node);
327 } else if let Some(node) =
328 self.tree._walk_dir(NonNull::new_unchecked(self.node), DIR_RIGHT)
329 {
330 return Some(node.as_ref());
331 }
332 }
333 }
334 None
335 }
336
337 #[inline]
338 pub fn move_prev(self) -> Option<OccupiedEntry<'a, P, Tag>> {
339 if !self.node.is_null() {
340 unsafe {
341 let p = NonNull::new_unchecked(self.node);
342 if self.direction == DIR_RIGHT {
343 return Some(OccupiedEntry { node: p, tree: self.tree });
344 } else if let Some(node) = self.tree._walk_dir(p, DIR_LEFT) {
345 return Some(OccupiedEntry { node, tree: self.tree });
346 }
347 }
348 }
349 None
350 }
351
352 #[inline]
353 pub fn move_next(self) -> Option<OccupiedEntry<'a, P, Tag>> {
354 if !self.node.is_null() {
355 unsafe {
356 let p = NonNull::new_unchecked(self.node);
357 if self.direction == DIR_LEFT {
358 return Some(OccupiedEntry { node: p, tree: self.tree });
359 } else if let Some(node) = self.tree._walk_dir(p, DIR_RIGHT) {
360 return Some(OccupiedEntry { node, tree: self.tree });
361 }
362 }
363 }
364 None
365 }
366
367 #[inline]
373 pub unsafe fn insert_node_unchecked(self, new_node: P) -> OccupiedEntry<'a, P, Tag> {
374 let new_ptr = new_node.into_raw() as *mut P::Target;
375 self.tree._insert(new_ptr, self.node, self.direction);
376 OccupiedEntry { node: unsafe { NonNull::new_unchecked(new_ptr) }, tree: self.tree }
377 }
378}
379
380impl<'a, P, Tag, K> VacantEntry<'a, P, Tag, K>
381where
382 P: Pointer,
383 P::Target: AvlItem<Tag> + Borrow<K>,
384 K: PartialEq,
385{
386 #[inline]
392 pub fn insert_node(self, new_node: P) -> OccupiedEntry<'a, P, Tag> {
393 debug_assert!(&self.key == new_node.as_ref().borrow());
394 let new_ptr = new_node.into_raw() as *mut P::Target;
395 self.tree._insert(new_ptr, self.node, self.direction);
396 OccupiedEntry { node: unsafe { NonNull::new_unchecked(new_ptr) }, tree: self.tree }
397 }
398}