embed_collections/avl/
iter.rs1use super::*;
2use crate::Pointer;
3use core::mem::MaybeUninit;
4use core::ptr::null;
5
6pub struct AvlDrain<'a, P: Pointer, Tag>
9where
10 P::Target: AvlItem<Tag>,
11{
12 tree: &'a mut AvlTree<P, Tag>,
13 parent: *const P::Target,
14 dir: Option<AvlDirection>,
15}
16
17impl<'a, P: Pointer, Tag> AvlDrain<'a, P, Tag>
18where
19 P::Target: AvlItem<Tag>,
20{
21 #[inline]
22 pub(super) fn new(tree: &'a mut AvlTree<P, Tag>) -> Self {
23 Self { tree, parent: null(), dir: None }
24 }
25}
26
27unsafe impl<'a, P, Tag> Send for AvlDrain<'a, P, Tag>
28where
29 P: Pointer + Send,
30 P::Target: AvlItem<Tag>,
31{
32}
33
34impl<'a, P: Pointer, Tag> Iterator for AvlDrain<'a, P, Tag>
35where
36 P::Target: AvlItem<Tag>,
37{
38 type Item = P;
39
40 fn next(&mut self) -> Option<Self::Item> {
41 if self.tree.root.is_null() {
42 return None;
43 }
44
45 let mut node: *const P::Target;
46 let parent: *const P::Target;
47
48 if self.dir.is_none() && self.parent.is_null() {
49 let mut curr = self.tree.root;
51 while unsafe { !(*curr).get_node().left.is_null() } {
52 curr = unsafe { (*curr).get_node().left };
53 }
54 node = curr;
55 } else {
56 parent = self.parent;
57 if parent.is_null() {
58 return None;
60 }
61
62 let child_dir = self.dir.unwrap();
63 if child_dir == AvlDirection::Right || unsafe { (*parent).get_node().right.is_null() } {
67 node = parent;
68 } else {
69 node = unsafe { (*parent).get_node().right };
71 while unsafe { !(*node).get_node().left.is_null() } {
72 node = unsafe { (*node).get_node().left };
73 }
74 }
75 }
76
77 if unsafe { !(*node).get_node().right.is_null() } {
79 node = unsafe { (*node).get_node().right };
82 }
83
84 let next_parent = unsafe { (*node).get_node().parent };
86 if next_parent.is_null() {
87 self.tree.root = null();
88 self.parent = null();
89 self.dir = Some(AvlDirection::Left);
90 } else {
91 self.parent = next_parent;
92 self.dir = Some(self.tree.parent_direction(node, next_parent));
93 unsafe { (*next_parent).get_node().set_child(self.dir.unwrap(), null()) };
95 }
96
97 self.tree.count -= 1;
98 unsafe {
99 (*node).get_node().detach();
100 Some(P::from_raw(node))
101 }
102 }
103}
104
105pub struct AvlIter<'a, P, Tag>
106where
107 P: Pointer,
108 P::Target: AvlItem<Tag>,
109{
110 tree: &'a AvlTree<P, Tag>,
111 cur: Option<NonNull<P::Target>>,
112 dir: AvlDirection,
113 temp: MaybeUninit<P>,
114}
115
116impl<'a, P, Tag> AvlIter<'a, P, Tag>
122where
123 P: Pointer,
124 P::Target: AvlItem<Tag>,
125{
126 #[inline]
127 pub(crate) fn new(
128 tree: &'a AvlTree<P, Tag>, init: Option<NonNull<P::Target>>, dir: AvlDirection,
129 ) -> Self {
130 Self { tree, cur: init, dir, temp: MaybeUninit::uninit() }
131 }
132
133 #[inline]
182 pub fn next_ref(&mut self) -> Option<&P> {
183 let cur: NonNull<P::Target> = self.cur.take()?;
184 self.temp.write(unsafe { P::from_raw(cur.as_ptr()) });
185 let p = self.tree.walk_dir(cur, self.dir);
186 self.cur = p;
187 Some(unsafe { self.temp.assume_init_ref() })
188 }
189}
190
191unsafe impl<'a, P, Tag> Send for AvlIter<'a, P, Tag>
192where
193 P: Pointer + Send,
194 P::Target: AvlItem<Tag>,
195{
196}
197
198impl<'a, P, Tag> Iterator for AvlIter<'a, P, Tag>
199where
200 P: Pointer,
201 P::Target: AvlItem<Tag>,
202{
203 type Item = &'a P::Target;
204
205 fn next(&mut self) -> Option<Self::Item> {
206 let cur: NonNull<P::Target> = self.cur.take()?;
207 let p = self.tree.walk_dir(cur, self.dir);
208 self.cur = p;
209 Some(unsafe { cur.as_ref() })
210 }
211}