litcheck_lit/test/
list.rs1use std::sync::Arc;
2
3use intrusive_collections::{intrusive_adapter, LinkedList, LinkedListAtomicLink};
4
5use super::Test;
6
7pub type TestCursor<'a> = intrusive_collections::linked_list::Cursor<'a, TestAdapter>;
8
9intrusive_adapter!(pub TestAdapter = Arc<Test>: Test { link: LinkedListAtomicLink });
10
11#[derive(Default)]
12pub struct TestList {
13 len: usize,
14 tests: LinkedList<TestAdapter>,
15}
16impl TestList {
17 pub fn is_empty(&self) -> bool {
18 self.tests.is_empty()
19 }
20
21 pub fn len(&self) -> usize {
22 self.len
23 }
24
25 #[allow(unused)]
26 pub fn front(&self) -> TestCursor<'_> {
27 self.tests.front()
28 }
29
30 #[allow(unused)]
31 pub fn back(&self) -> TestCursor<'_> {
32 self.tests.back()
33 }
34
35 pub fn front_mut(&mut self) -> TestCursorMut<'_> {
36 TestCursorMut {
37 len: &mut self.len,
38 pos: 0,
39 tests: self.tests.front_mut(),
40 }
41 }
42
43 #[allow(unused)]
44 pub fn back_mut(&mut self) -> TestCursorMut<'_> {
45 TestCursorMut {
46 len: &mut self.len,
47 pos: 0,
48 tests: self.tests.back_mut(),
49 }
50 }
51
52 pub fn pop_front(&mut self) -> Option<Arc<Test>> {
53 let test = self.tests.pop_front();
54 if test.is_some() {
55 self.len -= 1;
56 }
57 test
58 }
59
60 pub fn pop_back(&mut self) -> Option<Arc<Test>> {
61 let test = self.tests.pop_back();
62 if test.is_some() {
63 self.len -= 1;
64 }
65 test
66 }
67
68 pub fn clear(&mut self) {
69 self.len = 0;
70 self.tests.clear();
71 }
72
73 pub fn iter(&self) -> Iter<'_> {
74 Iter::new(self.len, self.tests.front())
75 }
76
77 pub fn push_back(&mut self, test: Arc<Test>) {
78 self.len += 1;
79 self.tests.push_back(test);
80 }
81
82 pub fn append(&mut self, tests: Self) {
83 self.len += tests.len;
84 self.tests.back_mut().splice_after(tests.tests);
85 }
86}
87
88pub struct TestCursorMut<'a> {
89 len: &'a mut usize,
90 pos: usize,
91 tests: intrusive_collections::linked_list::CursorMut<'a, TestAdapter>,
92}
93impl<'a> TestCursorMut<'a> {
94 pub fn is_null(&self) -> bool {
95 self.tests.is_null()
96 }
97
98 #[allow(unused)]
99 pub fn get(&self) -> Option<&Test> {
100 self.tests.get()
101 }
102
103 pub fn move_next(&mut self) {
104 if self.pos == *self.len {
105 assert!(self.tests.is_null());
106 self.tests.move_next();
107 self.pos = 0;
108 } else {
109 self.tests.move_next();
110 self.pos += 1;
111 }
112 }
113
114 #[allow(unused)]
115 pub fn move_prev(&mut self) {
116 if self.pos == *self.len {
117 assert!(self.tests.is_null());
118 self.tests.move_prev();
119 self.pos = self.len.saturating_sub(1);
120 } else if self.pos == 0 {
121 self.tests.move_prev();
122 self.pos = *self.len;
123 } else {
124 self.tests.move_prev();
125 self.pos -= 1;
126 }
127 }
128
129 #[allow(unused)]
130 pub fn remove(&mut self) -> Option<Arc<Test>> {
131 let test = self.tests.remove();
132 if test.is_some() {
133 *self.len -= 1;
134 }
135 test
136 }
137
138 #[allow(unused)]
139 pub fn insert_after(&mut self, test: Arc<Test>) {
140 if self.pos == *self.len {
141 self.pos += 1;
142 }
143 *self.len += 1;
144 self.tests.insert_after(test);
145 }
146
147 #[allow(unused)]
148 pub fn insert_before(&mut self, test: Arc<Test>) {
149 *self.len += 1;
150 self.pos += 1;
151 self.tests.insert_before(test);
152 }
153
154 pub fn split_after(&mut self) -> TestList {
155 let len = *self.len;
156 if len == 0 {
157 TestList::default()
158 } else if self.pos == len {
159 let tests = self.tests.split_after();
160 *self.len = 0;
161 self.pos = 0;
162 TestList { len, tests }
163 } else {
164 let tests = self.tests.split_after();
165 let new_len = self.pos + 1;
166 *self.len = new_len;
167 TestList {
168 len: len - new_len,
169 tests,
170 }
171 }
172 }
173
174 #[allow(unused)]
175 pub fn splice_after(&mut self, list: TestList) {
176 if self.pos == *self.len {
177 self.pos += 1;
178 }
179 *self.len += list.len;
180 self.tests.splice_after(list.tests);
181 }
182
183 #[allow(unused)]
184 pub fn splice_before(&mut self, list: TestList) {
185 self.pos += 1;
186 *self.len += list.len;
187 self.tests.splice_before(list.tests);
188 }
189}
190impl IntoIterator for TestList {
191 type Item = Arc<Test>;
192 type IntoIter = Drain;
193
194 #[inline]
195 fn into_iter(self) -> Self::IntoIter {
196 Drain::new(self)
197 }
198}
199impl rayon::iter::IntoParallelIterator for TestList {
200 type Item = Arc<Test>;
201 type Iter = Drain;
202
203 #[inline]
204 fn into_par_iter(self) -> Self::Iter {
205 Drain::new(self)
206 }
207}
208
209pub struct Iter<'a> {
210 range: core::ops::Range<usize>,
211 cursor: TestCursor<'a>,
212}
213impl<'a> Iter<'a> {
214 fn new(len: usize, cursor: TestCursor<'a>) -> Self {
215 Self {
216 range: 0..len,
217 cursor,
218 }
219 }
220}
221impl<'a> core::iter::FusedIterator for Iter<'a> {}
222impl<'a> ExactSizeIterator for Iter<'a> {
223 #[inline(always)]
224 fn len(&self) -> usize {
225 self.range.len()
226 }
227}
228impl<'a> Iterator for Iter<'a> {
229 type Item = Arc<Test>;
230
231 fn next(&mut self) -> Option<Self::Item> {
232 self.range.next()?;
233 let test = self.cursor.clone_pointer();
234 self.cursor.move_next();
235 test
236 }
237}
238impl<'a> DoubleEndedIterator for Iter<'a> {
239 fn next_back(&mut self) -> Option<Self::Item> {
240 self.range.next_back()?;
241 let test = self.cursor.clone_pointer();
242 self.cursor.move_prev();
243 test
244 }
245}
246
247pub struct Drain {
248 tests: TestList,
249}
250impl Drain {
251 pub fn new(tests: TestList) -> Self {
252 Self { tests }
253 }
254}
255impl core::iter::FusedIterator for Drain {}
256impl ExactSizeIterator for Drain {
257 #[inline(always)]
258 fn len(&self) -> usize {
259 self.tests.len()
260 }
261}
262impl Iterator for Drain {
263 type Item = Arc<Test>;
264
265 #[inline(always)]
266 fn next(&mut self) -> Option<Self::Item> {
267 self.tests.pop_front()
268 }
269}
270impl DoubleEndedIterator for Drain {
271 #[inline(always)]
272 fn next_back(&mut self) -> Option<Self::Item> {
273 self.tests.pop_back()
274 }
275}
276impl rayon::iter::plumbing::Producer for Drain {
277 type Item = Arc<Test>;
278 type IntoIter = Drain;
279
280 #[inline(always)]
281 fn into_iter(self) -> Self::IntoIter {
282 self
283 }
284
285 fn split_at(mut self, index: usize) -> (Self, Self) {
286 if self.tests.is_empty() {
287 return (self, Drain::new(Default::default()));
288 }
289 assert!(index < self.tests.len());
290 let mut cursor = self.tests.front_mut();
291 for _ in 0..index {
292 cursor.move_next();
293 }
294 assert!(!cursor.is_null());
295 let split = cursor.split_after();
296 (self, Self { tests: split })
297 }
298}
299impl rayon::iter::plumbing::UnindexedProducer for Drain {
300 type Item = Arc<Test>;
301
302 fn split(self) -> (Self, Option<Self>) {
303 use rayon::iter::plumbing::Producer;
304
305 let len = self.tests.len();
306 if len < 2 {
307 return (self, None);
308 }
309 let (a, b) = self.split_at(len / 2);
310 (a, Some(b))
311 }
312
313 fn fold_with<F>(self, folder: F) -> F
314 where
315 F: rayon::iter::plumbing::Folder<Self::Item>,
316 {
317 folder.consume_iter(self)
318 }
319}
320impl rayon::iter::ParallelIterator for Drain {
321 type Item = Arc<Test>;
322
323 fn drive_unindexed<C>(self, consumer: C) -> C::Result
324 where
325 C: rayon::iter::plumbing::UnindexedConsumer<Self::Item>,
326 {
327 rayon::iter::plumbing::bridge(self, consumer)
328 }
329
330 #[inline(always)]
331 fn opt_len(&self) -> Option<usize> {
332 Some(self.tests.len())
333 }
334}
335impl rayon::iter::IndexedParallelIterator for Drain {
336 fn drive<C>(self, consumer: C) -> C::Result
337 where
338 C: rayon::iter::plumbing::Consumer<Self::Item>,
339 {
340 rayon::iter::plumbing::bridge(self, consumer)
341 }
342
343 #[inline(always)]
344 fn len(&self) -> usize {
345 self.tests.len()
346 }
347
348 fn with_producer<CB>(self, callback: CB) -> CB::Output
349 where
350 CB: rayon::iter::plumbing::ProducerCallback<Self::Item>,
351 {
352 callback.callback(self)
353 }
354}