blend_rs/blend/traverse/
double_linked.rs1use std::marker::PhantomData;
2use crate::blend::{GeneratedBlendStruct, PointerLike, PointerTarget, Reader};
3
4pub trait DoubleLinked<Ptr> : Sized + PointerTarget<Self>
5where Ptr: PointerLike<Self> {
6 fn next(&self) -> &Ptr;
7 fn prev(&self) -> &Ptr;
8}
9
10pub struct DoubleLinkedIter<'a, D, Ptr>
11where D: 'a + DoubleLinked<Ptr> + GeneratedBlendStruct,
12 Ptr: PointerLike<D> {
13 reader: &'a Reader<'a>,
14 first: &'a D,
15 next: Option<&'a D>,
16 d_phantom: PhantomData<&'a D>,
17 p_phantom: PhantomData<&'a Ptr>,
18}
19
20impl<'a, D, Ptr> DoubleLinkedIter<'a, D, Ptr>
21where D: 'a + DoubleLinked<Ptr> + GeneratedBlendStruct,
22 Ptr: PointerLike<D> {
23
24 pub fn new(reader: &'a Reader<'a>, first: &'a D) -> Self {
25 DoubleLinkedIter {
26 reader,
27 first,
28 next: Some(first),
29 d_phantom: Default::default(),
30 p_phantom: Default::default(),
31 }
32 }
33
34 pub fn find<P>(&self, predicate: P) -> Option<&'a D>
35 where P: Fn(&'a D) -> bool {
36 let mut current = self.first;
37 loop {
38 if predicate(current) {
39 return Some(current)
40 }
41 else {
42 if let Some(next) = self.reader.deref_single(¤t.next().as_instance_of::<D>()).ok() {
43 current = next
44 }
45 else {
46 return None
47 }
48 }
49 }
50 }
51}
52
53impl <'a, D, Ptr> Iterator for DoubleLinkedIter<'a, D, Ptr>
54where D: 'a + DoubleLinked<Ptr> + GeneratedBlendStruct,
55 Ptr: PointerLike<D> {
56
57 type Item = &'a D;
58
59 fn next(&mut self) -> Option<Self::Item> {
60 let result = self.next;
61 self.next = self.next
62 .map(|current| {
63 self.reader.deref_single(¤t.next().as_instance_of::<D>()).ok()
64 })
65 .flatten();
66 result
67 }
68}