1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
use super::BacktrackingRecorder;
use super::BacktrackingState::*;
pub struct ReferencingBacktrackingIterator<'record, Iter> where Iter: Iterator {
recorder: &'record mut BacktrackingRecorder<Iter>,
}
impl<'record, Iter> ReferencingBacktrackingIterator<'record, Iter> where Iter: Iterator {
pub(crate) fn new(recorder: &'record mut BacktrackingRecorder<Iter>) -> Self {
ReferencingBacktrackingIterator {
recorder,
}
}
}
impl<'record, Iter> Iterator for ReferencingBacktrackingIterator<'record, Iter> where Iter: Iterator, Iter::Item: 'record {
type Item = &'record Iter::Item;
fn next(&mut self) -> Option<&'record Iter::Item> {
macro_rules! unsafe_backtracking_index {
($index:expr) => {
unsafe {
&*(&self.recorder.backtracking_vec[$index] as *const Iter::Item)
}
};
}
use crate::{Backtracking, Progressing};
match self.recorder.state {
Progressing => {
if let Some(val) = self.recorder.iterator.next() {
self.recorder.backtracking_vec.push(val);
Some(unsafe_backtracking_index!(self.recorder.backtracking_vec.len() - 1))
} else {
None
}
},
Backtracking { position } => {
if position >= self.recorder.backtracking_vec.len() {
self.recorder.state = Progressing;
self.next()
} else {
let new_position = position + 1;
self.recorder.state = Backtracking { position: new_position };
Some(unsafe_backtracking_index!(position))
}
},
}
}
}
use super::BacktrackingIterator;
impl<'record, Iter> BacktrackingIterator for ReferencingBacktrackingIterator<'record, Iter> where Iter: Iterator {
type RefPoint = usize;
fn get_ref_point(&self) -> usize {
match self.recorder.state {
Progressing => self.recorder.backtracking_vec.len(),
Backtracking { position } => position,
}
}
fn get_oldest_point(&self) -> usize {
0_usize
}
fn backtrack(&mut self, position: usize) {
self.recorder.state = Backtracking { position };
}
}
use super::Walkbackable;
impl<'history, 'record, Iter: 'history> Walkbackable<'history> for ReferencingBacktrackingIterator<'record, Iter> where Iter: Iterator, 'history : 'record {
type RefPoint = usize;
type Item = &'record Iter::Item;
type Walkback = ReferencingWalkback<'record, Iter>;
fn walk_back(&'history self) -> ReferencingWalkback<'record, Iter> where {
ReferencingWalkback::new(self)
}
}
pub struct ReferencingWalkback<'record, Iter> where Iter: Iterator {
backtracker: &'record BacktrackingRecorder<Iter>,
reverse_position: usize,
}
impl<'record, Iter> ReferencingWalkback<'record, Iter>
where Iter: Iterator, Iter::Item: 'record {
fn new<'history>(backtracker: &'history ReferencingBacktrackingIterator<'record, Iter>) -> Self where 'history : 'record {
let history_len = backtracker.recorder.backtracking_vec.len();
ReferencingWalkback {
backtracker: backtracker.recorder,
reverse_position: history_len,
}
}
}
use super::Walkback;
impl<'history, 'record, Iter> Walkback<'history> for ReferencingWalkback<'record, Iter>
where Iter: Iterator, 'history : 'record {
type RefPoint = usize;
fn get_ref_point(&self) -> usize {
self.reverse_position
}
}
impl<'history, 'record, Iter> Iterator for ReferencingWalkback<'record, Iter>
where Iter: Iterator, Iter::Item: 'record, 'history : 'record {
type Item = &'record Iter::Item;
fn next(&mut self) -> Option<Self::Item> {
if self.reverse_position == 0 {
None
} else {
let new_position = self.reverse_position - 1_usize;
let val = &self.backtracker.backtracking_vec[new_position];
self.reverse_position = new_position;
Some(val)
}
}
}