1use prelude::*;
2use std::marker::PhantomData;
3
4#[derive(Clone, Debug, Eq, Hash, PartialEq)]
6pub struct TreeCursor<'n: 'f, 'f, N: 'n> {
7 root: PhantomData<&'n N>,
8 frozen: PhantomData<&'f ()>,
9 stack: Vec<(*const N, usize)>,
10}
11
12impl<'n, N: 'n> TreeCursor<'n, 'n, N> {
13 pub fn new(root: &'n N) -> Self {
15 Self {
16 root: PhantomData,
17 frozen: PhantomData,
18 stack: vec![(root as *const N, 0)],
19 }
20 }
21}
22
23impl<'n: 'f, 'f, N: 'n> TreeCursor<'n, 'f, N> {
24 fn top(&self) -> &(*const N, usize) {
25 self.stack.last().unwrap()
26 }
27
28 fn top_mut(&mut self) -> &mut (*const N, usize) {
29 self.stack.last_mut().unwrap()
30 }
31
32 fn down_map_ptr<F>(&mut self, f: F) -> Option<*const N>
33 where
34 F: Fn(&'n N, usize) -> Option<&'n N>,
35 {
36 let idx = self.top().1;
37 let here_ptr = self.get() as *const N;
38 let new_ptr =
39 f(unsafe { here_ptr.as_ref().unwrap() }, idx)? as *const N;
40 self.top_mut().1 += 1;
41 Some(new_ptr)
42 }
43
44 pub fn down_map<F>(&mut self, f: F) -> bool
49 where
50 F: Fn(&'n N, usize) -> Option<&'n N>,
51 {
52 let maybe_new_ptr = self.down_map_ptr(f);
53 if let &Some(new_ptr) = &maybe_new_ptr {
54 self.stack.push((new_ptr, 0));
55 }
56 maybe_new_ptr.is_some()
57 }
58
59 pub fn down_map_new<'s, F>(&'s mut self, f: F)
64 -> Option<TreeCursor<'n, 's, N>>
65 where
66 F: Fn(&'n N, usize) -> Option<&'n N>,
67 {
68 let new_ptr = self.down_map_ptr(f)?;
69 Some(Self {
70 root: PhantomData,
71 frozen: PhantomData,
72 stack: vec![(new_ptr, 0)],
73 })
74 }
75
76 pub fn zero(&mut self) {
78 self.top_mut().1 = 0;
79 }
80
81 pub fn up(&mut self) -> bool {
87 if self.stack.len() == 1 {
88 self.stack[0].1 = 0;
89 false
90 } else {
91 self.stack.pop().unwrap();
92 true
93 }
94 }
95
96 pub fn take<'s>(&'s mut self) -> Option<TreeCursor<'n, 's, N>> {
100 if self.stack.len() == 1 {
101 None
102 } else {
103 let (old_ptr, old_idx) = self.stack.pop().unwrap();
104 let old = unsafe { old_ptr.as_ref().unwrap() };
105 Some(Self {
106 root: PhantomData,
107 frozen: PhantomData,
108 stack: vec![(old, old_idx)],
109 })
110 }
111 }
112
113 pub fn get(&self) -> &N {
115 let here: *const N = self.top().0;
116 unsafe { here.as_ref().unwrap() }
117 }
118}
119
120impl<'n: 'f, 'f, N: 'n + Down> TreeCursor<'n, 'f, N> {
121 fn down_ptr(&mut self) -> Option<*const N> {
122 let idx = self.top().1;
123 let new_ptr = self.get().down(idx)? as *const N;
124 self.top_mut().1 += 1;
125 Some(new_ptr)
126 }
127
128 pub fn down(&mut self) -> bool {
134 let maybe_new_ptr = self.down_ptr();
135 if let &Some(new_ptr) = &maybe_new_ptr {
136 self.stack.push((new_ptr, 0));
137 }
138 maybe_new_ptr.is_some()
139 }
140
141 pub fn down_new<'s>(&'s mut self) -> Option<TreeCursor<'n, 's, N>> {
147 let new_ptr = self.down_ptr()?;
148 Some(Self {
149 root: PhantomData,
150 frozen: PhantomData,
151 stack: vec![(new_ptr, 0)],
152 })
153 }
154}
155
156impl<'n: 'f, 'f, N: 'n> From<TreeCursorMut<'n, 'f, N>>
157 for TreeCursor<'n, 'f, N>
158{
159 fn from(mut cm: TreeCursorMut<'n, 'f, N>) -> Self {
160 TreeCursor {
161 root: PhantomData,
162 frozen: PhantomData,
163 stack: cm.stack.drain(..).map(|(p, n)| (p as *const N, n))
164 .collect(), }
166 }
167}
168
169#[derive(Debug, Eq, Hash, PartialEq)]
171pub struct TreeCursorMut<'n: 'f, 'f, N: 'n> {
172 root: PhantomData<&'n mut N>,
173 frozen: PhantomData<&'f ()>,
174 stack: Vec<(*mut N, usize)>,
175}
176
177impl<'n, N: 'n> TreeCursorMut<'n, 'n, N> {
178 pub fn new(root: &'n mut N) -> Self {
180 Self {
181 root: PhantomData,
182 frozen: PhantomData,
183 stack: vec![(root as *mut N, 0)],
184 }
185 }
186}
187
188impl<'n: 'f, 'f, N: 'n> TreeCursorMut<'n, 'f, N> {
189 fn top(&self) -> &(*mut N, usize) {
190 self.stack.last().unwrap()
191 }
192
193 fn top_mut(&mut self) -> &mut (*mut N, usize) {
194 self.stack.last_mut().unwrap()
195 }
196
197 fn down_map_ptr<F>(&mut self, f: F) -> Option<*mut N>
198 where
199 F: Fn(&'n mut N, usize) -> Option<&'n mut N>,
200 {
201 let idx = self.top().1;
202 let here_ptr = self.get_mut() as *mut N;
203 let new_ptr = f(unsafe { here_ptr.as_mut().unwrap() }, idx)? as *mut N;
204 self.top_mut().1 += 1;
205 Some(new_ptr)
206 }
207
208 pub fn down_map<F>(&mut self, f: F) -> bool
213 where
214 F: Fn(&'n mut N, usize) -> Option<&'n mut N>,
215 {
216 let maybe_new_ptr = self.down_map_ptr(f);
217 if let &Some(new_ptr) = &maybe_new_ptr {
218 self.stack.push((new_ptr, 0));
219 }
220 maybe_new_ptr.is_some()
221 }
222
223 pub fn down_map_new<'s, F>(&'s mut self, f: F)
228 -> Option<TreeCursorMut<'n, 's, N>>
229 where
230 F: Fn(&'n mut N, usize) -> Option<&'n mut N>,
231 {
232 let new_ptr = self.down_map_ptr(f)?;
233 Some(Self {
234 root: PhantomData,
235 frozen: PhantomData,
236 stack: vec![(new_ptr, 0)],
237 })
238 }
239
240 pub fn zero(&mut self) {
242 self.top_mut().1 = 0;
243 }
244
245 pub fn up(&mut self) -> bool {
251 if self.stack.len() == 1 {
252 self.stack[0].1 = 0;
253 false
254 } else {
255 self.stack.pop().unwrap();
256 true
257 }
258 }
259
260 pub fn take<'s>(&'s mut self) -> Option<TreeCursorMut<'n, 's, N>> {
264 if self.stack.len() == 1 {
265 None
266 } else {
267 let (old_ptr, old_idx) = self.stack.pop().unwrap();
268 let old = unsafe { old_ptr.as_mut().unwrap() };
269 Some(Self {
270 root: PhantomData,
271 frozen: PhantomData,
272 stack: vec![(old, old_idx)],
273 })
274 }
275 }
276
277 pub fn get(&self) -> &N {
279 let here: *const N = self.top().0;
280 (unsafe { here.as_ref() }).unwrap()
281 }
282
283 pub fn get_mut(&mut self) -> &mut N {
285 let here = self.top().0;
286 (unsafe { here.as_mut() }).unwrap()
287 }
288
289 pub fn as_cursor<'s>(&'s self) -> TreeCursor<'n, 's, N> {
290 TreeCursor {
291 root: PhantomData,
292 frozen: PhantomData,
293 stack: self.stack.iter()
294 .map(|&(p, n)| (p as *const N, n)).collect(),
295 }
296 }
297}
298
299pub struct TreeCursorPos(Vec<usize>);
301
302impl<'n: 'f, 'f, N: 'n + DownMut> TreeCursorMut<'n, 'f, N> {
303 pub fn pos(&self) -> TreeCursorPos {
308 TreeCursorPos(self.stack.iter().map(|&(_, idx)| idx).collect())
309 }
310
311 pub fn set_pos(&mut self, pos: &TreeCursorPos) {
325 self.stack.truncate(1);
326 for &idx in pos.0.iter().rev().skip(1).rev() { self.top_mut().1 = idx - 1;
328 if !self.down() {
329 panic!("missing node in TreeCursorPos");
330 }
331 }
332 let &idx = pos.0.last().unwrap();
333 self.top_mut().1 = idx;
334 }
335
336 fn down_ptr(&mut self) -> Option<*mut N> {
337 let idx = self.stack.last().unwrap().1;
338 let new_ptr = self.get_mut().down_mut(idx)? as *mut N;
339 self.stack.last_mut().unwrap().1 += 1;
340 Some(new_ptr)
341 }
342
343 pub fn down(&mut self) -> bool {
349 let maybe_new_ptr = self.down_ptr();
350 if let &Some(new_ptr) = &maybe_new_ptr {
351 self.stack.push((new_ptr, 0));
352 }
353 maybe_new_ptr.is_some()
354 }
355
356 pub fn down_new<'s>(&'s mut self) -> Option<TreeCursorMut<'n, 's, N>> {
362 let new_ptr = self.down_ptr()?;
363 Some(Self {
364 root: PhantomData,
365 frozen: PhantomData,
366 stack: vec![(new_ptr, 0)],
367 })
368 }
369}