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}