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    /// for (a, b) in array.iter().zip(&array2) {
501    ///     assert_eq!(a, b)
502    /// }
503    ///
504    /// let first_element = array.replace_front(first_index, 100);
505    /// let first_element2 = array2.remove(first_index);
506    /// array2.push_front(100);
507    ///
508    /// assert_eq!(first_element, first_element2);
509    /// for (a, b) in array.iter().zip(&array2) {
510    ///     assert_eq!(a, b)
511    /// }
512    ///
513    /// let second_element = array.replace_front(first_index, 0);
514    /// let second_element2 = array2.remove(first_index);
515    /// array2.push_back(0);
516    ///
517    /// assert_eq!(second_element, second_element2);
518    ///
519    /// assert!(array.iter().zip(&array2).any(|(a, b)| a != b));
520    ///
521    /// assert_eq!(array.len(), 5);
522    /// assert_eq!(array2.len(), 5);
523    /// ```
524    pub fn replace_front(&mut self, index: usize, value: T) -> Option<T> {
525        let LinkedListNode {
526            next_index,
527            prev_index,
528            data,
529        } = mem::replace(
530            &mut self.elements[index],
531            LinkedListNode::front(self.first_index, value),
532        );
533
534        let removed = data.is_some();
535        self.connect_indices(prev_index, next_index, removed);
536
537        if !removed {
538            self.count += 1;
539        }
540
541        if self.first_index > 0 {
542            self.elements[self.first_index - 1].prev_index = index + 1;
543        }
544
545        self.first_index = index + 1;
546        data
547    }
548
549    /// Adds element at specified index at the front of the list.
550    /// Useful for updating contents.
551    ///
552    /// It basically does the same as `remove` and `push_back`, even if the specified index is already removed.
553    ///
554    /// # Panics
555    ///
556    /// Panics if index >= capacity
557    ///
558    /// # Examples
559    ///
560    /// ```
561    /// use array_linked_list::ArrayLinkedList;
562    ///
563    /// let mut array = ArrayLinkedList::new();
564    ///
565    /// array.push_front(1);
566    /// array.push_back(2);
567    /// let middle_index = array.push_back(3);
568    /// array.push_front(4);
569    /// array.push_back(5);
570    ///
571    /// let mut array2 = array.clone();
572    /// for (a, b) in array.iter().zip(&array2) {
573    ///     assert_eq!(a, b)
574    /// }
575    ///
576    /// let element = array.replace_back(middle_index, 100);
577    /// let element2 = array2.remove(middle_index);
578    /// array2.push_back(100);
579    ///
580    /// assert_eq!(element, element2);
581    /// for (a, b) in array.iter().zip(&array2) {
582    ///     assert_eq!(a, b)
583    /// }
584    ///
585    /// assert_eq!(array.len(), 5);
586    /// assert_eq!(array2.len(), 5);
587    /// ```
588    pub fn replace_back(&mut self, index: usize, value: T) -> Option<T> {
589        let LinkedListNode {
590            next_index,
591            prev_index,
592            data,
593        } = mem::replace(
594            &mut self.elements[index],
595            LinkedListNode::back(self.last_index, value),
596        );
597
598        let removed = data.is_some();
599        self.connect_indices(prev_index, next_index, removed);
600
601        if !removed {
602            self.count += 1;
603        }
604
605        if self.last_index > 0 {
606            self.elements[self.last_index - 1].next_index = index + 1;
607        }
608
609        self.last_index = index + 1;
610        data
611    }
612
613    /// Removes the first element from the array and returns it, or `None` if it is empty.
614    ///
615    /// This operation should compute in *O*(1) time.
616    ///
617    /// # Examples
618    ///
619    /// ```
620    /// use array_linked_list::ArrayLinkedList;
621    ///
622    /// let mut array = ArrayLinkedList::new();
623    /// assert_eq!(array.pop_front(), None);
624    /// array.push_back(1);
625    /// array.push_back(3);
626    /// assert_eq!(array.pop_front(), Some(1));
627    /// ```
628    pub fn pop_front(&mut self) -> Option<T> {
629        if self.first_index == 0 {
630            return None;
631        }
632        let index = self.first_index - 1;
633        let LinkedListNode {
634            next_index, data, ..
635        } = mem::replace(
636            &mut self.elements[index],
637            LinkedListNode::deleted(self.free_index),
638        );
639
640        *self.prev_of_next(next_index, true) = 0;
641        self.first_index = next_index;
642
643        self.count -= 1;
644        if self.free_index > 0 {
645            self.elements[self.free_index - 1].prev_index = index;
646        }
647
648        self.free_index = index;
649        Some(unsafe { data.unwrap_unchecked() })
650    }
651
652    /// Removes the last element from the array and returns it, or `None` if it is empty.
653    ///
654    /// This operation should compute in *O*(1) time.
655    ///
656    /// # Examples
657    ///
658    /// ```
659    /// use array_linked_list::ArrayLinkedList;
660    ///
661    /// let mut array = ArrayLinkedList::new();
662    /// assert_eq!(array.pop_back(), None);
663    /// array.push_back(1);
664    /// array.push_back(3);
665    /// assert_eq!(array.pop_back(), Some(3));
666    /// ```
667    pub fn pop_back(&mut self) -> Option<T> {
668        if self.last_index == 0 {
669            return None;
670        }
671        let index = self.last_index - 1;
672        let LinkedListNode {
673            prev_index, data, ..
674        } = mem::replace(
675            &mut self.elements[index],
676            LinkedListNode::deleted(self.free_index),
677        );
678
679        self.last_index = prev_index;
680        *self.next_of_prev(prev_index, true) = 0;
681
682        self.count -= 1;
683        if self.free_index > 0 {
684            self.elements[self.free_index - 1].prev_index = index;
685        }
686
687        self.free_index = index;
688        Some(unsafe { data.unwrap_unchecked() })
689    }
690
691    /// The index of the first list element.
692    /// Returns `None` if array is empty.
693    pub fn front_index(&self) -> Option<usize> {
694        if self.first_index > 0 {
695            Some(self.first_index - 1)
696        } else {
697            None
698        }
699    }
700
701    /// The index of the last list element.
702    /// Returns `None` if array is empty.
703    pub fn back_index(&self) -> Option<usize> {
704        if self.last_index > 0 {
705            Some(self.last_index - 1)
706        } else {
707            None
708        }
709    }
710
711    /// The first list element.
712    /// Returns `None` if array is empty.
713    pub fn front(&self) -> Option<&T> {
714        if self.first_index == 0 {
715            return None;
716        }
717
718        Some(unsafe {
719            self.elements[self.first_index - 1]
720                .data
721                .as_ref()
722                .unwrap_unchecked()
723        })
724    }
725
726    /// The last list element.
727    /// Returns `None` if array is empty.
728    pub fn back(&self) -> Option<&T> {
729        if self.last_index == 0 {
730            return None;
731        }
732
733        Some(unsafe {
734            self.elements[self.last_index - 1]
735                .data
736                .as_ref()
737                .unwrap_unchecked()
738        })
739    }
740
741    /// The first list element as a mutable reference.
742    /// Returns `None` if array is empty.
743    pub fn front_mut(&mut self) -> Option<&mut T> {
744        if self.first_index == 0 {
745            return None;
746        }
747
748        Some(unsafe {
749            self.elements[self.first_index - 1]
750                .data
751                .as_mut()
752                .unwrap_unchecked()
753        })
754    }
755
756    /// The last list element as a mutable reference.
757    /// Returns `None` if array is empty.
758    pub fn back_mut(&mut self) -> Option<&mut T> {
759        if self.last_index == 0 {
760            return None;
761        }
762
763        Some(unsafe {
764            self.elements[self.last_index - 1]
765                .data
766                .as_mut()
767                .unwrap_unchecked()
768        })
769    }
770
771    /// Checks if the list is empty.
772    pub fn is_empty(&self) -> bool {
773        self.first_index == 0 && self.last_index == 0
774    }
775
776    /// Clears the linked array, removing all values.
777    ///
778    /// Note that this method has no effect on the allocated capacity of the array.
779    /// So all indices, which have already been used (see `capacity`), are still available.
780    pub fn clear(&mut self) {
781        self.count = 0;
782        self.first_index = 0;
783        self.last_index = 0;
784        self.free_index = 0;
785        self.end_index = 0;
786
787        let capacity = self.elements.len();
788        self.elements.clear();
789        self.fill_elements(capacity);
790    }
791
792    /// Returns the number of elements in the linked array.
793    pub fn len(&self) -> usize {
794        self.count
795    }
796
797    /// Returns the number of elements the vector can hold without reallocating.
798    ///
799    /// Methods, which take indices, require the specified index to be below the capacity.
800    ///
801    /// All the following methods require indices:
802    ///
803    /// * `insert_before`
804    /// * `insert_after`
805    /// * `remove`
806    /// * `replace_front`
807    /// * `replace_back`
808    ///
809    /// Besides that, some of the iterators are constructed using indices in the same range.
810    pub fn capacity(&self) -> usize {
811        self.elements.len()
812    }
813
814    /// Returns a borrowing iterator over its elements.
815    pub fn iter(&self) -> impl DoubleEndedIterator<Item = &T> {
816        Values(Indexed::new(self))
817    }
818
819    /// Returns a borrowing iterator over its indexed elements.
820    pub fn indexed(&self) -> impl DoubleEndedIterator<Item = (usize, &T)> {
821        Indexed::new(self)
822    }
823
824    /// Returns a borrowing iterator over its indices.
825    pub fn indices(&self) -> impl DoubleEndedIterator<Item = usize> + '_ {
826        Indices(Indexed::new(self))
827    }
828
829    /// Returns a borrowing iterator over its elements, starting after the element at the specified index.
830    ///
831    /// # Panics
832    ///
833    /// Panics if index >= capacity
834    pub fn iter_after(&self, index: usize) -> impl DoubleEndedIterator<Item = &T> {
835        Values(Indexed::after(self, index))
836    }
837
838    /// Returns a borrowing iterator over its indexed elements, starting after the element at the specified index.
839    ///
840    /// # Panics
841    ///
842    /// Panics if index >= capacity
843    pub fn indexed_after(&self, index: usize) -> impl DoubleEndedIterator<Item = (usize, &T)> {
844        Indexed::after(self, index)
845    }
846
847    /// Returns a borrowing iterator over its indices, starting after the element at the specified index.
848    ///
849    /// # Panics
850    ///
851    /// Panics if index >= capacity
852    pub fn indices_after(&self, index: usize) -> impl DoubleEndedIterator<Item = usize> + '_ {
853        Indices(Indexed::after(self, index))
854    }
855
856    /// Returns a borrowing iterator over its elements, ending before the element at the specified index.
857    ///
858    /// # Panics
859    ///
860    /// Panics if index >= capacity
861    pub fn iter_before(&self, index: usize) -> impl DoubleEndedIterator<Item = &T> {
862        Values(Indexed::before(self, index))
863    }
864
865    /// Returns a borrowing iterator over its indexed elements, ending before the element at the specified index.
866    ///
867    /// # Panics
868    ///
869    /// Panics if index >= capacity
870    pub fn indexed_before(&self, index: usize) -> impl DoubleEndedIterator<Item = (usize, &T)> {
871        Indexed::before(self, index)
872    }
873
874    /// Returns a borrowing iterator over its indices, ending before the element at the specified index.
875    ///
876    /// # Panics
877    ///
878    /// Panics if index >= capacity
879    pub fn indices_before(&self, index: usize) -> impl DoubleEndedIterator<Item = usize> + '_ {
880        Indices(Indexed::before(self, index))
881    }
882
883    /// Returns an owning iterator returning its indexed elements.
884    pub fn into_indexed(self) -> impl DoubleEndedIterator<Item = (usize, T)> {
885        IntoIndexed(self)
886    }
887
888    /// Returns an owning iterator returning its indices.
889    pub fn into_indices(self) -> impl DoubleEndedIterator<Item = usize> {
890        IntoIndices(IntoIndexed(self))
891    }
892}
893
894impl<T> Index<usize> for ArrayLinkedList<T> {
895    type Output = Option<T>;
896    fn index(&self, index: usize) -> &Option<T> {
897        &self.elements[index].data
898    }
899}
900
901impl<T> IndexMut<usize> for ArrayLinkedList<T> {
902    fn index_mut(&mut self, index: usize) -> &mut Option<T> {
903        &mut self.elements[index].data
904    }
905}
906
907struct Indexed<'a, T> {
908    front_index: usize,
909    back_index: usize,
910    array: &'a ArrayLinkedList<T>,
911}
912
913impl<'a, T> Indexed<'a, T> {
914    fn empty(array: &'a ArrayLinkedList<T>) -> Self {
915        Self {
916            front_index: 0,
917            back_index: 0,
918            array,
919        }
920    }
921
922    fn new(array: &'a ArrayLinkedList<T>) -> Self {
923        Self {
924            front_index: array.first_index,
925            back_index: array.last_index,
926            array,
927        }
928    }
929
930    fn after(array: &'a ArrayLinkedList<T>, prev_index: usize) -> Self {
931        let element = &array.elements[prev_index];
932        if element.data.is_some() {
933            Self {
934                front_index: element.next_index,
935                back_index: array.last_index,
936                array,
937            }
938        } else {
939            Self::empty(array)
940        }
941    }
942
943    fn before(array: &'a ArrayLinkedList<T>, next_index: usize) -> Self {
944        let element = &array.elements[next_index];
945        if element.data.is_some() {
946            Self {
947                front_index: array.first_index,
948                back_index: element.prev_index,
949                array,
950            }
951        } else {
952            Self::empty(array)
953        }
954    }
955}
956
957struct Indices<'a, T>(Indexed<'a, T>);
958
959/// Borrowing iterator over values of the linked array.
960pub struct Values<'a, T>(Indexed<'a, T>);
961
962impl<'a, T> Iterator for Indexed<'a, T> {
963    type Item = (usize, &'a T);
964    #[inline]
965    fn next(&mut self) -> Option<Self::Item> {
966        if self.front_index == 0 {
967            return None;
968        }
969
970        let index = self.front_index - 1;
971        let element = &self.array.elements[index];
972        if self.front_index == self.back_index {
973            self.front_index = 0;
974            self.back_index = 0;
975        } else {
976            self.front_index = element.next_index;
977        }
978        Some((index, unsafe { element.data.as_ref().unwrap_unchecked() }))
979    }
980}
981
982impl<T> DoubleEndedIterator for Indexed<'_, T> {
983    #[inline]
984    fn next_back(&mut self) -> Option<Self::Item> {
985        if self.back_index == 0 {
986            return None;
987        }
988
989        let index = self.back_index - 1;
990        let element = &self.array.elements[index];
991        if self.front_index == self.back_index {
992            self.front_index = 0;
993            self.back_index = 0;
994        } else {
995            self.back_index = element.prev_index;
996        }
997        Some((index, unsafe { element.data.as_ref().unwrap_unchecked() }))
998    }
999}
1000
1001impl<T> Iterator for Indices<'_, T> {
1002    type Item = usize;
1003    fn next(&mut self) -> Option<Self::Item> {
1004        self.0.next().map(|(index, _)| index)
1005    }
1006}
1007
1008impl<T> DoubleEndedIterator for Indices<'_, T> {
1009    fn next_back(&mut self) -> Option<Self::Item> {
1010        self.0.next_back().map(|(index, _)| index)
1011    }
1012}
1013
1014impl<'a, T> Iterator for Values<'a, T> {
1015    type Item = &'a T;
1016    fn next(&mut self) -> Option<Self::Item> {
1017        self.0.next().map(|(_, value)| value)
1018    }
1019}
1020
1021impl<T> DoubleEndedIterator for Values<'_, T> {
1022    fn next_back(&mut self) -> Option<Self::Item> {
1023        self.0.next_back().map(|(_, value)| value)
1024    }
1025}
1026
1027impl<'a, T> IntoIterator for &'a ArrayLinkedList<T> {
1028    type Item = &'a T;
1029    type IntoIter = Values<'a, T>;
1030
1031    #[inline]
1032    fn into_iter(self) -> Self::IntoIter {
1033        Values(Indexed::new(self))
1034    }
1035}
1036
1037struct IntoIndexed<T>(ArrayLinkedList<T>);
1038struct IntoIndices<T>(IntoIndexed<T>);
1039
1040/// Owning iterator over values of the linked array.
1041pub struct IntoValues<T>(IntoIndexed<T>);
1042
1043impl<T> Iterator for IntoIndexed<T> {
1044    type Item = (usize, T);
1045    #[inline]
1046    fn next(&mut self) -> Option<Self::Item> {
1047        if self.0.first_index == 0 {
1048            return None;
1049        }
1050
1051        let index = self.0.first_index - 1;
1052        let element = &mut self.0.elements[index];
1053        if self.0.first_index == self.0.last_index {
1054            self.0.first_index = 0;
1055            self.0.last_index = 0;
1056        } else {
1057            self.0.first_index = element.next_index;
1058        }
1059        Some((index, unsafe { element.data.take().unwrap_unchecked() }))
1060    }
1061}
1062
1063impl<T> DoubleEndedIterator for IntoIndexed<T> {
1064    fn next_back(&mut self) -> Option<Self::Item> {
1065        if self.0.first_index == 0 {
1066            return None;
1067        }
1068
1069        let index = self.0.first_index - 1;
1070        let element = &mut self.0.elements[index];
1071        if self.0.first_index == self.0.last_index {
1072            self.0.first_index = 0;
1073            self.0.last_index = 0;
1074        } else {
1075            self.0.first_index = element.next_index;
1076        }
1077        Some((index, unsafe { element.data.take().unwrap_unchecked() }))
1078    }
1079}
1080
1081impl<T> Iterator for IntoIndices<T> {
1082    type Item = usize;
1083    fn next(&mut self) -> Option<Self::Item> {
1084        self.0.next().map(|(index, _)| index)
1085    }
1086}
1087
1088impl<T> DoubleEndedIterator for IntoIndices<T> {
1089    fn next_back(&mut self) -> Option<Self::Item> {
1090        self.0.next_back().map(|(index, _)| index)
1091    }
1092}
1093
1094impl<T> Iterator for IntoValues<T> {
1095    type Item = T;
1096    fn next(&mut self) -> Option<Self::Item> {
1097        self.0.next().map(|(_, value)| value)
1098    }
1099}
1100
1101impl<T> DoubleEndedIterator for IntoValues<T> {
1102    fn next_back(&mut self) -> Option<Self::Item> {
1103        self.0.next_back().map(|(_, value)| value)
1104    }
1105}
1106
1107impl<T> IntoIterator for ArrayLinkedList<T> {
1108    type Item = T;
1109    type IntoIter = IntoValues<T>;
1110
1111    fn into_iter(self) -> Self::IntoIter {
1112        IntoValues(IntoIndexed(self))
1113    }
1114}