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}