Skip to main content

cdll/head/
cursor.rs

1use {super::ListHead, crate::CircularList, alloc::vec::Vec};
2
3/// A `Cursor` is like an iterator, except that it can freely seek back-and-forth.
4/// This `struct` is constructed by the [`CircularList::cursor`](CircularList::cursor)
5/// function.
6#[derive(Clone, Copy)]
7pub struct Cursor<'life, T> {
8    list: &'life CircularList<T>,
9    // Invariant (4): `current` is a valid pointer.
10    current: *const ListHead<T>,
11}
12
13impl<'life, T> PartialEq for Cursor<'life, T> {
14    fn eq(&self, other: &Self) -> bool {
15        self.list.head == other.list.head && self.current == other.current
16    }
17}
18
19impl<'life, T> Cursor<'life, T> {
20    /// Builds a `Cursor` from a (valid) pointer to a `ListHead<T>`.
21    /// # Panics
22    /// This function panics if the list is empty.
23    pub(crate) fn from_list(list: &'life CircularList<T>) -> Self {
24        if list.is_empty() {
25            // Preserving the invariant (4)
26            panic!("Cannot build a `Cursor` from an empty list.");
27        }
28        Self {
29            list,
30            current: list.head,
31        }
32    }
33
34    /// Returns a reference of the underlying list.
35    pub fn list(&self) -> &CircularList<T> {
36        self.list
37    }
38
39    /// Returns to its initial position (the head of the list).
40    pub fn reset(&mut self) {
41        self.current = self.list.head;
42    }
43
44    /// Moves the cursor to the next element of the `CircularList`.
45    pub fn move_next(&mut self) {
46        unsafe {
47            // SAFETY: Invariants (3) and (4) assert that `self.current` is a valid pointer to
48            // a valid circular linked list
49            self.current = (*self.current).next;
50        }
51    }
52
53    /// Moves the cursor to the previous element of the `CircularList`.
54    pub fn move_prev(&mut self) {
55        unsafe {
56            // SAFETY: Invariants (3) and (4) assert that `self.current` is a valid pointer to
57            // a valid circular linked list
58            self.current = (*self.current).prev;
59        }
60    }
61
62    /// Returns the value of the list element behind the cursor.
63    pub fn value(&self) -> &T {
64        // SAFETY: Invariant (4) asserts that `current` is a valid pointer to a `ListHead<T>`.
65        unsafe { (*self.current).value() }
66    }
67}
68
69impl<'life, T: core::fmt::Debug> core::fmt::Debug for Cursor<'life, T> {
70    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
71        self.value().fmt(f)
72    }
73}
74
75impl<'life, T: core::fmt::Display> core::fmt::Display for Cursor<'life, T> {
76    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77        self.value().fmt(f)
78    }
79}
80
81/// A `DoubleCursor` is a `struct` that points to 2 elements 'a' and 'b' of a [`CircularList`].
82/// One can then [`swap`](`Self::swap`) the 2 elements or put the first after the second etc.
83#[derive(Debug)]
84pub struct DoubleCursor<'life, T> {
85    list: &'life mut CircularList<T>,
86    // Invariant (5):
87    // * `a` and `b` are always valid pointers
88    // * The `idx_a` and `idx_b` are always equal to the number of (forward) steps between the
89    // head and the position of `a` and `b` respectively
90    a: *const ListHead<T>,
91    b: *const ListHead<T>,
92    idx_a: usize,
93    idx_b: usize,
94    stack: Vec<(*const ListHead<T>, usize)>,
95}
96
97// Private functions
98impl<'life, T> DoubleCursor<'life, T> {
99    /// Builds a `DoubleCursor` from a [`CircularList`].
100    /// # Panics
101    /// This function panics if the list is empty.
102    pub(crate) fn from_list(list: &'life mut CircularList<T>) -> Self {
103        if list.is_empty() {
104            // Preserving the invariant (5)
105            panic!("Cannot build a `DoubleCursor` from an empty list.");
106        }
107        let head = list.head;
108        Self {
109            list,
110            a: head,
111            b: head,
112            idx_a: 0,
113            idx_b: 0,
114            stack: Vec::new(),
115        }
116    }
117
118    /// Returns a reference of the underlying list.
119    pub fn list(&self) -> &CircularList<T> {
120        self.list
121    }
122
123    /// Cuts the list at `new_head` and create a new list from there.
124    ///
125    /// # Note
126    /// The `DoubleCursor` is consumed in the operation.
127    ///
128    /// # Safety
129    /// The caller must assert that `new_head` is a valid pointer to a `ListHead` that is a member
130    /// of the same list as `self.list`. The `idx` must correspond to the index of `new_head` in
131    /// `self.list`.
132    unsafe fn split_at(self, new_head: *mut ListHead<T>, idx: usize) -> CircularList<T> {
133        let head = self.list.head as *mut _;
134        if head == new_head {
135            return core::mem::take(self.list);
136        }
137
138        // SAFETY: `head` must be a valid pointer since a double cursor cannot be created from
139        // an empty list.
140        ListHead::<T>::split(head, new_head);
141
142        // The `new_head` is wrapped in a new `CircularList` to satisfy the safety condition of
143        // `ListHead::split`.
144        let new_list = CircularList {
145            head: new_head,
146            length: self.list.length - idx,
147        };
148        self.list.length = idx;
149        new_list
150    }
151}
152
153impl<'life, T> DoubleCursor<'life, T> {
154    /// Returns `true` if the 'a' cursor points to the same element as the 'b cursor.
155    pub fn a_is_b(&self) -> bool {
156        self.a == self.b
157    }
158
159    /// Moves the 'a' cursor to the next element of the `CircularList`.
160    pub fn move_next_a(&mut self) {
161        unsafe {
162            // SAFETY: Invariants (3) and (5) assert that `self.a` is a valid pointer to
163            // a valid circular linked list
164            self.a = (*self.a).next;
165        }
166        self.idx_a = (self.idx_a + 1) % self.list.len();
167    }
168
169    /// Moves the 'b' cursor to the next element of the `CircularList`.
170    pub fn move_next_b(&mut self) {
171        unsafe {
172            // SAFETY: Invariants (3) and (5) assert that `self.b` is a valid pointer to
173            // a valid circular linked list
174            self.b = (*self.b).next;
175        }
176        self.idx_b = (self.idx_b + 1) % self.list.len();
177    }
178
179    /// Moves the 'a' cursor to the previous element of the `CircularList`.
180    pub fn move_prev_a(&mut self) {
181        unsafe {
182            // SAFETY: Invariants (3) and (5) assert that `self.a` is a valid pointer to
183            // a valid circular linked list
184            self.a = (*self.a).prev;
185        }
186        let len = self.list.len();
187        self.idx_a = (len + self.idx_a - 1) % len;
188    }
189
190    /// Moves the 'b' cursor to the previous element of the `CircularList`.
191    pub fn move_prev_b(&mut self) {
192        unsafe {
193            // SAFETY: Invariants (3) and (5) assert that `self.b` is a valid pointer to
194            // a valid circular linked list
195            self.b = (*self.b).prev;
196        }
197        let len = self.list.len();
198        self.idx_b = (len + self.idx_b - 1) % len;
199    }
200
201    /// Returns the value of the list element behind the 'a' cursor.
202    pub fn value_a(&self) -> &T {
203        // SAFETY: Invariant (5) asserts that `self.a` is a valid pointer to a `ListHead<T>`.
204        unsafe { (*self.a).value() }
205    }
206
207    /// Returns the value of the list element behind the 'b' cursor.
208    pub fn value_b(&self) -> &T {
209        // SAFETY: Invariant (5) asserts that `self.b` is a valid pointer to a `ListHead<T>`.
210        unsafe { (*self.b).value() }
211    }
212
213    /// Swaps the 'a' and 'b' cursors of this `DoubleCursor`.
214    pub fn swap_cursors(&mut self) {
215        (self.a, self.b) = (self.b, self.a);
216        (self.idx_a, self.idx_b) = (self.idx_b, self.idx_a);
217    }
218
219    /// Sets the position of the 'a' cursor to the head of the list.
220    pub fn reset_a(&mut self) {
221        self.a = self.list.head;
222        self.idx_a = 0;
223    }
224
225    /// Sets the position of the 'b' cursor to the head of the list.
226    pub fn reset_b(&mut self) {
227        self.b = self.list.head;
228        self.idx_b = 0;
229    }
230
231    /// Sets the position of the 'b' cursor to the same as the 'a' cursor.
232    pub fn set_b_to_a(&mut self) {
233        self.b = self.a;
234        self.idx_b = self.idx_a;
235    }
236
237    /// Sets the position of the 'a' cursor to the same as the 'b' cursor.
238    pub fn set_a_to_b(&mut self) {
239        self.a = self.b;
240        self.idx_a = self.idx_b;
241    }
242
243    /// Saves the position of the 'a' cursor on a stack (internal to `Self`).
244    pub fn push_a(&mut self) {
245        self.stack.push((self.a, self.idx_a));
246    }
247
248    /// Saves the position of the 'b' cursor on a stack (internal to `Self`).
249    pub fn push_b(&mut self) {
250        self.stack.push((self.b, self.idx_b));
251    }
252
253    /// Load the position of the 'a' cursor to the last saved position of 'b' or 'a'.
254    pub fn pop_a(&mut self) {
255        if let Some((a, idx_a)) = self.stack.pop() {
256            (self.a, self.idx_a) = (a, idx_a);
257        }
258    }
259
260    /// Load the position of the 'b' cursor to the last saved position of 'b' or 'a'.
261    pub fn pop_b(&mut self) {
262        if let Some((b, idx_b)) = self.stack.pop() {
263            (self.b, self.idx_b) = (b, idx_b);
264        }
265    }
266
267    /// Swaps the list nodes pointed by the 'a' and 'b' cursors. It is a `O(1)` operation.
268    pub fn swap(&mut self) {
269        unsafe {
270            // SAFETY: Invariants (3) and (5) assert that `self.a` and `self.b` are part of
271            // a valid circular linked list.
272            ListHead::<T>::swap(self.a as *mut _, self.b as *mut _);
273        }
274        if self.a == self.list.head {
275            self.list.head = self.b;
276        } else if self.b == self.list.head {
277            self.list.head = self.a;
278        }
279    }
280
281    /// Cuts the list at the position pointing on the 'a' cursor.
282    ///
283    /// # Note
284    /// The `DoubleCursor` is consumed in the operation.
285    pub fn split_at_a(self) -> CircularList<T> {
286        let a = self.a as *mut _;
287        let idx_a = self.idx_a;
288        unsafe {
289            // SAFETY: `self.a` is valid and `self.idx_a` is the index of `self.a` in `self.list`
290            // according to (5).
291            self.split_at(a, idx_a)
292        }
293    }
294
295    /// Cuts the list at the position pointing on the 'b' cursor.
296    ///
297    /// # Note
298    /// The `DoubleCursor` is consumed in the operation.
299    pub fn split_at_b(self) -> CircularList<T> {
300        let b = self.b as *mut _;
301        let idx_b = self.idx_b;
302        unsafe {
303            // SAFETY: `self.b` is valid and `self.idx_b` is the index of `self.b` in `self.list`
304            // according to (5).
305            self.split_at(b, idx_b)
306        }
307    }
308
309    /// Displaces the element pointed by the 'a' cursor next to the element pointed by the 'b'
310    /// cursor.
311    pub fn insert_a_after_b(&mut self) {
312        unsafe {
313            // SAFETY: Invariant (5) asserts that `self.a` and `self.b` are valid. Invariant (3)
314            // asserts that it is part of a valid circular linked list.
315            if (*self.a).prev == self.b || self.a == self.b {
316                // `self.a` is already in the good place.
317                return;
318            }
319            if self.a == self.list.head {
320                // keep the head in its place
321                self.list.head = (*self.a).next;
322            }
323            ListHead::<T>::move_entry(self.a as *mut _, self.b as *mut _, (*self.b).next as *mut _);
324        }
325    }
326
327    /// Displaces the element pointed by the 'b' cursor before the element pointed by the 'a'
328    /// cursor.
329    pub fn insert_b_before_a(&mut self) {
330        unsafe {
331            // SAFETY: Invariant (5) asserts that `self.a` and `self.b` are valid. Invariant (3)
332            // asserts that it is part of a valid circular linked list.
333            if (*self.a).prev == self.b || self.a == self.b {
334                // `self.b` is already in the good place.
335                return;
336            }
337            if self.b == self.list.head {
338                // keep the head in its place
339                self.list.head = (*self.b).next;
340            }
341            if self.a == self.list.head {
342                // Inserting before the head means not at the end of the list
343                self.list.head = self.b;
344            }
345            ListHead::<T>::move_entry(self.b as *mut _, (*self.a).prev as *mut _, self.a as *mut _);
346        }
347    }
348
349    /// Creates a new list node with value `val` and places it after the element pointed by the
350    /// cursor 'a'.
351    pub fn insert_value_after_a(&mut self, val: T) {
352        unsafe {
353            // SAFETY: According to invariant (5), `self.a` is a valid pointer. Moreover, `self.a`
354            // points to a member of `self.list`.
355            self.list.insert_after(val, self.a as *mut _)
356        }
357        // Preserving invariant (5)
358        if self.idx_a < self.idx_b {
359            self.idx_b += 1;
360        }
361    }
362
363    /// Creates a new list node with value `val` and places it after the element pointed by the
364    /// cursor 'b'.
365    pub fn insert_value_after_b(&mut self, val: T) {
366        unsafe {
367            // SAFETY: According to invariant (5), `self.b` is a valid pointer. Moreover, `self.b`
368            // points to a member of `self.list`.
369            self.list.insert_after(val, self.b as *mut _)
370        }
371        // Preserving invariant (5)
372        if self.idx_b < self.idx_a {
373            self.idx_a += 1;
374        }
375    }
376}
377
378/// Like a [`Cursor`] but with mutative operations on the list.
379/// This `struct` is constructed by the [`CircularList::cursor_mut`](CircularList::cursor_mut)
380/// function.
381pub struct CursorMut<'life, T> {
382    list: &'life mut CircularList<T>,
383    // Invariant (6): `current` is a valid pointer to an element of `list`.
384    current: *mut ListHead<T>,
385}
386
387impl<'life, T> CursorMut<'life, T> {
388    /// Builds a `CursorMut` from a (valid) pointer to a `ListHead<T>`.
389    /// # Panics
390    /// This function panics if the list is empty.
391    pub(crate) fn from_list(list: &'life mut CircularList<T>) -> Self {
392        if list.is_empty() {
393            // Preserving the invariant (6)
394            panic!("Cannot build a `Cursor` from an empty list.");
395        }
396        let current = list.head as *mut _;
397        Self { list, current }
398    }
399
400    /// Returns a reference of the underlying list.
401    pub fn list(&self) -> &CircularList<T> {
402        self.list
403    }
404
405    /// Returns to its initial position (the head of the list).
406    pub fn reset(&mut self) {
407        self.current = self.list.head as *mut _;
408    }
409
410    /// Moves the cursor to the next element of the `CircularList`.
411    pub fn move_next(&mut self) {
412        unsafe {
413            // SAFETY: Invariants (3) and (6) assert that `self.current` is a valid pointer to
414            // a valid circular linked list
415            self.current = (*self.current).next as *mut _;
416        }
417    }
418
419    /// Moves the cursor to the previous element of the `CircularList`.
420    pub fn move_prev(&mut self) {
421        unsafe {
422            // SAFETY: Invariants (3) and (6) assert that `self.current` is a valid pointer to
423            // a valid circular linked list
424            self.current = (*self.current).prev as *mut _;
425        }
426    }
427
428    /// Returns the (mutable reference to the) value of the list element behind the cursor.
429    pub fn value(&mut self) -> &mut T {
430        // SAFETY: Invariant (6) asserts that `current` is a valid pointer to a `ListHead<T>`.
431        unsafe { (*self.current).value_mut() }
432    }
433
434    /// Removes the current element from the list and returns its value. The new current element is
435    /// the next element. Use [`remove_final`](Self::remove_final) function to remove the last
436    /// element.
437    ///
438    /// # Panics
439    /// The function panics if it is called on a cursor to a list with only 1 element because there
440    /// cannot be a `Cursor` or `CursorMut` to an empty list.
441    pub fn remove(&mut self) -> T {
442        if self.list.len() == 1 {
443            panic!("Cannot remove the last element with this function");
444        }
445        if self.list.head == self.current {
446            let val = self.list.remove().unwrap();
447
448            // Preserve invariant (6).
449            self.current = self.list.head as *mut _;
450
451            val
452        } else {
453            unsafe {
454                // SAFETY: Invariant (6) asserts that `current` is a valid pointer to a `ListHead<T>`.
455                let (next, val) = ListHead::del_entry(self.current);
456
457                // Preserve invariant (6).
458                self.current = next as *mut _;
459
460                // Preserving invariant (2).
461                self.list.length -= 1;
462
463                val
464            }
465        }
466    }
467
468    /// Removes the current element from the list, returns its value and consumes the cursor. To be
469    /// used when the list contains only 1 element.
470    pub fn remove_final(self) -> T {
471        if self.list.head == self.current {
472            // Invariant (6) does not need to be preserved here as the cursor is consumed.
473            self.list.remove().unwrap()
474        } else {
475            unsafe {
476                // SAFETY: Invariant (6) asserts that `current` is a valid pointer to a `ListHead<T>`.
477                let (_next, val) = ListHead::del_entry(self.current);
478
479                // Preserving invariant (2).
480                self.list.length -= 1;
481
482                val
483            }
484        }
485    }
486
487    /// Inserts an element before the current one.
488    pub fn insert_before(&mut self, val: T) {
489        unsafe {
490            // SAFETY: Invariant (6) asserts that `current` is a valid pointer to a `ListHead<T>`
491            // and it is part of the list.
492            self.list.insert_after(val, (*self.current).prev as *mut _);
493        }
494    }
495
496    /// Inserts an element after the current one.
497    pub fn insert_after(&mut self, val: T) {
498        unsafe {
499            // SAFETY: Invariant (6) asserts that `current` is a valid pointer to a `ListHead<T>`
500            // and it is part of the list.
501            self.list.insert_after(val, self.current);
502        }
503    }
504}
505
506#[cfg(test)]
507mod tests {
508    use {
509        crate::{list, CircularList},
510        alloc::vec::Vec,
511    };
512
513    #[test]
514    fn cursor_empty_list() {
515        assert_eq!(CircularList::<()>::default().cursor(), None)
516    }
517
518    #[test]
519    fn cursor() {
520        let list = list![1, 2, 3, 4, 5];
521        let mut c1 = list
522            .cursor()
523            .expect("A cursor should always be available on a non empty list");
524
525        assert_eq!(c1.value(), &1);
526
527        c1.move_prev();
528        assert_eq!(c1.value(), &5);
529
530        for _ in 0..5 {
531            c1.move_next();
532        }
533        assert_eq!(c1.value(), &5);
534
535        c1.move_next();
536        c1.move_next();
537        assert_eq!(c1.value(), &2);
538    }
539
540    #[test]
541    fn double_cursor_empty_list() {
542        assert!(matches!(
543            CircularList::<()>::default().double_cursor(),
544            None
545        ))
546    }
547
548    #[test]
549    fn double_cursor_swap() {
550        let mut list = list![1, 2, 3, 4, 5];
551        let mut dc = list
552            .double_cursor()
553            .expect("A cursor should always be available on a non empty list");
554
555        dc.move_next_b();
556        dc.swap();
557        assert_eq!(list.into_iter().collect::<Vec<i32>>(), &[2, 1, 3, 4, 5]);
558
559        let mut list = list![0];
560        let mut dc = list.double_cursor().unwrap();
561        dc.swap();
562        assert_eq!(list.into_iter().collect::<Vec<i32>>(), &[0]);
563    }
564
565    #[test]
566    fn double_cursor_move() {
567        let mut list = list![1, 2, 3, 4, 5];
568        let mut dc = list
569            .double_cursor()
570            .expect("A cursor should always be available on a non empty list");
571
572        dc.move_next_b();
573        dc.insert_a_after_b();
574        // This function is idempotent
575        dc.insert_a_after_b();
576        assert_eq!(list.into_iter().collect::<Vec<i32>>(), &[2, 1, 3, 4, 5]);
577    }
578
579    #[test]
580    fn double_cursor_sort() {
581        let mut list = list![3, 1, 8, 21, 5, 9, 12, 5, 2, 6, 6, 6, 13, 2, 17];
582        let len = list.len();
583        let mut dc = list
584            .double_cursor()
585            .expect("A cursor should always be available on a non empty list");
586
587        let mut min = *dc.value_a();
588        for i in 1..len {
589            dc.set_b_to_a();
590            dc.push_a();
591            for _ in i..len {
592                dc.move_next_a();
593                let val = *dc.value_a();
594                if val < min {
595                    min = val;
596                    dc.set_b_to_a();
597                }
598            }
599            dc.pop_a();
600            dc.insert_b_before_a();
601            if dc.a_is_b() {
602                dc.move_next_a();
603            }
604            min = *dc.value_a();
605        }
606        assert_eq!(
607            list.into_iter().collect::<Vec<i32>>(),
608            &[1, 2, 2, 3, 5, 5, 6, 6, 6, 8, 9, 12, 13, 17, 21]
609        );
610    }
611
612    #[test]
613    fn double_cursor_split_empty() {
614        let mut list = list![1, 2, 3, 4, 5];
615        let dc = list.double_cursor().unwrap();
616
617        let list2 = dc.split_at_a();
618        let v2 = list2.into_iter().collect::<Vec<i32>>();
619
620        assert_eq!(v2, &[1, 2, 3, 4, 5]);
621        assert!(list.is_empty());
622    }
623
624    #[test]
625    fn double_cursor_split() {
626        let mut list = list![1, 2, 3, 4, 5];
627        let mut dc = list.double_cursor().unwrap();
628
629        dc.move_next_a();
630        dc.move_next_a();
631        let list2 = dc.split_at_a();
632
633        let v1 = list.into_iter().collect::<Vec<i32>>();
634        let v2 = list2.into_iter().collect::<Vec<i32>>();
635        assert_eq!(v1, &[1, 2]);
636        assert_eq!(v2, &[3, 4, 5]);
637    }
638
639    #[test]
640    fn double_cursor_insert_val_after_a() {
641        let mut list = list![1, 2, 3, 4, 5];
642        let mut dc = list.double_cursor().unwrap();
643
644        dc.move_next_a();
645        dc.move_next_a();
646
647        dc.insert_value_after_a(42);
648        let v1 = list.into_iter().collect::<Vec<i32>>();
649        assert_eq!(v1, &[1, 2, 3, 42, 4, 5]);
650    }
651
652    #[test]
653    fn cursor_mut_remove() {
654        let mut list = list![1, 2, 3, 4, 5];
655        let mut c = list.cursor_mut().unwrap();
656
657        c.move_next();
658        assert_eq!(c.remove(), 2);
659        assert_eq!(c.remove(), 3);
660        assert_eq!(c.remove(), 4);
661        assert_eq!(c.remove(), 5);
662        assert_eq!(c.remove_final(), 1);
663    }
664
665    #[test]
666    fn cursor_mut_insert() {
667        let mut list = list![1, 2, 3, 4, 5];
668        let mut c = list.cursor_mut().unwrap();
669
670        c.move_next();
671        assert_eq!(c.remove(), 2);
672        c.insert_before(2);
673        let v1 = list.into_iter().collect::<Vec<i32>>();
674        assert_eq!(v1, &[1, 2, 3, 4, 5]);
675    }
676}