Skip to main content

array_linked_list/
lib.rs

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