1use super::*;
2use core::cmp::Ordering;
3use core::fmt::Debug;
4use core::ops::Deref;
5use pointers::{CloneablePointer, Pointer};
6
7pub enum Entry<'a, P, Tag, K>
9where
10 P: Pointer,
11 P::Target: AvlItem<Tag>,
12{
13 Vacant(VacantEntry<'a, P, Tag, K>),
14 Occupied(OccupiedEntry<'a, P, Tag>),
15}
16
17impl<'a, P, Tag, K> Entry<'a, P, Tag, K>
18where
19 P: Pointer,
20 P::Target: AvlItem<Tag>,
21{
22 #[inline]
23 pub fn unwrap_occupied(self) -> OccupiedEntry<'a, P, Tag>
24 where
25 K: Debug,
26 {
27 match self {
28 Self::Occupied(ent) => ent,
29 Self::Vacant(ent) => {
30 panic!("called unwrap_occupied on vacent entry {:?}", ent.key);
31 }
32 }
33 }
34
35 #[inline]
36 pub fn unwrap_vacant(self) -> VacantEntry<'a, P, Tag, K>
37 where
38 P::Target: Debug,
39 {
40 match self {
41 Self::Vacant(ent) => ent,
42 Self::Occupied(ent) => {
43 panic!("called unwrap_occupied on vacent entry {:?}", ent.as_ref());
44 }
45 }
46 }
47
48 #[inline]
49 pub fn try_occupied(self) -> Option<OccupiedEntry<'a, P, Tag>> {
50 match self {
51 Self::Occupied(ent) => Some(ent),
52 Self::Vacant(_ent) => None,
53 }
54 }
55
56 #[inline]
57 pub fn try_vacant(self) -> Option<VacantEntry<'a, P, Tag, K>> {
58 match self {
59 Self::Vacant(ent) => Some(ent),
60 Self::Occupied(_ent) => None,
61 }
62 }
63}
64
65impl<'a, P, Tag, K> From<Entry<'a, P, Tag, K>> for Option<OccupiedEntry<'a, P, Tag>>
66where
67 P: Pointer,
68 P::Target: AvlItem<Tag>,
69{
70 #[inline]
71 fn from(ent: Entry<'a, P, Tag, K>) -> Option<OccupiedEntry<'a, P, Tag>> {
72 ent.try_occupied()
73 }
74}
75
76impl<'a, P, Tag, K> From<Entry<'a, P, Tag, K>> for Option<VacantEntry<'a, P, Tag, K>>
77where
78 P: Pointer,
79 P::Target: AvlItem<Tag>,
80{
81 #[inline]
82 fn from(ent: Entry<'a, P, Tag, K>) -> Option<VacantEntry<'a, P, Tag, K>> {
83 ent.try_vacant()
84 }
85}
86
87pub struct Last();
89
90impl fmt::Debug for Last {
91 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
92 write!(f, "last")
93 }
94}
95
96impl<'a, P, Tag> Entry<'a, P, Tag, Last>
97where
98 P: Pointer,
99 P::Target: AvlItem<Tag>,
100{
101 pub unsafe fn append_unchecked(self, node: P) -> Self {
110 match self {
111 Self::Occupied(ent) => Self::Occupied(unsafe { ent.insert_move_next_unchecked(node) }),
112 Self::Vacant(ent) => {
113 debug_assert!(
114 ent.node.is_null(),
115 "can only append to VacantEntry when tree is empty"
116 );
117 debug_assert_eq!(ent.direction, DIR_RIGHT);
118 let p = node.into_raw() as *mut P::Target;
119 ent.tree._insert(p, null_mut(), DIR_RIGHT);
120 Self::Occupied(OccupiedEntry {
121 node: unsafe { NonNull::new_unchecked(p) },
122 tree: ent.tree,
123 })
124 }
125 }
126 }
127
128 pub fn append<F>(self, node: P, cmp_f: F) -> Result<Self, P>
138 where
139 F: FnOnce(&P::Target, &P::Target) -> Ordering,
140 {
141 match self {
142 Self::Occupied(ent) => {
143 if cmp_f(ent.get(), node.as_ref()) == Ordering::Less {
144 Ok(Self::Occupied(unsafe { ent.insert_move_next_unchecked(node) }))
145 } else {
146 Err(node)
147 }
148 }
149 Self::Vacant(ent) => {
150 debug_assert!(
151 ent.node.is_null(),
152 "can only append to VacantEntry when tree is empty"
153 );
154 debug_assert_eq!(ent.direction, DIR_RIGHT);
155 let p = node.into_raw() as *mut P::Target;
156 ent.tree._insert(p, null_mut(), DIR_RIGHT);
157 Ok(Self::Occupied(OccupiedEntry {
158 node: unsafe { NonNull::new_unchecked(p) },
159 tree: ent.tree,
160 }))
161 }
162 }
163 }
164}
165
166pub struct First();
168
169impl fmt::Debug for First {
170 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
171 write!(f, "first")
172 }
173}
174
175impl<'a, P, Tag> Entry<'a, P, Tag, First>
176where
177 P: Pointer,
178 P::Target: AvlItem<Tag>,
179{
180 pub unsafe fn prepend_unchecked(self, node: P) -> Self {
189 match self {
190 Self::Occupied(ent) => Self::Occupied(unsafe { ent.insert_move_prev_unchecked(node) }),
191 Self::Vacant(ent) => {
192 debug_assert!(
193 ent.node.is_null(),
194 "can only append to VacantEntry when tree is empty"
195 );
196 debug_assert_eq!(ent.direction, DIR_LEFT);
197 let p = node.into_raw() as *mut P::Target;
198 ent.tree._insert(p, null_mut(), DIR_LEFT);
199 Self::Occupied(OccupiedEntry {
200 node: unsafe { NonNull::new_unchecked(p) },
201 tree: ent.tree,
202 })
203 }
204 }
205 }
206
207 pub fn prepend<F>(self, node: P, cmp_f: F) -> Result<Self, P>
217 where
218 F: FnOnce(&P::Target, &P::Target) -> Ordering,
219 {
220 match self {
221 Self::Occupied(ent) => {
222 if cmp_f(node.as_ref(), ent.get()) == Ordering::Less {
223 Ok(Self::Occupied(unsafe { ent.insert_move_prev_unchecked(node) }))
224 } else {
225 Err(node)
226 }
227 }
228 Self::Vacant(ent) => {
229 debug_assert!(
230 ent.node.is_null(),
231 "can only append to VacantEntry when tree is empty"
232 );
233 debug_assert_eq!(ent.direction, DIR_LEFT);
234 let p = node.into_raw() as *mut P::Target;
235 ent.tree._insert(p, null_mut(), DIR_LEFT);
236 Ok(Self::Occupied(OccupiedEntry {
237 node: unsafe { NonNull::new_unchecked(p) },
238 tree: ent.tree,
239 }))
240 }
241 }
242 }
243}
244
245pub struct OccupiedEntry<'a, P, Tag>
246where
247 P: Pointer,
248 P::Target: AvlItem<Tag>,
249{
250 pub(crate) node: NonNull<P::Target>,
252 pub(crate) tree: &'a mut AvlTree<P, Tag>,
253}
254
255impl<'a, P, Tag> OccupiedEntry<'a, P, Tag>
256where
257 P: Pointer,
258 P::Target: AvlItem<Tag>,
259{
260 #[inline]
261 pub fn get(&self) -> &'a P::Target {
262 unsafe { self.node.as_ref() }
263 }
264
265 #[inline]
266 pub fn clone_ref(&self) -> P
267 where
268 P: CloneablePointer,
269 {
270 unsafe { CloneablePointer::from_raw_and_clone(self.node.as_ptr()) }
271 }
272
273 #[inline]
275 pub fn remove(self) -> P {
276 let p = self.node.as_ptr();
277 unsafe {
278 self.tree._remove(p);
279 P::from_raw(p)
280 }
281 }
282
283 #[inline]
285 pub fn remove_prev(&mut self) -> Option<P> {
286 if let Some(prev) = AvlTree::<P, Tag>::_walk_dir(self.node, DIR_LEFT) {
287 unsafe {
288 self.tree._remove(prev.as_ptr());
289 return Some(P::from_raw(prev.as_ptr()));
290 }
291 }
292 None
293 }
294
295 #[inline]
297 pub fn remove_next(&mut self) -> Option<P> {
298 if let Some(next) = AvlTree::<P, Tag>::_walk_dir(self.node, DIR_RIGHT) {
299 unsafe {
300 self.tree._remove(next.as_ptr());
301 return Some(P::from_raw(next.as_ptr()));
302 }
303 }
304 None
305 }
306
307 #[inline]
308 pub fn peek_prev(&self) -> Option<&'a P::Target> {
309 if let Some(p) = AvlTree::<P, Tag>::_walk_dir(self.node, DIR_LEFT) {
310 Some(unsafe { p.as_ref() })
311 } else {
312 None
313 }
314 }
315
316 #[inline]
317 pub fn peek_next(&self) -> Option<&'a P::Target> {
318 if let Some(p) = AvlTree::<P, Tag>::_walk_dir(self.node, DIR_RIGHT) {
319 Some(unsafe { p.as_ref() })
320 } else {
321 None
322 }
323 }
324
325 #[inline]
326 pub fn move_prev(mut self) -> Option<Self> {
327 if let Some(p) = AvlTree::<P, Tag>::_walk_dir(self.node, DIR_LEFT) {
328 self.node = p;
329 Some(self)
330 } else {
331 None
332 }
333 }
334
335 #[inline]
336 pub fn move_next(mut self) -> Option<Self> {
337 if let Some(p) = AvlTree::<P, Tag>::_walk_dir(self.node, DIR_RIGHT) {
338 self.node = p;
339 Some(self)
340 } else {
341 None
342 }
343 }
344
345 #[inline]
355 pub unsafe fn insert_prev_unchecked(&mut self, new_node: P) {
356 unsafe {
357 let new_ptr = new_node.into_raw() as *mut P::Target;
358 self.tree._insert_here(new_ptr, self.node, DIR_LEFT);
359 }
360 }
361
362 #[inline]
372 pub unsafe fn insert_move_prev_unchecked(self, new_node: P) -> Self {
373 unsafe {
374 let new_ptr = new_node.into_raw() as *mut P::Target;
375 self.tree._insert_here(new_ptr, self.node, DIR_LEFT);
376 Self { node: NonNull::new_unchecked(new_ptr), tree: self.tree }
377 }
378 }
379
380 #[inline]
390 pub unsafe fn insert_next_unchecked(&mut self, new_node: P) {
391 unsafe {
392 let new_ptr = new_node.into_raw() as *mut P::Target;
393 self.tree._insert_here(new_ptr, self.node, DIR_RIGHT);
394 }
395 }
396
397 #[inline]
407 pub unsafe fn insert_move_next_unchecked(self, new_node: P) -> Self {
408 unsafe {
409 let new_ptr = new_node.into_raw() as *mut P::Target;
410 self.tree._insert_here(new_ptr, self.node, DIR_RIGHT);
411 Self { node: NonNull::new_unchecked(new_ptr), tree: self.tree }
412 }
413 }
414}
415
416impl<'a, P, Tag> Deref for OccupiedEntry<'a, P, Tag>
417where
418 P: Pointer,
419 P::Target: AvlItem<Tag>,
420{
421 type Target = P::Target;
422
423 #[inline]
424 fn deref(&self) -> &Self::Target {
425 self.as_ref()
426 }
427}
428
429impl<'a, P, Tag> AsRef<P::Target> for OccupiedEntry<'a, P, Tag>
430where
431 P: Pointer,
432 P::Target: AvlItem<Tag>,
433{
434 #[inline]
435 fn as_ref(&self) -> &P::Target {
436 Self::get(self)
437 }
438}
439
440pub struct VacantEntry<'a, P, Tag, K>
476where
477 P: Pointer,
478 P::Target: AvlItem<Tag>,
479{
480 pub(crate) node: *mut P::Target,
481 pub(crate) direction: Dir,
482 pub(crate) tree: &'a mut AvlTree<P, Tag>,
483 pub(crate) key: K,
484}
485
486impl<'a, P, Tag, K> VacantEntry<'a, P, Tag, K>
487where
488 P: Pointer,
489 P::Target: AvlItem<Tag>,
490{
491 #[inline(always)]
493 pub fn nearest(&self) -> Option<&P::Target> {
494 if !self.node.is_null() { unsafe { self.node.as_ref() } } else { None }
495 }
496
497 #[inline]
498 pub fn peek_prev(&self) -> Option<&P::Target> {
499 if !self.node.is_null() {
500 unsafe {
501 if self.direction == DIR_RIGHT {
502 return Some(&*self.node);
503 } else if let Some(node) =
504 AvlTree::<P, Tag>::_walk_dir(NonNull::new_unchecked(self.node), DIR_LEFT)
505 {
506 return Some(node.as_ref());
507 }
508 }
509 }
510 None
511 }
512
513 #[inline]
514 pub fn key(&self) -> &K {
515 &self.key
516 }
517
518 #[inline]
519 pub fn peek_next(&self) -> Option<&P::Target> {
520 if !self.node.is_null() {
521 unsafe {
522 if self.direction == DIR_LEFT {
523 return Some(&*self.node);
524 } else if let Some(node) =
525 AvlTree::<P, Tag>::_walk_dir(NonNull::new_unchecked(self.node), DIR_RIGHT)
526 {
527 return Some(node.as_ref());
528 }
529 }
530 }
531 None
532 }
533
534 #[inline]
535 pub fn move_prev(self) -> Option<OccupiedEntry<'a, P, Tag>> {
536 if !self.node.is_null() {
537 unsafe {
538 let p = NonNull::new_unchecked(self.node);
539 if self.direction == DIR_RIGHT {
540 return Some(OccupiedEntry { node: p, tree: self.tree });
541 } else if let Some(node) = AvlTree::<P, Tag>::_walk_dir(p, DIR_LEFT) {
542 return Some(OccupiedEntry { node, tree: self.tree });
543 }
544 }
545 }
546 None
547 }
548
549 #[inline]
550 pub fn move_next(self) -> Option<OccupiedEntry<'a, P, Tag>> {
551 if !self.node.is_null() {
552 unsafe {
553 let p = NonNull::new_unchecked(self.node);
554 if self.direction == DIR_LEFT {
555 return Some(OccupiedEntry { node: p, tree: self.tree });
556 } else if let Some(node) = AvlTree::<P, Tag>::_walk_dir(p, DIR_RIGHT) {
557 return Some(OccupiedEntry { node, tree: self.tree });
558 }
559 }
560 }
561 None
562 }
563
564 #[inline]
570 pub unsafe fn insert_node_unchecked(self, new_node: P) -> OccupiedEntry<'a, P, Tag> {
571 let new_ptr = new_node.into_raw() as *mut P::Target;
572 self.tree._insert(new_ptr, self.node, self.direction);
573 OccupiedEntry { node: unsafe { NonNull::new_unchecked(new_ptr) }, tree: self.tree }
574 }
575}
576
577impl<'a, P, Tag, K> VacantEntry<'a, P, Tag, K>
578where
579 P: Pointer,
580 P::Target: AvlItem<Tag> + Borrow<K>,
581 K: PartialEq,
582{
583 #[inline]
589 pub fn insert_node(self, new_node: P) -> OccupiedEntry<'a, P, Tag> {
590 debug_assert!(&self.key == new_node.as_ref().borrow());
591 let new_ptr = new_node.into_raw() as *mut P::Target;
592 self.tree._insert(new_ptr, self.node, self.direction);
593 OccupiedEntry { node: unsafe { NonNull::new_unchecked(new_ptr) }, tree: self.tree }
594 }
595}