1use std::cell::Cell;
33
34
35pub struct Node<'a, T: 'a> {
37 parent: Cell<Option<&'a Node<'a, T>>>,
38 previous_sibling: Cell<Option<&'a Node<'a, T>>>,
39 next_sibling: Cell<Option<&'a Node<'a, T>>>,
40 first_child: Cell<Option<&'a Node<'a, T>>>,
41 last_child: Cell<Option<&'a Node<'a, T>>>,
42 pub data: T,
43}
44
45
46fn same_ref<T>(a: &T, b: &T) -> bool {
47 a as *const T == b as *const T
48}
49
50trait Take<T> {
51 fn take(&self) -> Option<T>;
52}
53
54impl<T: Copy> Take<T> for Cell<Option<T>> {
55 fn take(&self) -> Option<T> {
56 let value = self.get();
57 self.set(None);
58 value
59 }
60}
61
62impl<'a, T> Node<'a, T> {
63 pub fn new(data: T) -> Node<'a, T> {
68 Node {
69 parent: Cell::new(None),
70 first_child: Cell::new(None),
71 last_child: Cell::new(None),
72 previous_sibling: Cell::new(None),
73 next_sibling: Cell::new(None),
74 data: data,
75 }
76 }
77
78 pub fn parent(&self) -> Option<&'a Node<'a, T>> {
80 self.parent.get()
81 }
82
83 pub fn first_child(&self) -> Option<&'a Node<'a, T>> {
85 self.first_child.get()
86 }
87
88 pub fn last_child(&self) -> Option<&'a Node<'a, T>> {
90 self.last_child.get()
91 }
92
93 pub fn previous_sibling(&self) -> Option<&'a Node<'a, T>> {
95 self.previous_sibling.get()
96 }
97
98 pub fn next_sibling(&self) -> Option<&'a Node<'a, T>> {
100 self.next_sibling.get()
101 }
102
103 pub fn same_node(&self, other: &Node<'a, T>) -> bool {
105 same_ref(self, other)
106 }
107
108 pub fn ancestors(&'a self) -> Ancestors<'a, T> {
112 Ancestors(Some(self))
113 }
114
115 pub fn preceding_siblings(&'a self) -> PrecedingSiblings<'a, T> {
119 PrecedingSiblings(Some(self))
120 }
121
122 pub fn following_siblings(&'a self) -> FollowingSiblings<'a, T> {
126 FollowingSiblings(Some(self))
127 }
128
129 pub fn children(&'a self) -> Children<'a, T> {
131 Children(self.first_child.get())
132 }
133
134 pub fn reverse_children(&'a self) -> ReverseChildren<'a, T> {
136 ReverseChildren(self.last_child.get())
137 }
138
139 pub fn descendants(&'a self) -> Descendants<'a, T> {
144 Descendants(self.traverse())
145 }
146
147 pub fn traverse(&'a self) -> Traverse<'a, T> {
149 Traverse {
150 root: self,
151 next: Some(NodeEdge::Start(self)),
152 }
153 }
154
155 pub fn reverse_traverse(&'a self) -> ReverseTraverse<'a, T> {
157 ReverseTraverse {
158 root: self,
159 next: Some(NodeEdge::End(self)),
160 }
161 }
162
163 pub fn detach(&self) {
165 let parent = self.parent.take();
166 let previous_sibling = self.previous_sibling.take();
167 let next_sibling = self.next_sibling.take();
168
169 if let Some(next_sibling) = next_sibling {
170 next_sibling.previous_sibling.set(previous_sibling);
171 } else if let Some(parent) = parent {
172 parent.last_child.set(previous_sibling);
173 }
174
175 if let Some(previous_sibling) = previous_sibling {
176 previous_sibling.next_sibling.set(next_sibling);
177 } else if let Some(parent) = parent {
178 parent.first_child.set(next_sibling);
179 }
180 }
181
182 pub fn append(&'a self, new_child: &'a Node<'a, T>) {
184 new_child.detach();
185 new_child.parent.set(Some(self));
186 if let Some(last_child) = self.last_child.take() {
187 new_child.previous_sibling.set(Some(last_child));
188 debug_assert!(last_child.next_sibling.get().is_none());
189 last_child.next_sibling.set(Some(new_child));
190 } else {
191 debug_assert!(self.first_child.get().is_none());
192 self.first_child.set(Some(new_child));
193 }
194 self.last_child.set(Some(new_child));
195 }
196
197 pub fn prepend(&'a self, new_child: &'a Node<'a, T>) {
199 new_child.detach();
200 new_child.parent.set(Some(self));
201 if let Some(first_child) = self.first_child.take() {
202 debug_assert!(first_child.previous_sibling.get().is_none());
203 first_child.previous_sibling.set(Some(new_child));
204 new_child.next_sibling.set(Some(first_child));
205 } else {
206 debug_assert!(self.first_child.get().is_none());
207 self.last_child.set(Some(new_child));
208 }
209 self.first_child.set(Some(new_child));
210 }
211
212 pub fn insert_after(&'a self, new_sibling: &'a Node<'a, T>) {
214 new_sibling.detach();
215 new_sibling.parent.set(self.parent.get());
216 new_sibling.previous_sibling.set(Some(self));
217 if let Some(next_sibling) = self.next_sibling.take() {
218 debug_assert!(same_ref(next_sibling.previous_sibling.get().unwrap(), self));
219 next_sibling.previous_sibling.set(Some(new_sibling));
220 new_sibling.next_sibling.set(Some(next_sibling));
221 } else if let Some(parent) = self.parent.get() {
222 debug_assert!(same_ref(parent.last_child.get().unwrap(), self));
223 parent.last_child.set(Some(new_sibling));
224 }
225 self.next_sibling.set(Some(new_sibling));
226 }
227
228 pub fn insert_before(&'a self, new_sibling: &'a Node<'a, T>) {
230 new_sibling.detach();
231 new_sibling.parent.set(self.parent.get());
232 new_sibling.next_sibling.set(Some(self));
233 if let Some(previous_sibling) = self.previous_sibling.take() {
234 new_sibling.previous_sibling.set(Some(previous_sibling));
235 debug_assert!(same_ref(previous_sibling.next_sibling.get().unwrap(), self));
236 previous_sibling.next_sibling.set(Some(new_sibling));
237 } else if let Some(parent) = self.parent.get() {
238 debug_assert!(same_ref(parent.first_child.get().unwrap(), self));
239 parent.first_child.set(Some(new_sibling));
240 }
241 self.previous_sibling.set(Some(new_sibling));
242 }
243}
244
245
246macro_rules! axis_iterator {
247 (#[$attr:meta] $name: ident: $next: ident) => {
248 #[$attr]
249 pub struct $name<'a, T: 'a>(Option<&'a Node<'a, T>>);
250
251 impl<'a, T> Iterator for $name<'a, T> {
252 type Item = &'a Node<'a, T>;
253
254 fn next(&mut self) -> Option<&'a Node<'a, T>> {
255 match self.0.take() {
256 Some(node) => {
257 self.0 = node.$next.get();
258 Some(node)
259 }
260 None => None
261 }
262 }
263 }
264 }
265}
266
267axis_iterator! {
268 #[doc = "An iterator of references to the ancestors a given node."]
269 Ancestors: parent
270}
271
272axis_iterator! {
273 #[doc = "An iterator of references to the siblings before a given node."]
274 PrecedingSiblings: previous_sibling
275}
276
277axis_iterator! {
278 #[doc = "An iterator of references to the siblings after a given node."]
279 FollowingSiblings: next_sibling
280}
281
282axis_iterator! {
283 #[doc = "An iterator of references to the children of a given node."]
284 Children: next_sibling
285}
286
287axis_iterator! {
288 #[doc = "An iterator of references to the children of a given node, in reverse order."]
289 ReverseChildren: previous_sibling
290}
291
292
293pub struct Descendants<'a, T: 'a>(Traverse<'a, T>);
295
296impl<'a, T> Iterator for Descendants<'a, T> {
297 type Item = &'a Node<'a, T>;
298
299 fn next(&mut self) -> Option<&'a Node<'a, T>> {
300 loop {
301 match self.0.next() {
302 Some(NodeEdge::Start(node)) => return Some(node),
303 Some(NodeEdge::End(_)) => {}
304 None => return None
305 }
306 }
307 }
308}
309
310
311#[derive(Debug, Clone)]
312pub enum NodeEdge<T> {
313 Start(T),
317
318 End(T),
322}
323
324macro_rules! traverse_iterator {
325 (#[$attr:meta] $name: ident: $first_child: ident, $next_sibling: ident) => {
326 #[$attr]
327 pub struct $name<'a, T: 'a> {
328 root: &'a Node<'a, T>,
329 next: Option<NodeEdge<&'a Node<'a, T>>>,
330 }
331
332 impl<'a, T> Iterator for $name<'a, T> {
333 type Item = NodeEdge<&'a Node<'a, T>>;
334
335 fn next(&mut self) -> Option<NodeEdge<&'a Node<'a, T>>> {
336 match self.next.take() {
337 Some(item) => {
338 self.next = match item {
339 NodeEdge::Start(node) => {
340 match node.$first_child.get() {
341 Some(child) => Some(NodeEdge::Start(child)),
342 None => Some(NodeEdge::End(node))
343 }
344 }
345 NodeEdge::End(node) => {
346 if node.same_node(self.root) {
347 None
348 } else {
349 match node.$next_sibling.get() {
350 Some(sibling) => Some(NodeEdge::Start(sibling)),
351 None => match node.parent.get() {
352 Some(parent) => Some(NodeEdge::End(parent)),
353
354 None => None
359 }
360 }
361 }
362 }
363 };
364 Some(item)
365 }
366 None => None
367 }
368 }
369 }
370 }
371}
372
373traverse_iterator! {
374 #[doc = "An iterator of the start and end edges of a given node and its descendants, in tree order."]
375 Traverse: first_child, next_sibling
376}
377
378traverse_iterator! {
379 #[doc = "An iterator of the start and end edges of a given node and its descendants, in reverse tree order."]
380 ReverseTraverse: last_child, previous_sibling
381}
382
383
384#[cfg(test)]
385extern crate typed_arena;
386
387#[test]
388fn it_works() {
389 struct DropTracker<'a>(&'a Cell<u32>);
390 impl<'a> Drop for DropTracker<'a> {
391 fn drop(&mut self) {
392 self.0.set(self.0.get() + 1);
393 }
394 }
395
396 let drop_counter = Cell::new(0);
397 {
398 let mut new_counter = 0;
399 let arena = typed_arena::Arena::new();
400 let mut new = || {
401 new_counter += 1;
402 arena.alloc(Node::new((new_counter, DropTracker(&drop_counter))))
403 };
404
405 let a = new(); a.append(new()); a.append(new()); a.prepend(new()); let b = new(); b.append(a);
411 a.insert_before(new()); a.insert_before(new()); a.insert_after(new()); a.insert_after(new()); let c = new(); b.append(c);
417
418 assert_eq!(drop_counter.get(), 0);
419 c.previous_sibling.get().unwrap().detach();
420 assert_eq!(drop_counter.get(), 0);
421
422 assert_eq!(b.descendants().map(|node| node.data.0).collect::<Vec<_>>(), [
423 5, 6, 7, 1, 4, 2, 3, 9, 10
424 ]);
425 }
426
427 assert_eq!(drop_counter.get(), 10);
428}