1use super::*;
2use core::ptr::null_mut;
3use pointers::Pointer;
4
5pub struct AvlDrain<'a, P: Pointer, Tag>
8where
9 P::Target: AvlItem<Tag>,
10{
11 tree: &'a mut AvlTree<P, Tag>,
12 parent: *mut P::Target,
13 dir: Option<Dir>,
14}
15
16impl<'a, P: Pointer, Tag> AvlDrain<'a, P, Tag>
17where
18 P::Target: AvlItem<Tag>,
19{
20 #[inline]
21 pub(super) fn new(tree: &'a mut AvlTree<P, Tag>) -> Self {
22 Self { tree, parent: null_mut(), dir: None }
23 }
24}
25
26unsafe impl<'a, P, Tag> Send for AvlDrain<'a, P, Tag>
27where
28 P: Pointer + Send,
29 P::Target: AvlItem<Tag>,
30{
31}
32
33impl<'a, P: Pointer, Tag> Iterator for AvlDrain<'a, P, Tag>
34where
35 P::Target: AvlItem<Tag>,
36{
37 type Item = P;
38
39 fn next(&mut self) -> Option<Self::Item> {
40 if self.tree.root.is_null() {
41 return None;
42 }
43
44 let mut node: *mut P::Target;
45 let parent: *mut P::Target;
46
47 if self.dir.is_none() && self.parent.is_null() {
48 let mut curr = self.tree.root;
50 loop {
51 let left = unsafe { (*curr).get_node().left() };
52 if !left.is_null() {
53 curr = left;
54 } else {
55 break;
56 }
57 }
58 node = curr;
59 } else {
60 parent = self.parent;
61 if parent.is_null() {
62 return None;
64 }
65 let child_dir = self.dir.unwrap();
66 if child_dir == DIR_RIGHT || unsafe { (*parent).get_node().right().is_null() } {
70 node = parent;
71 } else {
72 node = unsafe { (*parent).get_node().right() };
74 loop {
75 let left = unsafe { (*node).get_node().left() };
76 if !left.is_null() {
77 node = left;
78 } else {
79 break;
80 }
81 }
82 }
83 }
84 let right = unsafe { (*node).get_node().right() };
85
86 if !right.is_null() {
88 node = right;
91 }
92
93 let next_parent = unsafe { (*node).get_node().parent };
95 if next_parent.is_null() {
96 self.tree.root = null_mut();
97 self.parent = null_mut();
98 self.dir = Some(DIR_LEFT);
99 } else {
100 self.parent = next_parent;
101 let next_parent_node = unsafe { (*next_parent).get_node() };
102 let _dir = next_parent_node._child_direction(node);
103 next_parent_node.set_child(_dir, null_mut());
105 self.dir = Some(_dir);
106 }
107
108 self.tree.count -= 1;
109 unsafe {
110 (*node).get_node().detach();
111 Some(P::from_raw(node))
112 }
113 }
114}
115
116pub struct AvlIter<'a, P, Tag>
165where
166 P: Pointer,
167 P::Target: AvlItem<Tag>,
168{
169 tree: &'a AvlTree<P, Tag>,
170 cur: Option<NonNull<P::Target>>,
171 dir: Dir,
172 left: usize,
173}
174
175impl<'a, P, Tag> AvlIter<'a, P, Tag>
179where
180 P: Pointer,
181 P::Target: AvlItem<Tag>,
182{
183 #[inline]
184 pub(crate) fn new(
185 tree: &'a AvlTree<P, Tag>, init: Option<NonNull<P::Target>>, dir: Dir,
186 ) -> Self {
187 Self { tree, cur: init, dir, left: tree.len() }
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 = NodeRef<'a, P>;
204
205 fn next(&mut self) -> Option<Self::Item> {
206 let cur: NonNull<P::Target> = self.cur.take()?;
207 self.left -= 1;
208 self.cur = self.tree._walk_dir(cur, self.dir);
209 Some(NodeRef::<'a, P>::new(cur.as_ptr()))
210 }
211}
212
213impl<'a, P, Tag> ExactSizeIterator for AvlIter<'a, P, Tag>
214where
215 P: Pointer,
216 P::Target: AvlItem<Tag>,
217{
218 #[inline]
219 fn len(&self) -> usize {
220 self.left
221 }
222}