litcheck_lit/test/
list.rs

1use 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}