array_linked_list/
lib.rs

1#![deny(missing_docs)]
2
3/*!
4The `ArrayLinkedList` data structure combines the benefit of an array and a linked list.
5
6Every supported operation, which does not (re-)allocate the array, is done in *O*(1):
7
8* inserting elements at the front and back
9* popping element at the front or back
10* getting the element count
11* removing elements at an arbitrary index
12* inserting elements at an arbitrary index
13* replacing elements at an arbitrary index
14
15It's stored like an array, but contains some additional information.
16
17You would typically use it, where you need to be able to do multiple of the following tasks efficiently:
18
19* accessing single elements by index
20* adding and removing elements without changing order or indices
21* sorting elements without changing indices or moving the content around.
22
23# Order and indexing
24
25You might also use it as a more convenient version of a `Vec<Option<T>>`.
26When iterating over it, only the elements, which are `Some` are given to the user.
27And even the checks for `Some` are optimized away.
28So when it's likely, that most of the options of a large array are `None`, this might be a huge performance improvement.
29
30Another advantage over a `LinkedList` is the cache locality.
31Everything is laid out in a contiguous region of memory.
32Compared to a `Vec` on the other hand, it might be bad.
33The iteration does not necessarily take place in the same order.
34That's mostly a problem for large arrays.
35The iterator would jump back and forth in the array.
36
37In order to understand this type, it's necessary to know about the iteration order.
38There is a logical order, which is used by the iterators, or when doing anything with the first and last elements.
39You can think of it as the order of a linked list, which is just packed into an array here.
40And then there is indexing, which has nothing to do with the order of the linked list.
41The indices just return the array elements.
42
43## Index Example
44
45So when adding an element to the linked array without specifying the index, you get the index, it was put to, as a result.
46The results are always added to the array in order, so the indices increase, no matter if you add the indices to the front or to the back:
47
48```
49use array_linked_list::ArrayLinkedList;
50
51let mut array = ArrayLinkedList::new();
52
53assert_eq!(array.push_front(1), 0);
54assert_eq!(array.push_back(2), 1);
55assert_eq!(array.push_front(3), 2);
56assert_eq!(array.push_front(4), 3);
57assert_eq!(array.push_back(5), 4);
58```
59
60## Order example
61
62When you just apped elements from the front or back, the indices even correlate to the order:
63
64```
65use array_linked_list::ArrayLinkedList;
66
67let mut array = ArrayLinkedList::new();
68
69array.push_front(1);
70array.push_front(2);
71array.push_front(3);
72
73for (i, element) in array.iter().rev().enumerate() {
74    assert_eq!(*element, array[i].unwrap());
75}
76```
77
78```
79use array_linked_list::ArrayLinkedList;
80
81let mut array = ArrayLinkedList::new();
82
83array.push_back(1);
84array.push_back(2);
85array.push_back(3);
86
87for (i, element) in array.iter().enumerate() {
88    assert_eq!(*element, array[i].unwrap());
89}
90```
91
92## Iteration over unsorted lists
93
94In realistic cases, you need to store the indices somewhere else, if you need them.
95Alternatively, you can also use
96
97```
98use array_linked_list::ArrayLinkedList;
99
100let mut array = ArrayLinkedList::new();
101
102array.push_back(1);
103array.push_front(2);
104array.push_front(3);
105array.push_back(4);
106array.push_front(5);
107
108for (index, element) in array.indexed().rev() {
109    assert_eq!(*element, array[index].unwrap());
110}
111```
112
113## Conclusion
114
115Just remember, that indices and order are two different things, which don't correlate, and you should be safe.
116
117**/
118
119use std::{
120    mem,
121    ops::{Index, IndexMut},
122};
123
124#[derive(Copy, Clone, Debug)]
125struct LinkedListNode<T> {
126    next_index: usize,
127    prev_index: usize,
128    data: Option<T>,
129}
130
131impl<T> LinkedListNode<T> {
132    fn new(prev_index: usize, next_index: usize, data: T) -> Self {
133        Self {
134            next_index,
135            prev_index,
136            data: Some(data),
137        }
138    }
139
140    fn front(first_index: usize, data: T) -> Self {
141        Self {
142            next_index: first_index,
143            prev_index: 0,
144            data: Some(data),
145        }
146    }
147
148    fn back(last_index: usize, data: T) -> Self {
149        Self {
150            next_index: 0,
151            prev_index: last_index,
152            data: Some(data),
153        }
154    }
155
156    fn deleted(free_index: usize) -> Self {
157        Self {
158            next_index: free_index,
159            prev_index: 0,
160            data: None,
161        }
162    }
163}
164
165/// The `ArrayLinkedList` type, which combines the advantages of dynamic arrays and linked lists.
166#[derive(Clone, Debug, Default)]
167pub struct ArrayLinkedList<T> {
168    count: usize,
169    first_index: usize,
170    last_index: usize,
171    free_index: usize,
172    end_index: usize,
173    elements: Vec<LinkedListNode<T>>,
174}
175
176impl<T> ArrayLinkedList<T> {
177    /// Constructs a new, empty `ArrayLinkedList`.
178    ///
179    /// The linked array will not allocate until elements are pushed onto it.
180    pub fn new() -> Self {
181        Self {
182            count: 0,
183            first_index: 0,
184            last_index: 0,
185            free_index: 0,
186            end_index: 0,
187            elements: Vec::new(),
188        }
189    }
190
191    #[inline]
192    fn fill_elements(&mut self, capacity: usize) {
193        if capacity == 0 {
194            return;
195        }
196        for i in 1..capacity {
197            self.elements.push(LinkedListNode::deleted(i + 1))
198        }
199        self.elements.push(LinkedListNode::deleted(0));
200
201        self.free_index = 1;
202        self.end_index = capacity;
203    }
204
205    /// Constructs a new, empty `ArrayLinkedList<T>` with the specified capacity.
206    ///
207    /// The array will be able to hold exactly `capacity` elements without reallocating.
208    // If `capacity` is 0, the vector will not allocate.
209    pub fn with_capacity(capacity: usize) -> Self {
210        let mut result = Self::new();
211        result.elements = Vec::with_capacity(capacity);
212        result.fill_elements(capacity);
213        result
214    }
215
216    fn insert_free_element(&mut self, element: LinkedListNode<T>) -> usize {
217        if self.free_index == 0 {
218            self.elements.push(element);
219            self.elements.len()
220        } else {
221            let free_index = self.free_index;
222            let recycle_element = &mut self.elements[free_index - 1];
223            self.free_index = recycle_element.next_index;
224            *recycle_element = element;
225            free_index
226        }
227    }
228
229    /// Adds an element at the front of the array and returns its index.
230    /// The indices are returned in a raising order, starting with zero.
231    /// See the module description for more information.
232    ///
233    /// This operation should compute in *O*(1) time.
234    ///
235    /// # Examples
236    ///
237    /// ```
238    /// use array_linked_list::ArrayLinkedList;
239    ///
240    /// let mut array = ArrayLinkedList::new();
241    ///
242    /// assert_eq!(array.push_front(2), 0);
243    /// assert_eq!(array.front().unwrap(), &2);
244    ///
245    /// assert_eq!(array.push_front(1), 1);
246    /// assert_eq!(array.front().unwrap(), &1);
247    /// ```
248    pub fn push_front(&mut self, value: T) -> usize {
249        let element = LinkedListNode::front(self.first_index, value);
250
251        let next_index = self.insert_free_element(element);
252
253        *self.prev_of_next(self.first_index, true) = next_index;
254
255        self.first_index = next_index;
256        self.count += 1;
257
258        next_index - 1
259    }
260
261    /// Adds an element at the back of the array and returns its index.
262    /// The indices are returned in a raising order, starting with zero.
263    /// See the module description for more information.
264    ///
265    /// This operation should compute in *O*(1) time.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// use array_linked_list::ArrayLinkedList;
271    ///
272    /// let mut array = ArrayLinkedList::new();
273    ///
274    /// assert_eq!(array.push_back(1), 0);
275    /// assert_eq!(array.push_back(3), 1);
276    /// assert_eq!(3, *array.back().unwrap());
277    /// ```
278    pub fn push_back(&mut self, value: T) -> usize {
279        let element = LinkedListNode::back(self.last_index, value);
280
281        let prev_index = self.insert_free_element(element);
282
283        *self.next_of_prev(self.last_index, true) = prev_index;
284
285        self.last_index = prev_index;
286        self.count += 1;
287
288        prev_index - 1
289    }
290
291    fn insert_between(&mut self, prev_index: usize, next_index: usize, value: T) -> usize {
292        let element = LinkedListNode::new(prev_index, next_index, value);
293
294        let index = self.insert_free_element(element);
295
296        *self.next_of_prev(prev_index, true) = index;
297        *self.prev_of_next(next_index, true) = index;
298
299        self.count += 1;
300
301        index - 1
302    }
303
304    /// Inserts an element after the element at the specified index.
305    /// Returns the index of the inserted element on success.
306    /// If no element was found at the specified index, `None` is returned.
307    ///
308    /// # Panics
309    ///
310    /// Panics if `prev_index >= capacity`
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// use array_linked_list::ArrayLinkedList;
316    ///
317    /// let mut array = ArrayLinkedList::new();
318    ///
319    /// let first = array.push_back(1);
320    /// let second = array.push_back(2);
321    /// let third = array.push_back(3);
322    ///
323    /// array.insert_after(second, 100);
324    ///
325    /// assert_eq!(array.pop_front(), Some(1));
326    /// assert_eq!(array.pop_front(), Some(2));
327    /// assert_eq!(array.pop_front(), Some(100));
328    /// assert_eq!(array.pop_front(), Some(3));
329    /// assert_eq!(array.pop_front(), None);
330    /// ```
331    pub fn insert_after(&mut self, prev_index: usize, value: T) -> Option<usize> {
332        let LinkedListNode {
333            next_index, data, ..
334        } = &self.elements[prev_index];
335
336        if data.is_some() {
337            let next_index = *next_index;
338            Some(self.insert_between(prev_index + 1, next_index, value))
339        } else {
340            None
341        }
342    }
343
344    /// Inserts an element before the element at the specified index.
345    /// Returns the index of the inserted element on success.
346    /// If no element was found at the specified index, `None` is returned.
347    ///
348    /// # Panics
349    ///
350    /// Panics if `next_index >= capacity`
351    ///
352    /// # Examples
353    ///
354    /// ```
355    /// use array_linked_list::ArrayLinkedList;
356    ///
357    /// let mut array = ArrayLinkedList::new();
358    ///
359    /// let first = array.push_back(1);
360    /// let second = array.push_back(2);
361    /// let third = array.push_back(3);
362    ///
363    /// array.insert_before(second, 100);
364    ///
365    /// assert_eq!(array.pop_front(), Some(1));
366    /// assert_eq!(array.pop_front(), Some(100));
367    /// assert_eq!(array.pop_front(), Some(2));
368    /// assert_eq!(array.pop_front(), Some(3));
369    /// assert_eq!(array.pop_front(), None);
370    /// ```
371    pub fn insert_before(&mut self, next_index: usize, value: T) -> Option<usize> {
372        let LinkedListNode {
373            prev_index, data, ..
374        } = &self.elements[next_index];
375
376        if data.is_some() {
377            let prev_index = *prev_index;
378            Some(self.insert_between(prev_index, next_index + 1, value))
379        } else {
380            None
381        }
382    }
383
384    #[inline]
385    fn prev_of_next(&mut self, index: usize, active: bool) -> &mut usize {
386        if index > 0 {
387            &mut self.elements[index - 1].prev_index
388        } else if active {
389            &mut self.last_index
390        } else {
391            &mut self.end_index
392        }
393    }
394
395    #[inline]
396    fn next_of_prev(&mut self, index: usize, active: bool) -> &mut usize {
397        if index > 0 {
398            &mut self.elements[index - 1].next_index
399        } else if active {
400            &mut self.first_index
401        } else {
402            &mut self.free_index
403        }
404    }
405
406    fn connect_indices(&mut self, prev_index: usize, next_index: usize, active: bool) {
407        *self.prev_of_next(next_index, active) = prev_index;
408        *self.next_of_prev(prev_index, active) = next_index;
409    }
410
411    /// Removes the element at the given index and returns it, or `None` if it is empty.
412    /// The indices of other items are not changed.
413    /// Indices, which have never been used (see `capacity`), will not be available, but panic instead.
414    ///
415    /// Indices are not the position they appear in, when iterating over them.
416    /// So you can't use enumerate to get the index to delete.
417    /// But the iteration order of the elements (in both directions) is preserved.
418    /// See the module description for more information.
419    ///
420    /// This operation should compute in *O*(1) time.
421    ///
422    /// # Panics
423    ///
424    /// Panics if index >= capacity
425    ///
426    /// # Examples
427    ///
428    /// ```
429    /// use array_linked_list::ArrayLinkedList;
430    ///
431    /// let mut array = ArrayLinkedList::new();
432    ///
433    /// let first = array.push_front(1);
434    /// let second = array.push_back(2);
435    /// let third = array.push_front(3);
436    ///
437    ///
438    /// assert_eq!(array.len(), 3);
439    ///
440    /// assert_eq!(array.remove(second).unwrap(), 2);
441    /// assert_eq!(array[second], None);
442    /// assert_eq!(array.len(), 2);
443    /// assert_eq!(array.remove(second), None);
444    /// assert_eq!(array.len(), 2);
445    ///
446    /// assert_eq!(array.remove(first).unwrap(), 1);
447    /// assert_eq!(array.len(), 1);
448    /// assert_eq!(array.remove(third).unwrap(), 3);
449    /// assert_eq!(array.len(), 0);
450    /// assert!(array.is_empty());
451    /// ```
452    pub fn remove(&mut self, index: usize) -> Option<T> {
453        let LinkedListNode {
454            next_index,
455            prev_index,
456            data,
457        } = mem::replace(
458            &mut self.elements[index],
459            LinkedListNode::deleted(self.free_index),
460        );
461
462        let removed = data.is_some();
463        self.connect_indices(prev_index, next_index, removed);
464
465        if removed {
466            self.count -= 1;
467        }
468
469        if self.free_index > 0 {
470            self.elements[self.free_index - 1].prev_index = index + 1;
471        }
472
473        self.free_index = index + 1;
474        data
475    }
476
477    /// Adds element at specified index at the front of the list.
478    /// Useful for updating contents.
479    ///
480    /// It basically does the same as `remove` and `push_back`, even if the specified index is already removed.
481    ///
482    /// # Panics
483    ///
484    /// Panics if index >= capacity
485    ///
486    /// # Examples
487    ///
488    /// ```
489    /// use array_linked_list::ArrayLinkedList;
490    ///
491    /// let mut array = ArrayLinkedList::new();
492    ///
493    /// array.push_front(1);
494    /// let first_index = array.push_back(2);
495    /// array.push_front(3);
496    /// let second_index = array.push_front(4);
497    /// array.push_back(5);
498    ///
499    /// let mut array2 = array.clone();
500    /// assert_eq!(array, array2);
501    ///
502    /// let first_element = array.replace_front(first_index, 100);
503    /// let first_element2 = array2.remove(first_index);
504    /// array2.push_front(100);
505    /// assert_eq!(first_element, first_element2);
506    /// assert_eq!(array, array2);
507    ///
508    /// let second_element = array.replace_front(first_index, 0);
509    /// let second_element2 = array2.remove(first_index);
510    /// array2.push_back(0);
511    /// assert_eq!(second_element, second_element2);
512    /// assert_ne!(array, array2);
513    ///
514    /// assert_eq!(array.len(), 5);
515    /// assert_eq!(array2.len(), 5);
516    /// ```
517    pub fn replace_front(&mut self, index: usize, value: T) -> Option<T> {
518        let LinkedListNode {
519            next_index,
520            prev_index,
521            data,
522        } = mem::replace(
523            &mut self.elements[index],
524            LinkedListNode::front(self.first_index, value),
525        );
526
527        let removed = data.is_some();
528        self.connect_indices(prev_index, next_index, removed);
529
530        if !removed {
531            self.count += 1;
532        }
533
534        if self.first_index > 0 {
535            self.elements[self.first_index - 1].prev_index = index + 1;
536        }
537
538        self.first_index = index + 1;
539        data
540    }
541
542    /// Adds element at specified index at the front of the list.
543    /// Useful for updating contents.
544    ///
545    /// It basically does the same as `remove` and `push_back`, even if the specified index is already removed.
546    ///
547    /// # Panics
548    ///
549    /// Panics if index >= capacity
550    ///
551    /// # Examples
552    ///
553    /// ```
554    /// use array_linked_list::ArrayLinkedList;
555    ///
556    /// let mut array = ArrayLinkedList::new();
557    ///
558    /// array.push_front(1);
559    /// array.push_back(2);
560    /// let middle_index = array.push_back(3);
561    /// array.push_front(4);
562    /// array.push_back(5);
563    ///
564    /// let mut array2 = array.clone();
565    /// assert_eq!(array, array2);
566    ///
567    /// let element = array.replace_back(middle_index, 100);
568    /// let element2 = array2.remove(middle_index);
569    /// array2.push_back(100);
570    /// assert_eq!(element, element2);
571    /// assert_eq!(array, array2);
572    ///
573    /// assert_eq!(array.len(), 5);
574    /// assert_eq!(array2.len(), 5);
575    /// ```
576    pub fn replace_back(&mut self, index: usize, value: T) -> Option<T> {
577        let LinkedListNode {
578            next_index,
579            prev_index,
580            data,
581        } = mem::replace(
582            &mut self.elements[index],
583            LinkedListNode::back(self.last_index, value),
584        );
585
586        let removed = data.is_some();
587        self.connect_indices(prev_index, next_index, removed);
588
589        if !removed {
590            self.count += 1;
591        }
592
593        if self.last_index > 0 {
594            self.elements[self.last_index - 1].next_index = index + 1;
595        }
596
597        self.last_index = index + 1;
598        data
599    }
600
601    /// Removes the first element from the array and returns it, or `None` if it is empty.
602    ///
603    /// This operation should compute in *O*(1) time.
604    ///
605    /// # Examples
606    ///
607    /// ```
608    /// use array_linked_list::ArrayLinkedList;
609    ///
610    /// let mut array = ArrayLinkedList::new();
611    /// assert_eq!(array.pop_front(), None);
612    /// array.push_back(1);
613    /// array.push_back(3);
614    /// assert_eq!(array.pop_front(), Some(1));
615    /// ```
616    pub fn pop_front(&mut self) -> Option<T> {
617        if self.first_index == 0 {
618            return None;
619        }
620        let index = self.first_index - 1;
621        let LinkedListNode {
622            next_index, data, ..
623        } = mem::replace(
624            &mut self.elements[index],
625            LinkedListNode::deleted(self.free_index),
626        );
627
628        *self.prev_of_next(next_index, true) = 0;
629        self.first_index = next_index;
630
631        self.count -= 1;
632        if self.free_index > 0 {
633            self.elements[self.free_index - 1].prev_index = index;
634        }
635
636        self.free_index = index;
637        Some(unsafe { data.unwrap_unchecked() })
638    }
639
640    /// Removes the last element from the array and returns it, or `None` if it is empty.
641    ///
642    /// This operation should compute in *O*(1) time.
643    ///
644    /// # Examples
645    ///
646    /// ```
647    /// use array_linked_list::ArrayLinkedList;
648    ///
649    /// let mut array = ArrayLinkedList::new();
650    /// assert_eq!(array.pop_back(), None);
651    /// array.push_back(1);
652    /// array.push_back(3);
653    /// assert_eq!(array.pop_back(), Some(3));
654    /// ```
655    pub fn pop_back(&mut self) -> Option<T> {
656        if self.last_index == 0 {
657            return None;
658        }
659        let index = self.last_index - 1;
660        let LinkedListNode {
661            prev_index, data, ..
662        } = mem::replace(
663            &mut self.elements[index],
664            LinkedListNode::deleted(self.free_index),
665        );
666
667        self.last_index = prev_index;
668        *self.next_of_prev(prev_index, true) = 0;
669
670        self.count -= 1;
671        if self.free_index > 0 {
672            self.elements[self.free_index - 1].prev_index = index;
673        }
674
675        self.free_index = index;
676        Some(unsafe { data.unwrap_unchecked() })
677    }
678
679    /// The index of the first list element.
680    /// Returns `None` if array is empty.
681    pub fn front_index(&self) -> Option<usize> {
682        if self.first_index > 0 {
683            Some(self.first_index - 1)
684        } else {
685            None
686        }
687    }
688
689    /// The index of the last list element.
690    /// Returns `None` if array is empty.
691    pub fn back_index(&self) -> Option<usize> {
692        if self.last_index > 0 {
693            Some(self.last_index - 1)
694        } else {
695            None
696        }
697    }
698
699    /// The first list element.
700    /// Returns `None` if array is empty.
701    pub fn front(&self) -> Option<&T> {
702        if self.first_index == 0 {
703            return None;
704        }
705
706        Some(unsafe {
707            self.elements[self.first_index - 1]
708                .data
709                .as_ref()
710                .unwrap_unchecked()
711        })
712    }
713
714    /// The last list element.
715    /// Returns `None` if array is empty.
716    pub fn back(&self) -> Option<&T> {
717        if self.last_index == 0 {
718            return None;
719        }
720
721        Some(unsafe {
722            self.elements[self.last_index - 1]
723                .data
724                .as_ref()
725                .unwrap_unchecked()
726        })
727    }
728
729    /// The first list element as a mutable reference.
730    /// Returns `None` if array is empty.
731    pub fn front_mut(&mut self) -> Option<&mut T> {
732        if self.first_index == 0 {
733            return None;
734        }
735
736        Some(unsafe {
737            self.elements[self.first_index - 1]
738                .data
739                .as_mut()
740                .unwrap_unchecked()
741        })
742    }
743
744    /// The last list element as a mutable reference.
745    /// Returns `None` if array is empty.
746    pub fn back_mut(&mut self) -> Option<&mut T> {
747        if self.last_index == 0 {
748            return None;
749        }
750
751        Some(unsafe {
752            self.elements[self.last_index - 1]
753                .data
754                .as_mut()
755                .unwrap_unchecked()
756        })
757    }
758
759    /// Checks if the list is empty.
760    pub fn is_empty(&self) -> bool {
761        self.first_index == 0 && self.last_index == 0
762    }
763
764    /// Clears the linked array, removing all values.
765    ///
766    /// Note that this method has no effect on the allocated capacity of the array.
767    /// So all indices, which have already been used (see `capacity`), are still available.
768    pub fn clear(&mut self) {
769        self.count = 0;
770        self.first_index = 0;
771        self.last_index = 0;
772        self.free_index = 0;
773        self.end_index = 0;
774
775        let capacity = self.elements.len();
776        self.elements.clear();
777        self.fill_elements(capacity);
778    }
779
780    /// Returns the number of elements in the linked array.
781    pub fn len(&self) -> usize {
782        self.count
783    }
784
785    /// Returns the number of elements the vector can hold without reallocating.
786    ///
787    /// Methods, which take indices, require the specified index to be below the capacity.
788    ///
789    /// All the following methods require indices:
790    ///
791    /// * `insert_before`
792    /// * `insert_after`
793    /// * `remove`
794    /// * `replace_front`
795    /// * `replace_back`
796    ///
797    /// Besides that, some of the iterators are constructed using indices in the same range.
798    pub fn capacity(&self) -> usize {
799        self.elements.len()
800    }
801
802    /// Returns a borrowing iterator over its elements.
803    pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> {
804        Values(Indexed::new(self))
805    }
806
807    /// Returns a borrowing iterator over its indexed elements.
808    pub fn indexed(&self) -> impl DoubleEndedIterator<Item = (usize, &T)> {
809        Indexed::new(self)
810    }
811
812    /// Returns a borrowing iterator over its indices.
813    pub fn indices(&self) -> impl DoubleEndedIterator<Item = usize> + '_ {
814        Indices(Indexed::new(self))
815    }
816
817    /// Returns a borrowing iterator over its elements, starting after the element at the specified index.
818    ///
819    /// # Panics
820    ///
821    /// Panics if index >= capacity
822    pub fn iter_after(&self, index: usize) -> impl DoubleEndedIterator<Item = &T> {
823        Values(Indexed::after(self, index))
824    }
825
826    /// Returns a borrowing iterator over its indexed elements, starting after the element at the specified index.
827    ///
828    /// # Panics
829    ///
830    /// Panics if index >= capacity
831    pub fn indexed_after(&self, index: usize) -> impl DoubleEndedIterator<Item = (usize, &T)> {
832        Indexed::after(self, index)
833    }
834
835    /// Returns a borrowing iterator over its indices, starting after the element at the specified index.
836    ///
837    /// # Panics
838    ///
839    /// Panics if index >= capacity
840    pub fn indices_after(&self, index: usize) -> impl DoubleEndedIterator<Item = usize> + '_ {
841        Indices(Indexed::after(self, index))
842    }
843
844    /// Returns a borrowing iterator over its elements, ending before the element at the specified index.
845    ///
846    /// # Panics
847    ///
848    /// Panics if index >= capacity
849    pub fn iter_before(&self, index: usize) -> impl DoubleEndedIterator<Item = &T> {
850        Values(Indexed::before(self, index))
851    }
852
853    /// Returns a borrowing iterator over its indexed elements, ending before the element at the specified index.
854    ///
855    /// # Panics
856    ///
857    /// Panics if index >= capacity
858    pub fn indexed_before(&self, index: usize) -> impl DoubleEndedIterator<Item = (usize, &T)> {
859        Indexed::before(self, index)
860    }
861
862    /// Returns a borrowing iterator over its indices, ending before the element at the specified index.
863    ///
864    /// # Panics
865    ///
866    /// Panics if index >= capacity
867    pub fn indices_before(&self, index: usize) -> impl DoubleEndedIterator<Item = usize> + '_ {
868        Indices(Indexed::before(self, index))
869    }
870
871    /// Returns an owning iterator returning its indexed elements.
872    pub fn into_indexed(self) -> impl DoubleEndedIterator<Item = (usize, T)> {
873        IntoIndexed(self)
874    }
875
876    /// Returns an owning iterator returning its indices.
877    pub fn into_indices(self) -> impl DoubleEndedIterator<Item = usize> {
878        IntoIndices(IntoIndexed(self))
879    }
880}
881
882impl<T> Index<usize> for ArrayLinkedList<T> {
883    type Output = Option<T>;
884    fn index(&self, index: usize) -> &Option<T> {
885        &self.elements[index].data
886    }
887}
888
889impl<T> IndexMut<usize> for ArrayLinkedList<T> {
890    fn index_mut(&mut self, index: usize) -> &mut Option<T> {
891        &mut self.elements[index].data
892    }
893}
894
895struct Indexed<'a, T> {
896    front_index: usize,
897    back_index: usize,
898    array: &'a ArrayLinkedList<T>,
899}
900
901impl<'a, T> Indexed<'a, T> {
902    fn empty(array: &'a ArrayLinkedList<T>) -> Self {
903        Self {
904            front_index: 0,
905            back_index: 0,
906            array,
907        }
908    }
909
910    fn new(array: &'a ArrayLinkedList<T>) -> Self {
911        Self {
912            front_index: array.first_index,
913            back_index: array.last_index,
914            array,
915        }
916    }
917
918    fn after(array: &'a ArrayLinkedList<T>, prev_index: usize) -> Self {
919        let element = &array.elements[prev_index];
920        if element.data.is_some() {
921            Self {
922                front_index: element.next_index,
923                back_index: array.last_index,
924                array,
925            }
926        } else {
927            Self::empty(array)
928        }
929    }
930
931    fn before(array: &'a ArrayLinkedList<T>, next_index: usize) -> Self {
932        let element = &array.elements[next_index];
933        if element.data.is_some() {
934            Self {
935                front_index: array.first_index,
936                back_index: element.prev_index,
937                array,
938            }
939        } else {
940            Self::empty(array)
941        }
942    }
943}
944
945struct Indices<'a, T>(Indexed<'a, T>);
946
947/// Borrowing iterator over values of the linked array.
948pub struct Values<'a, T>(Indexed<'a, T>);
949
950impl<'a, T> Iterator for Indexed<'a, T> {
951    type Item = (usize, &'a T);
952    #[inline]
953    fn next(&mut self) -> Option<Self::Item> {
954        if self.front_index == 0 {
955            return None;
956        }
957
958        let index = self.front_index - 1;
959        let element = &self.array.elements[index];
960        if self.front_index == self.back_index {
961            self.front_index = 0;
962            self.back_index = 0;
963        } else {
964            self.front_index = element.next_index;
965        }
966        Some((index, unsafe { element.data.as_ref().unwrap_unchecked() }))
967    }
968}
969
970impl<T> DoubleEndedIterator for Indexed<'_, T> {
971    #[inline]
972    fn next_back(&mut self) -> Option<Self::Item> {
973        if self.back_index == 0 {
974            return None;
975        }
976
977        let index = self.back_index - 1;
978        let element = &self.array.elements[index];
979        if self.front_index == self.back_index {
980            self.front_index = 0;
981            self.back_index = 0;
982        } else {
983            self.back_index = element.prev_index;
984        }
985        Some((index, unsafe { element.data.as_ref().unwrap_unchecked() }))
986    }
987}
988
989impl<T> Iterator for Indices<'_, T> {
990    type Item = usize;
991    fn next(&mut self) -> Option<Self::Item> {
992        self.0.next().map(|(index, _)| index)
993    }
994}
995
996impl<T> DoubleEndedIterator for Indices<'_, T> {
997    fn next_back(&mut self) -> Option<Self::Item> {
998        self.0.next_back().map(|(index, _)| index)
999    }
1000}
1001
1002impl<'a, T> Iterator for Values<'a, T> {
1003    type Item = &'a T;
1004    fn next(&mut self) -> Option<Self::Item> {
1005        self.0.next().map(|(_, value)| value)
1006    }
1007}
1008
1009impl<T> DoubleEndedIterator for Values<'_, T> {
1010    fn next_back(&mut self) -> Option<Self::Item> {
1011        self.0.next_back().map(|(_, value)| value)
1012    }
1013}
1014
1015impl<'a, T> IntoIterator for &'a ArrayLinkedList<T> {
1016    type Item = &'a T;
1017    type IntoIter = Values<'a, T>;
1018
1019    #[inline]
1020    fn into_iter(self) -> Self::IntoIter {
1021        Values(Indexed::new(self))
1022    }
1023}
1024
1025struct IntoIndexed<T>(ArrayLinkedList<T>);
1026struct IntoIndices<T>(IntoIndexed<T>);
1027
1028/// Owning iterator over values of the linked array.
1029pub struct IntoValues<T>(IntoIndexed<T>);
1030
1031impl<T> Iterator for IntoIndexed<T> {
1032    type Item = (usize, T);
1033    #[inline]
1034    fn next(&mut self) -> Option<Self::Item> {
1035        if self.0.first_index == 0 {
1036            return None;
1037        }
1038
1039        let index = self.0.first_index - 1;
1040        let element = &mut self.0.elements[index];
1041        if self.0.first_index == self.0.last_index {
1042            self.0.first_index = 0;
1043            self.0.last_index = 0;
1044        } else {
1045            self.0.first_index = element.next_index;
1046        }
1047        Some((index, unsafe { element.data.take().unwrap_unchecked() }))
1048    }
1049}
1050
1051impl<T> DoubleEndedIterator for IntoIndexed<T> {
1052    fn next_back(&mut self) -> Option<Self::Item> {
1053        if self.0.first_index == 0 {
1054            return None;
1055        }
1056
1057        let index = self.0.first_index - 1;
1058        let element = &mut self.0.elements[index];
1059        if self.0.first_index == self.0.last_index {
1060            self.0.first_index = 0;
1061            self.0.last_index = 0;
1062        } else {
1063            self.0.first_index = element.next_index;
1064        }
1065        Some((index, unsafe { element.data.take().unwrap_unchecked() }))
1066    }
1067}
1068
1069impl<T> Iterator for IntoIndices<T> {
1070    type Item = usize;
1071    fn next(&mut self) -> Option<Self::Item> {
1072        self.0.next().map(|(index, _)| index)
1073    }
1074}
1075
1076impl<T> DoubleEndedIterator for IntoIndices<T> {
1077    fn next_back(&mut self) -> Option<Self::Item> {
1078        self.0.next_back().map(|(index, _)| index)
1079    }
1080}
1081
1082impl<T> Iterator for IntoValues<T> {
1083    type Item = T;
1084    fn next(&mut self) -> Option<Self::Item> {
1085        self.0.next().map(|(_, value)| value)
1086    }
1087}
1088
1089impl<T> DoubleEndedIterator for IntoValues<T> {
1090    fn next_back(&mut self) -> Option<Self::Item> {
1091        self.0.next_back().map(|(_, value)| value)
1092    }
1093}
1094
1095impl<T> IntoIterator for ArrayLinkedList<T> {
1096    type Item = T;
1097    type IntoIter = IntoValues<T>;
1098
1099    fn into_iter(self) -> Self::IntoIter {
1100        IntoValues(IntoIndexed(self))
1101    }
1102}