Skip to main content

tiered_vector/
lib.rs

1//
2// Copyright (c) 2025 Nathan Fiedler
3//
4
5//! An implementation of tiered vectors as described in the paper **Tiered
6//! Vectors** by Goodrich and Kloss II, published in 1999.
7//!
8//! * DOI:10.1007/3-540-48447-7_21
9//!
10//! This implementation is based on the algorithms described in the 1998 version
11//! of the paper titled **Tiered Vector** by the same authors. In short, the
12//! structure consists of a dope vector that references one or more circular
13//! buffers in which all buffers are full, with the exception of the last buffer
14//! which may be partially filled.
15//!
16//! # Memory Usage
17//!
18//! An empty resizable vector is approximately 72 bytes in size, and while
19//! holding elements it will have a space overhead on the order of O(√N) as
20//! described in the paper. As elements are added the vector will grow by
21//! allocating additional data blocks. Likewise, as elements are removed from
22//! the vector, data blocks will be deallocated as they become empty.
23//!
24//! # Performance
25//!
26//! The performance and memory layout is as described in the paper: O(√N) space
27//! overhead, O(1) get and update operations, and O(√n) insert and remove.
28//!
29//! # Safety
30//!
31//! Because this data structure is allocating memory, copying bytes using raw
32//! pointers, and de-allocating memory as needed, there are many `unsafe` blocks
33//! throughout the code.
34
35use std::alloc::{Layout, alloc, dealloc, handle_alloc_error};
36use std::fmt;
37use std::ops::{Index, IndexMut};
38
39/// Tiered vector which maintains a collection of circular deques in order to
40/// efficiently support insert and remove from any location within the vector.
41pub struct Vector<T> {
42    /// each deque is of size l = 2^k
43    k: usize,
44    /// bit-mask to get the index into a circular deque
45    k_mask: usize,
46    /// the 'l' value (2^k) cached for performance
47    l: usize,
48    /// when count increases to this size, expand the vector
49    upper_limit: usize,
50    /// when count decreases to this size, compress the vector
51    lower_limit: usize,
52    /// number of elements in the vector
53    count: usize,
54    /// dope vector
55    index: Vec<CyclicArray<T>>,
56}
57
58impl<T> Vector<T> {
59    /// Return an empty vector with zero capacity.
60    pub fn new() -> Self {
61        // default l value of 4 like std::vec::Vec does for its initial
62        // allocation (its initial capacity is zero then becomes 4 then doubles
63        // with each expansion)
64        Self {
65            k: 2,
66            k_mask: 3,
67            l: 4,
68            upper_limit: 16,
69            lower_limit: 0,
70            count: 0,
71            index: vec![],
72        }
73    }
74
75    /// Double the capacity of this vector by combining its deques into new
76    /// deques of double the capacity.
77    fn expand(&mut self) {
78        let l_prime = 1 << (self.k + 1);
79        let old_index: Vec<CyclicArray<T>> = std::mem::take(&mut self.index);
80        let mut iter = old_index.into_iter();
81        while let Some(a) = iter.next() {
82            if let Some(b) = iter.next() {
83                self.index.push(CyclicArray::combine(a, b));
84            } else {
85                self.index.push(CyclicArray::from(l_prime, a));
86            }
87        }
88        self.k += 1;
89        self.k_mask = (1 << self.k) - 1;
90        self.l = 1 << self.k;
91        self.upper_limit = self.l * self.l;
92        self.lower_limit = self.upper_limit / 8;
93    }
94
95    /// Inserts an element at position `index` within the array, shifting some
96    /// elements to the right as needed.
97    pub fn insert(&mut self, index: usize, value: T) {
98        let len = self.count;
99        if index > len {
100            panic!("insertion index (is {index}) should be <= len (is {len})");
101        }
102        if len >= self.upper_limit {
103            self.expand();
104        }
105        if len >= self.capacity() {
106            self.index.push(CyclicArray::<T>::new(self.l));
107        }
108        let sub = index >> self.k;
109        let end = len >> self.k;
110        let r_prime = index & self.k_mask;
111        if sub < end {
112            // push-pop phase
113            let mut head = self.index[sub].pop_back().unwrap();
114            for i in (sub + 1)..end {
115                let tail = self.index[i].pop_back().unwrap();
116                self.index[i].push_front(head);
117                head = tail;
118            }
119            self.index[end].push_front(head);
120        }
121        // shift phase
122        self.index[sub].insert(r_prime, value);
123        self.count += 1;
124    }
125
126    /// Appends an element to the back of a collection.
127    ///
128    /// # Panics
129    ///
130    /// Panics if a new block is allocated that would exceed `isize::MAX` _bytes_.
131    ///
132    /// # Time complexity
133    ///
134    /// O(√N) in the worst case.
135    pub fn push(&mut self, value: T) {
136        self.insert(self.count, value);
137    }
138
139    /// Appends an element if there is sufficient spare capacity, otherwise an
140    /// error is returned with the element.
141    ///
142    /// # Time complexity
143    ///
144    /// O(√N) in the worst case.
145    pub fn push_within_capacity(&mut self, value: T) -> Result<(), T> {
146        if self.capacity() <= self.count {
147            Err(value)
148        } else {
149            self.push(value);
150            Ok(())
151        }
152    }
153
154    /// Retrieve a reference to the element at the given offset.
155    ///
156    /// # Time complexity
157    ///
158    /// Constant time.
159    pub fn get(&self, index: usize) -> Option<&T> {
160        if index >= self.count {
161            None
162        } else {
163            let sub = index >> self.k;
164            let r_prime = index & self.k_mask;
165            self.index[sub].get(r_prime)
166        }
167    }
168
169    /// Returns a mutable reference to an element.
170    ///
171    /// # Time complexity
172    ///
173    /// Constant time.
174    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
175        if index >= self.count {
176            None
177        } else {
178            let sub = index >> self.k;
179            let r_prime = index & self.k_mask;
180            self.index[sub].get_mut(r_prime)
181        }
182    }
183
184    /// Shrink the capacity of this vector by splitting its deques into new
185    /// deques of half the capacity.
186    fn compress(&mut self) {
187        let old_index: Vec<CyclicArray<T>> = std::mem::take(&mut self.index);
188        for old_deque in old_index.into_iter() {
189            let (a, b) = old_deque.split();
190            self.index.push(a);
191            self.index.push(b);
192        }
193        self.k -= 1;
194        self.k_mask = (1 << self.k) - 1;
195        self.l = 1 << self.k;
196        self.upper_limit = self.l * self.l;
197        self.lower_limit = self.upper_limit / 8;
198    }
199
200    /// Removes an element from position `index` within the array, shifting some
201    /// elements to the left as needed to close the gap.
202    ///
203    /// # Time complexity
204    ///
205    /// O(√N) in the worst case.
206    pub fn remove(&mut self, index: usize) -> T {
207        let len = self.count;
208        if index >= len {
209            panic!("removal index (is {index}) should be < len (is {len})");
210        }
211        // avoid compressing to deques smaller than 4
212        if len < self.lower_limit && self.k > 2 {
213            self.compress();
214        }
215        let sub = index >> self.k;
216        let end = (len - 1) >> self.k;
217        let r_prime = index & self.k_mask;
218        // shift phase
219        let ret = self.index[sub].remove(r_prime);
220        if sub < end {
221            // push-pop phase
222            let mut tail = self.index[end].pop_front().unwrap();
223            for i in (sub + 1..end).rev() {
224                let head = self.index[i].pop_front().unwrap();
225                self.index[i].push_back(tail);
226                tail = head;
227            }
228            self.index[sub].push_back(tail);
229        }
230        if self.index[end].is_empty() {
231            // prune circular arrays as they become empty
232            self.index.pop();
233        }
234        self.count -= 1;
235        ret
236    }
237
238    /// Removes the last element from the vector and returns it, or `None` if the
239    /// vector is empty.
240    ///
241    /// # Time complexity
242    ///
243    /// O(√N) in the worst case.
244    pub fn pop(&mut self) -> Option<T> {
245        if self.count > 0 {
246            Some(self.remove(self.count - 1))
247        } else {
248            None
249        }
250    }
251
252    /// Removes and returns the last element from a vector if the predicate
253    /// returns true, or `None`` if the predicate returns `false`` or the vector
254    /// is empty (the predicate will not be called in that case).
255    ///
256    /// # Time complexity
257    ///
258    /// O(√N) in the worst case.
259    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
260        if self.count == 0 {
261            None
262        } else if let Some(last) = self.get_mut(self.count - 1) {
263            if predicate(last) { self.pop() } else { None }
264        } else {
265            None
266        }
267    }
268
269    // Returns an iterator over the vector.
270    //
271    // The iterator yields all items from start to end.
272    pub fn iter(&self) -> VectorIter<'_, T> {
273        VectorIter {
274            array: self,
275            index: 0,
276        }
277    }
278
279    /// Return the number of elements in the vector.
280    ///
281    /// # Time complexity
282    ///
283    /// Constant time.
284    pub fn len(&self) -> usize {
285        self.count
286    }
287
288    /// Returns the total number of elements the vector can hold without
289    /// reallocating.
290    ///
291    /// # Time complexity
292    ///
293    /// Constant time.
294    pub fn capacity(&self) -> usize {
295        (1 << self.k) * self.index.len()
296    }
297
298    /// Returns true if the array has a length of 0.
299    ///
300    /// # Time complexity
301    ///
302    /// Constant time.
303    pub fn is_empty(&self) -> bool {
304        self.count == 0
305    }
306
307    /// Clears the vector, removing all values and deallocating all blocks.
308    ///
309    /// # Time complexity
310    ///
311    /// O(n) if elements are droppable, otherwise O(√N)
312    pub fn clear(&mut self) {
313        self.index.clear();
314        self.count = 0;
315        self.k = 2;
316        self.k_mask = 3;
317        self.l = 1 << self.k;
318        self.upper_limit = self.l * self.l;
319        self.lower_limit = self.upper_limit / 8;
320    }
321}
322
323impl<T> Default for Vector<T> {
324    fn default() -> Self {
325        Self::new()
326    }
327}
328
329impl<T> fmt::Display for Vector<T> {
330    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331        write!(
332            f,
333            "Vector(k: {}, count: {}, dope: {})",
334            self.k,
335            self.count,
336            self.index.len(),
337        )
338    }
339}
340
341impl<T> Index<usize> for Vector<T> {
342    type Output = T;
343
344    fn index(&self, index: usize) -> &Self::Output {
345        let Some(item) = self.get(index) else {
346            panic!("index out of bounds: {}", index);
347        };
348        item
349    }
350}
351
352impl<T> IndexMut<usize> for Vector<T> {
353    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
354        let Some(item) = self.get_mut(index) else {
355            panic!("index out of bounds: {}", index);
356        };
357        item
358    }
359}
360
361impl<A> FromIterator<A> for Vector<A> {
362    fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self {
363        let mut arr: Vector<A> = Vector::new();
364        for value in iter {
365            arr.push(value)
366        }
367        arr
368    }
369}
370
371/// Immutable array iterator.
372pub struct VectorIter<'a, T> {
373    array: &'a Vector<T>,
374    index: usize,
375}
376
377impl<'a, T> Iterator for VectorIter<'a, T> {
378    type Item = &'a T;
379
380    fn next(&mut self) -> Option<Self::Item> {
381        let value = self.array.get(self.index);
382        self.index += 1;
383        value
384    }
385}
386
387impl<T> IntoIterator for Vector<T> {
388    type Item = T;
389    type IntoIter = VectorIntoIter<Self::Item>;
390
391    fn into_iter(self) -> Self::IntoIter {
392        let mut me = std::mem::ManuallyDrop::new(self);
393        let index = std::mem::take(&mut me.index);
394        VectorIntoIter {
395            count: me.count,
396            index,
397        }
398    }
399}
400
401/// An iterator that moves out of a tiered vector.
402pub struct VectorIntoIter<T> {
403    /// number of remaining elements
404    count: usize,
405    /// index of circular deques
406    index: Vec<CyclicArray<T>>,
407}
408
409impl<T> Iterator for VectorIntoIter<T> {
410    type Item = T;
411
412    fn next(&mut self) -> Option<Self::Item> {
413        if self.count > 0 {
414            let ret = self.index[0].pop_front();
415            self.count -= 1;
416            if self.index[0].is_empty() {
417                self.index.remove(0);
418            }
419            ret
420        } else {
421            None
422        }
423    }
424}
425
426/// Basic circular buffer, or what Goodrich and Kloss call a circular deque.
427///
428/// This implementation allows push and pop from both ends of the buffer and
429/// supports insert and remove from arbitrary offsets.
430///
431/// Unlike the `VecDeque` in the standard library, this array has a fixed size
432/// and will panic if a push is performed while the array is already full.
433pub struct CyclicArray<T> {
434    /// allocated buffer of size `capacity`
435    buffer: *mut T,
436    /// number of slots allocated in the buffer
437    capacity: usize,
438    /// offset of the first entry
439    head: usize,
440    /// number of elements
441    count: usize,
442}
443
444// SAFETY: a `CyclicArray` uniquely owns the elements behind its raw `buffer`
445// pointer, with no aliasing or shared interior state. It is therefore safe to
446// send to or share between threads whenever the elements themselves are, just
447// like the standard library's `Vec`. These impls also make the containing
448// `Vector` `Send`/`Sync` under the same bounds.
449unsafe impl<T: Send> Send for CyclicArray<T> {}
450unsafe impl<T: Sync> Sync for CyclicArray<T> {}
451
452impl<T> CyclicArray<T> {
453    /// Construct a new cyclic array with the given capacity.
454    pub fn new(capacity: usize) -> Self {
455        let buffer = if capacity == 0 || std::mem::size_of::<T>() == 0 {
456            // A zero-capacity array never dereferences its buffer, and a
457            // zero-sized type needs no allocation at all (allocating a
458            // zero-sized layout is undefined behavior). In both cases use a
459            // dangling but well-aligned pointer, as the standard library does.
460            std::ptr::NonNull::<T>::dangling().as_ptr()
461        } else {
462            let layout = Layout::array::<T>(capacity).expect("unexpected overflow");
463            unsafe {
464                let ptr = alloc(layout).cast::<T>();
465                if ptr.is_null() {
466                    handle_alloc_error(layout);
467                }
468                ptr
469            }
470        };
471        Self {
472            buffer,
473            capacity,
474            head: 0,
475            count: 0,
476        }
477    }
478
479    /// Free the buffer for this cyclic array without dropping the elements.
480    fn dealloc(&mut self) {
481        // A zero-capacity array and a zero-sized type both hold a dangling
482        // buffer that was never allocated; calling dealloc() on it is
483        // undefined behavior.
484        if self.capacity == 0 || std::mem::size_of::<T>() == 0 {
485            return;
486        }
487        let layout = Layout::array::<T>(self.capacity).expect("unexpected overflow");
488        unsafe {
489            dealloc(self.buffer as *mut u8, layout);
490        }
491    }
492
493    /// Take the elements from the two other cyclic arrays into a new cyclic
494    /// array with the combined capacity.
495    pub fn combine(a: CyclicArray<T>, b: CyclicArray<T>) -> Self {
496        let mut this: CyclicArray<T> = CyclicArray::new(a.capacity + b.capacity);
497        let mut this_pos = 0;
498        let their_a = std::mem::ManuallyDrop::new(a);
499        let their_b = std::mem::ManuallyDrop::new(b);
500        for mut other in [their_a, their_b] {
501            if other.head + other.count > other.capacity {
502                // data wraps around, copy as two blocks
503                let src = unsafe { other.buffer.add(other.head) };
504                let dst = unsafe { this.buffer.add(this_pos) };
505                let count_1 = other.capacity - other.head;
506                unsafe { std::ptr::copy(src, dst, count_1) }
507                this_pos += count_1;
508                let dst = unsafe { this.buffer.add(this_pos) };
509                let count_2 = other.count - count_1;
510                unsafe { std::ptr::copy(other.buffer, dst, count_2) }
511                this_pos += count_2;
512            } else {
513                // data is contiguous, copy as one block
514                let src = unsafe { other.buffer.add(other.head) };
515                let dst = unsafe { this.buffer.add(this_pos) };
516                unsafe { std::ptr::copy(src, dst, other.count) }
517                this_pos += other.count;
518            }
519            other.dealloc();
520            this.count += other.count;
521        }
522        this
523    }
524
525    /// Take the elements from the other cyclic array into a new cyclic array
526    /// with the given capacity.
527    pub fn from(capacity: usize, other: CyclicArray<T>) -> Self {
528        assert!(capacity > other.count, "count cannot be greater than capacity");
529        let buffer = if std::mem::size_of::<T>() == 0 {
530            // A zero-sized type needs no allocation; see CyclicArray::new.
531            std::ptr::NonNull::<T>::dangling().as_ptr()
532        } else {
533            let layout = Layout::array::<T>(capacity).expect("unexpected overflow");
534            unsafe {
535                let ptr = alloc(layout).cast::<T>();
536                if ptr.is_null() {
537                    handle_alloc_error(layout);
538                }
539                ptr
540            }
541        };
542        let mut them = std::mem::ManuallyDrop::new(other);
543        if them.head + them.count > them.capacity {
544            // data wraps around, copy as two blocks
545            let src = unsafe { them.buffer.add(them.head) };
546            let count_1 = them.capacity - them.head;
547            unsafe { std::ptr::copy(src, buffer, count_1) }
548            let dst = unsafe { buffer.add(count_1) };
549            let count_2 = them.count - count_1;
550            unsafe { std::ptr::copy(them.buffer, dst, count_2) }
551        } else {
552            // data is contiguous, copy as one block
553            let src = unsafe { them.buffer.add(them.head) };
554            unsafe { std::ptr::copy(src, buffer, them.count) }
555        }
556        them.dealloc();
557        Self {
558            buffer,
559            capacity,
560            head: 0,
561            count: them.count,
562        }
563    }
564
565    /// Split this cyclic buffer into two equal sized buffers.
566    ///
567    /// The second buffer may be empty if all elements fit within the first
568    /// buffer.
569    pub fn split(self) -> (CyclicArray<T>, CyclicArray<T>) {
570        assert!(
571            self.capacity.is_multiple_of(2),
572            "capacity must be an even number"
573        );
574        let half = self.capacity / 2;
575        let mut me = std::mem::ManuallyDrop::new(self);
576        let mut a: CyclicArray<T> = CyclicArray::new(half);
577        let mut b: CyclicArray<T> = CyclicArray::new(half);
578        let mut remaining = me.count;
579        for other in [&mut a, &mut b] {
580            let mut other_pos = 0;
581            while remaining > 0 && !other.is_full() {
582                let want_to_copy = if me.head + remaining > me.capacity {
583                    me.capacity - me.head
584                } else {
585                    remaining
586                };
587                let can_fit = other.capacity - other.count;
588                let to_copy = if want_to_copy > can_fit {
589                    can_fit
590                } else {
591                    want_to_copy
592                };
593                let src = unsafe { me.buffer.add(me.head) };
594                let dst = unsafe { other.buffer.add(other_pos) };
595                unsafe { std::ptr::copy(src, dst, to_copy) };
596                other_pos += to_copy;
597                other.count += to_copy;
598                me.head = me.physical_add(to_copy);
599                remaining -= to_copy;
600            }
601        }
602        me.dealloc();
603        (a, b)
604    }
605
606    /// Appends an element to the back of the cyclic array.
607    ///
608    /// # Panic
609    ///
610    /// Panics if the buffer is already full.
611    pub fn push_back(&mut self, value: T) {
612        if self.count == self.capacity {
613            panic!("cyclic array is full")
614        }
615        let off = self.physical_add(self.count);
616        unsafe { std::ptr::write(self.buffer.add(off), value) }
617        self.count += 1;
618    }
619
620    /// Prepends an element to the front of the cyclic array.
621    ///
622    /// # Panic
623    ///
624    /// Panics if the buffer is already full.
625    pub fn push_front(&mut self, value: T) {
626        if self.count == self.capacity {
627            panic!("cyclic array is full")
628        }
629        self.head = self.physical_sub(1);
630        unsafe { std::ptr::write(self.buffer.add(self.head), value) }
631        self.count += 1;
632    }
633
634    /// Removes the last element and returns it, or `None` if the cyclic array
635    /// is empty.
636    pub fn pop_back(&mut self) -> Option<T> {
637        if self.count == 0 {
638            None
639        } else {
640            self.count -= 1;
641            let off = self.physical_add(self.count);
642            unsafe { Some(std::ptr::read(self.buffer.add(off))) }
643        }
644    }
645
646    /// Removes the first element and returns it, or `None` if the cyclic array
647    /// is empty.
648    pub fn pop_front(&mut self) -> Option<T> {
649        if self.count == 0 {
650            None
651        } else {
652            let old_head = self.head;
653            self.head = self.physical_add(1);
654            self.count -= 1;
655            unsafe { Some(std::ptr::read(self.buffer.add(old_head))) }
656        }
657    }
658
659    /// Inserts an element at position `index` within the array, possibly
660    /// shifting some elements to the left or the right as needed.
661    pub fn insert(&mut self, index: usize, value: T) {
662        let len = self.count;
663        if index > len {
664            panic!("insertion index (is {index}) should be <= len (is {len})");
665        }
666        if len == self.capacity {
667            panic!("cyclic array is full")
668        }
669        //
670        // Some free space exists in the array, either on the left, the right,
671        // the middle, at both ends, or the entire array is empty. Regardless,
672        // there are two cases, shift some elements to the left or to the right.
673        //
674        let mut r_prime = self.physical_add(index);
675        if len > 0 && index < len {
676            // need to make space for the new element
677            if self.head == 0 || r_prime < self.head {
678                // Slide all elements in S,sub of rank greater than or equal to
679                // r’ and less than (|S,sub| — r’) mod l to the right by one
680                let src = unsafe { self.buffer.add(r_prime) };
681                let dst = unsafe { self.buffer.add(r_prime + 1) };
682                let count = self.count - index;
683                unsafe { std::ptr::copy(src, dst, count) }
684            } else {
685                // Slide all elements in S,sub of rank less than r’ and greater
686                // than or equal to h,sub to the left by one
687                let src = unsafe { self.buffer.add(self.head) };
688                let count = r_prime - self.head;
689                self.head = self.physical_sub(1);
690                let dst = unsafe { self.buffer.add(self.head) };
691                unsafe { std::ptr::copy(src, dst, count) }
692                r_prime -= 1;
693            }
694        }
695        unsafe { std::ptr::write(self.buffer.add(r_prime), value) }
696        self.count += 1;
697    }
698
699    /// Removes and returns the element at position `index` within the array,
700    /// shifting some elements to the left or to the right.
701    pub fn remove(&mut self, index: usize) -> T {
702        let len = self.count;
703        if index >= len {
704            panic!("removal index (is {index}) should be < len (is {len})");
705        }
706        let r_prime = self.physical_add(index);
707        let ret = unsafe { std::ptr::read(self.buffer.add(r_prime)) };
708        if index < (len - 1) {
709            // need to slide elements to fill the new gap
710            if self.head == 0 || r_prime < self.head {
711                // Slide all elements in S,sub of rank r'+1 to h,sub + |S,sub| to
712                // the left by one
713                let src = unsafe { self.buffer.add(r_prime + 1) };
714                let dst = unsafe { self.buffer.add(r_prime) };
715                let count = self.count - index - 1;
716                unsafe { std::ptr::copy(src, dst, count) }
717            } else {
718                // Slide all elements in S,sub of rank greater than or equal to
719                // h,sub and less than r' to the right by one
720                let src = unsafe { self.buffer.add(self.head) };
721                let count = r_prime - self.head;
722                self.head = self.physical_add(1);
723                let dst = unsafe { self.buffer.add(self.head) };
724                unsafe { std::ptr::copy(src, dst, count) }
725            }
726        }
727        self.count -= 1;
728        ret
729    }
730
731    /// Provides a reference to the element at the given index.
732    pub fn get(&self, index: usize) -> Option<&T> {
733        if index < self.count {
734            let idx = self.physical_add(index);
735            unsafe { Some(&*self.buffer.add(idx)) }
736        } else {
737            None
738        }
739    }
740
741    /// Returns a mutable reference to an element.
742    pub fn get_mut(&mut self, index: usize) -> Option<&mut T> {
743        if index < self.count {
744            let idx = self.physical_add(index);
745            unsafe { (self.buffer.add(idx)).as_mut() }
746        } else {
747            None
748        }
749    }
750
751    /// Clears the cyclic array, removing and dropping all values.
752    pub fn clear(&mut self) {
753        use std::ptr::{drop_in_place, slice_from_raw_parts_mut};
754
755        if self.count > 0 && std::mem::needs_drop::<T>() {
756            let first_slot = self.physical_add(0);
757            let last_slot = self.physical_add(self.count);
758            if first_slot < last_slot {
759                // elements are in one contiguous block
760                unsafe {
761                    drop_in_place(slice_from_raw_parts_mut(
762                        self.buffer.add(first_slot),
763                        last_slot - first_slot,
764                    ));
765                }
766            } else {
767                // elements wrap around the end of the buffer
768                unsafe {
769                    // drop the elements at the end of the buffer
770                    drop_in_place(slice_from_raw_parts_mut(
771                        self.buffer.add(first_slot),
772                        self.capacity - first_slot,
773                    ));
774                    // drop the elements at the start of the buffer, if any
775                    if first_slot != last_slot || first_slot != 0 {
776                        drop_in_place(slice_from_raw_parts_mut(self.buffer, last_slot));
777                    }
778                }
779            }
780        }
781        self.head = 0;
782        self.count = 0;
783    }
784
785    /// Return the number of elements in the array.
786    pub fn len(&self) -> usize {
787        self.count
788    }
789
790    /// Returns the total number of elements the cyclic array can hold.
791    pub fn capacity(&self) -> usize {
792        self.capacity
793    }
794
795    /// Returns true if the array has a length of 0.
796    pub fn is_empty(&self) -> bool {
797        self.count == 0
798    }
799
800    /// Returns true if the array has a length equal to its capacity.
801    pub fn is_full(&self) -> bool {
802        self.count == self.capacity
803    }
804
805    /// Perform a wrapping addition relative to the head of the array and
806    /// convert the logical offset to the physical offset within the array.
807    fn physical_add(&self, addend: usize) -> usize {
808        let logical_index = self.head.wrapping_add(addend);
809        if logical_index >= self.capacity {
810            logical_index - self.capacity
811        } else {
812            logical_index
813        }
814    }
815
816    /// Perform a wrapping subtraction relative to the head of the array and
817    /// convert the logical offset to the physical offset within the array.
818    fn physical_sub(&self, subtrahend: usize) -> usize {
819        let logical_index = self
820            .head
821            .wrapping_sub(subtrahend)
822            .wrapping_add(self.capacity);
823        if logical_index >= self.capacity {
824            logical_index - self.capacity
825        } else {
826            logical_index
827        }
828    }
829}
830
831impl<T> Default for CyclicArray<T> {
832    fn default() -> Self {
833        Self::new(0)
834    }
835}
836
837impl<T> fmt::Display for CyclicArray<T> {
838    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
839        write!(
840            f,
841            "CyclicArray(capacity: {}, head: {}, count: {})",
842            self.capacity, self.head, self.count,
843        )
844    }
845}
846
847impl<T> Index<usize> for CyclicArray<T> {
848    type Output = T;
849
850    fn index(&self, index: usize) -> &Self::Output {
851        let Some(item) = self.get(index) else {
852            panic!("index out of bounds: {}", index);
853        };
854        item
855    }
856}
857
858impl<T> IndexMut<usize> for CyclicArray<T> {
859    fn index_mut(&mut self, index: usize) -> &mut Self::Output {
860        let Some(item) = self.get_mut(index) else {
861            panic!("index out of bounds: {}", index);
862        };
863        item
864    }
865}
866
867impl<T> Drop for CyclicArray<T> {
868    fn drop(&mut self) {
869        self.clear();
870        self.dealloc();
871    }
872}
873
874#[cfg(test)]
875mod tests {
876    use super::*;
877
878    #[test]
879    fn test_vector_insert_head() {
880        let mut sut = Vector::<usize>::new();
881        assert!(sut.is_empty());
882        for value in (1..=16).rev() {
883            sut.insert(0, value);
884        }
885        assert!(!sut.is_empty());
886        for (index, value) in (1..=16).enumerate() {
887            assert_eq!(sut[index], value);
888        }
889    }
890
891    #[test]
892    fn test_vector_push_and_clear() {
893        let mut sut = Vector::<usize>::new();
894        assert!(sut.is_empty());
895        for value in 0..64 {
896            sut.push(value);
897        }
898        assert!(!sut.is_empty());
899        assert_eq!(sut.len(), 64);
900        assert_eq!(sut.capacity(), 64);
901        for value in 0..64 {
902            assert_eq!(sut[value], value);
903        }
904        sut.clear();
905        assert!(sut.is_empty());
906        assert_eq!(sut.len(), 0);
907        assert_eq!(sut.capacity(), 0);
908    }
909
910    #[test]
911    fn test_vector_get_mut() {
912        let mut sut = Vector::<usize>::new();
913        for value in 0..4 {
914            sut.push(value);
915        }
916        if let Some(value) = sut.get_mut(1) {
917            *value = 11;
918        } else {
919            panic!("get_mut() returned None")
920        }
921        sut[2] = 12;
922        assert_eq!(sut.len(), 4);
923        assert_eq!(sut[0], 0);
924        assert_eq!(sut[1], 11);
925        assert_eq!(sut[2], 12);
926        assert_eq!(sut[3], 3);
927    }
928
929    #[test]
930    fn test_vector_insert_expand() {
931        let mut sut = Vector::<usize>::new();
932        assert!(sut.is_empty());
933        for value in (1..=130).rev() {
934            sut.insert(0, value);
935        }
936        assert!(!sut.is_empty());
937        assert_eq!(sut.len(), 130);
938        assert_eq!(sut.capacity(), 144);
939        for value in 0..130 {
940            assert_eq!(sut[value], value + 1);
941        }
942    }
943
944    #[test]
945    fn test_vector_push_many() {
946        let mut sut = Vector::<usize>::new();
947        assert!(sut.is_empty());
948        for value in 0..100_000 {
949            sut.push(value);
950        }
951        assert!(!sut.is_empty());
952        assert_eq!(sut.len(), 100_000);
953        assert_eq!(sut.capacity(), 100352);
954        for value in 0..100_000 {
955            assert_eq!(sut[value], value);
956        }
957    }
958
959    #[test]
960    fn test_vector_push_within_capacity() {
961        // empty array has no allocated space
962        let mut sut = Vector::<u32>::new();
963        assert_eq!(sut.push_within_capacity(101), Err(101));
964        sut.push(1);
965        sut.push(2);
966        assert_eq!(sut.push_within_capacity(3), Ok(()));
967        assert_eq!(sut.push_within_capacity(4), Ok(()));
968        assert_eq!(sut.push_within_capacity(5), Err(5));
969    }
970
971    #[test]
972    fn test_vector_remove_small() {
973        let mut sut = Vector::<usize>::new();
974        assert!(sut.is_empty());
975        assert_eq!(sut.len(), 0);
976        for value in 0..15 {
977            sut.push(value);
978        }
979        assert!(!sut.is_empty());
980        assert_eq!(sut.len(), 15);
981        for value in 0..15 {
982            assert_eq!(sut.remove(0), value);
983        }
984        assert!(sut.is_empty());
985        assert_eq!(sut.len(), 0);
986        assert_eq!(sut.capacity(), 0);
987    }
988
989    #[test]
990    fn test_vector_remove_medium() {
991        let mut sut = Vector::<usize>::new();
992        assert!(sut.is_empty());
993        assert_eq!(sut.len(), 0);
994        assert_eq!(sut.capacity(), 0);
995        for value in 0..2048 {
996            sut.push(value);
997        }
998        assert!(!sut.is_empty());
999        assert_eq!(sut.len(), 2048);
1000        assert_eq!(sut.capacity(), 2048);
1001        for value in 0..2048 {
1002            assert_eq!(sut.remove(0), value);
1003        }
1004        assert!(sut.is_empty());
1005        assert_eq!(sut.len(), 0);
1006        assert_eq!(sut.capacity(), 0);
1007    }
1008
1009    #[test]
1010    fn test_vector_expand_and_compress() {
1011        // add enough to cause multiple expansions
1012        let mut sut = Vector::<usize>::new();
1013        for value in 0..1024 {
1014            sut.push(value);
1015        }
1016        assert_eq!(sut.len(), 1024);
1017        assert_eq!(sut.capacity(), 1024);
1018        // remove enough to cause multiple compressions
1019        for _ in 0..960 {
1020            sut.pop();
1021        }
1022        // ensure the correct elements remain
1023        assert_eq!(sut.len(), 64);
1024        assert_eq!(sut.capacity(), 64);
1025        for value in 0..64 {
1026            assert_eq!(sut[value], value);
1027        }
1028    }
1029
1030    #[test]
1031    fn test_vector_pop_small() {
1032        let mut sut = Vector::<usize>::new();
1033        assert!(sut.is_empty());
1034        assert_eq!(sut.len(), 0);
1035        for value in 0..15 {
1036            sut.push(value);
1037        }
1038        assert!(!sut.is_empty());
1039        assert_eq!(sut.len(), 15);
1040        for value in (0..15).rev() {
1041            assert_eq!(sut.pop(), Some(value));
1042        }
1043        assert!(sut.is_empty());
1044        assert_eq!(sut.len(), 0);
1045        assert_eq!(sut.capacity(), 0);
1046    }
1047
1048    #[test]
1049    fn test_vector_pop_if() {
1050        let mut sut = Vector::<u32>::new();
1051        assert!(sut.pop_if(|_| panic!("should not be called")).is_none());
1052        for value in 0..10 {
1053            sut.push(value);
1054        }
1055        assert!(sut.pop_if(|_| false).is_none());
1056        let maybe = sut.pop_if(|v| *v == 9);
1057        assert_eq!(maybe.unwrap(), 9);
1058        assert!(sut.pop_if(|v| *v == 9).is_none());
1059    }
1060
1061    #[test]
1062    fn test_vector_iter() {
1063        let mut sut = Vector::<usize>::new();
1064        for value in 0..1000 {
1065            sut.push(value);
1066        }
1067        assert_eq!(sut.len(), 1000);
1068        for (index, value) in sut.iter().enumerate() {
1069            assert_eq!(sut[index], *value);
1070        }
1071    }
1072
1073    #[test]
1074    fn test_vector_from_iterator() {
1075        let mut inputs: Vec<i32> = Vec::new();
1076        for value in 0..10_000 {
1077            inputs.push(value);
1078        }
1079        let sut: Vector<i32> = inputs.into_iter().collect();
1080        assert_eq!(sut.len(), 10_000);
1081        for idx in 0..10_000i32 {
1082            let maybe = sut.get(idx as usize);
1083            assert!(maybe.is_some(), "{idx} is none");
1084            let actual = maybe.unwrap();
1085            assert_eq!(idx, *actual);
1086        }
1087    }
1088
1089    #[test]
1090    fn test_vector_into_iterator_drop_empty() {
1091        let sut: Vector<String> = Vector::new();
1092        assert_eq!(sut.into_iter().count(), 0);
1093    }
1094
1095    #[test]
1096    fn test_vector_into_iterator_ints_done() {
1097        let mut sut = Vector::<usize>::new();
1098        for value in 0..1024 {
1099            sut.push(value);
1100        }
1101        for (idx, elem) in sut.into_iter().enumerate() {
1102            assert_eq!(idx, elem);
1103        }
1104        // sut.len(); // error: ownership of sut was moved
1105    }
1106
1107    #[test]
1108    fn test_vector_remove_insert_basic() {
1109        let mut sut = Vector::<usize>::new();
1110        for value in 1..=16 {
1111            sut.push(value);
1112        }
1113        let value = sut.remove(3);
1114        sut.insert(7, value);
1115        let mut sorted: Vec<usize> = sut.into_iter().collect();
1116        sorted.sort();
1117        for (index, value) in (1..=16).enumerate() {
1118            assert_eq!(sorted[index], value);
1119        }
1120    }
1121
1122    #[test]
1123    fn test_vector_random_insert_remove() {
1124        // trade-off of exhaustive randomized testing and running time
1125        let mut sut = Vector::<usize>::new();
1126        let size = 100_000;
1127        for value in 1..=size {
1128            sut.push(value);
1129        }
1130        for _ in 0..200_000 {
1131            let from = rand::random_range(0..size);
1132            let to = rand::random_range(0..size - 1);
1133            let value = sut.remove(from);
1134            sut.insert(to, value);
1135        }
1136        let mut sorted: Vec<usize> = sut.into_iter().collect();
1137        sorted.sort();
1138        for (idx, value) in (1..=size).enumerate() {
1139            assert_eq!(sorted[idx], value);
1140        }
1141    }
1142
1143    #[test]
1144    fn test_vector_push_pop_strings() {
1145        let mut array: Vector<String> = Vector::new();
1146        for _ in 0..1024 {
1147            let value = ulid::Ulid::new().to_string();
1148            array.push(value);
1149        }
1150        assert_eq!(array.len(), 1024);
1151        while let Some(s) = array.pop() {
1152            assert!(!s.is_empty());
1153        }
1154    }
1155
1156    #[test]
1157    fn test_cyclic_array_zero_capacity() {
1158        let sut = CyclicArray::<usize>::new(0);
1159        assert_eq!(sut.len(), 0);
1160        assert_eq!(sut.capacity(), 0);
1161        assert!(sut.is_empty());
1162        assert!(sut.is_full());
1163    }
1164
1165    #[test]
1166    #[should_panic(expected = "cyclic array is full")]
1167    fn test_cyclic_array_zero_push_panics() {
1168        let mut sut = CyclicArray::<usize>::new(0);
1169        sut.push_back(101);
1170    }
1171
1172    #[test]
1173    fn test_cyclic_array_forward() {
1174        let mut sut = CyclicArray::<usize>::new(10);
1175        assert_eq!(sut.len(), 0);
1176        assert_eq!(sut.capacity(), 10);
1177        assert!(sut.is_empty());
1178        assert!(!sut.is_full());
1179
1180        // add until full
1181        for value in 0..sut.capacity() {
1182            sut.push_back(value);
1183        }
1184        assert_eq!(sut.len(), 10);
1185        assert_eq!(sut.capacity(), 10);
1186        assert!(!sut.is_empty());
1187        assert!(sut.is_full());
1188
1189        assert_eq!(sut.get(1), Some(&1));
1190        assert_eq!(sut[1], 1);
1191        assert_eq!(sut.get(3), Some(&3));
1192        assert_eq!(sut[3], 3);
1193        assert_eq!(sut.get(6), Some(&6));
1194        assert_eq!(sut[6], 6);
1195        assert_eq!(sut.get(9), Some(&9));
1196        assert_eq!(sut[9], 9);
1197        assert_eq!(sut.get(10), None);
1198
1199        // remove until empty
1200        for index in 0..10 {
1201            let maybe = sut.pop_front();
1202            assert!(maybe.is_some());
1203            let value = maybe.unwrap();
1204            assert_eq!(value, index);
1205        }
1206        assert_eq!(sut.len(), 0);
1207        assert_eq!(sut.capacity(), 10);
1208        assert!(sut.is_empty());
1209        assert!(!sut.is_full());
1210    }
1211
1212    #[test]
1213    fn test_cyclic_array_backward() {
1214        let mut sut = CyclicArray::<usize>::new(10);
1215        assert_eq!(sut.len(), 0);
1216        assert_eq!(sut.capacity(), 10);
1217        assert!(sut.is_empty());
1218        assert!(!sut.is_full());
1219
1220        // add until full
1221        for value in 0..sut.capacity() {
1222            sut.push_front(value);
1223        }
1224        assert_eq!(sut.len(), 10);
1225        assert_eq!(sut.capacity(), 10);
1226        assert!(!sut.is_empty());
1227        assert!(sut.is_full());
1228
1229        // everything is backwards
1230        assert_eq!(sut.get(1), Some(&8));
1231        assert_eq!(sut[1], 8);
1232        assert_eq!(sut.get(3), Some(&6));
1233        assert_eq!(sut[3], 6);
1234        assert_eq!(sut.get(6), Some(&3));
1235        assert_eq!(sut[6], 3);
1236        assert_eq!(sut.get(9), Some(&0));
1237        assert_eq!(sut[9], 0);
1238        assert_eq!(sut.get(10), None);
1239
1240        // remove until empty
1241        for index in 0..10 {
1242            let maybe = sut.pop_back();
1243            assert!(maybe.is_some());
1244            let value = maybe.unwrap();
1245            assert_eq!(value, index);
1246        }
1247        assert_eq!(sut.len(), 0);
1248        assert_eq!(sut.capacity(), 10);
1249        assert!(sut.is_empty());
1250        assert!(!sut.is_full());
1251    }
1252
1253    #[test]
1254    #[should_panic(expected = "index out of bounds:")]
1255    fn test_cyclic_array_index_out_of_bounds() {
1256        let mut sut = CyclicArray::<usize>::new(10);
1257        sut.push_back(10);
1258        sut.push_back(20);
1259        let _ = sut[2];
1260    }
1261
1262    #[test]
1263    fn test_cyclic_array_clear_and_reuse() {
1264        let mut sut = CyclicArray::<String>::new(10);
1265        for _ in 0..7 {
1266            let value = ulid::Ulid::new().to_string();
1267            sut.push_back(value);
1268        }
1269        sut.clear();
1270        for _ in 0..7 {
1271            let value = ulid::Ulid::new().to_string();
1272            sut.push_back(value);
1273        }
1274        sut.clear();
1275        for _ in 0..7 {
1276            let value = ulid::Ulid::new().to_string();
1277            sut.push_back(value);
1278        }
1279        sut.clear();
1280    }
1281
1282    #[test]
1283    fn test_cyclic_array_drop_partial() {
1284        let mut sut = CyclicArray::<String>::new(10);
1285        for _ in 0..7 {
1286            let value = ulid::Ulid::new().to_string();
1287            sut.push_back(value);
1288        }
1289        drop(sut);
1290    }
1291
1292    #[test]
1293    fn test_cyclic_array_drop_full() {
1294        let mut sut = CyclicArray::<String>::new(10);
1295        for _ in 0..sut.capacity() {
1296            let value = ulid::Ulid::new().to_string();
1297            sut.push_back(value);
1298        }
1299        drop(sut);
1300    }
1301
1302    #[test]
1303    fn test_cyclic_array_drop_wrapped() {
1304        let mut sut = CyclicArray::<String>::new(10);
1305        // push enough to almost fill the buffer
1306        for _ in 0..7 {
1307            let value = ulid::Ulid::new().to_string();
1308            sut.push_back(value);
1309        }
1310        // empty the buffer
1311        while !sut.is_empty() {
1312            sut.pop_front();
1313        }
1314        // push enough to wrap around to the start of the physical buffer
1315        for _ in 0..7 {
1316            let value = ulid::Ulid::new().to_string();
1317            sut.push_back(value);
1318        }
1319        drop(sut);
1320    }
1321
1322    #[test]
1323    #[should_panic(expected = "cyclic array is full")]
1324    fn test_cyclic_array_full_panic() {
1325        let mut sut = CyclicArray::<usize>::new(1);
1326        sut.push_back(10);
1327        sut.push_back(20);
1328    }
1329
1330    #[test]
1331    fn test_cyclic_array_wrapping() {
1332        let mut sut = CyclicArray::<usize>::new(10);
1333        // push enough to almost fill the buffer
1334        for value in 0..7 {
1335            sut.push_back(value);
1336        }
1337        // empty the buffer
1338        while !sut.is_empty() {
1339            sut.pop_front();
1340        }
1341        // push enough to wrap around to the start of the physical buffer
1342        for value in 0..7 {
1343            sut.push_back(value);
1344        }
1345
1346        assert_eq!(sut.get(1), Some(&1));
1347        assert_eq!(sut[1], 1);
1348        assert_eq!(sut.get(3), Some(&3));
1349        assert_eq!(sut[3], 3);
1350        assert_eq!(sut.get(6), Some(&6));
1351        assert_eq!(sut[6], 6);
1352        assert_eq!(sut.get(8), None);
1353
1354        // ensure values are removed correctly
1355        for value in 0..7 {
1356            assert_eq!(sut.pop_front(), Some(value));
1357        }
1358        assert_eq!(sut.len(), 0);
1359        assert_eq!(sut.capacity(), 10);
1360        assert!(sut.is_empty());
1361        assert!(!sut.is_full());
1362    }
1363
1364    #[test]
1365    fn test_cyclic_array_random_insert_remove() {
1366        let size = 128;
1367        let mut sut = CyclicArray::<usize>::new(size);
1368        for value in 1..=size {
1369            sut.push_back(value);
1370        }
1371        for _ in 0..1024 {
1372            let from = rand::random_range(0..size);
1373            let to = rand::random_range(0..size - 1);
1374            let value = sut.remove(from);
1375            sut.insert(to, value);
1376        }
1377        let mut sorted: Vec<usize> = vec![];
1378        while let Some(value) = sut.pop_front() {
1379            sorted.push(value);
1380        }
1381        sorted.sort();
1382        for (idx, value) in (1..=size).enumerate() {
1383            assert_eq!(sorted[idx], value);
1384        }
1385    }
1386
1387    #[test]
1388    fn test_cyclic_array_insert_head() {
1389        let mut sut = CyclicArray::<usize>::new(4);
1390        sut.insert(0, 4);
1391        sut.insert(0, 3);
1392        sut.insert(0, 2);
1393        sut.insert(0, 1);
1394        assert_eq!(sut.len(), 4);
1395        assert_eq!(sut[0], 1);
1396        assert_eq!(sut[1], 2);
1397        assert_eq!(sut[2], 3);
1398        assert_eq!(sut[3], 4);
1399    }
1400
1401    #[test]
1402    fn test_cyclic_array_insert_empty() {
1403        let mut sut = CyclicArray::<usize>::new(4);
1404        // start with:
1405        // ```
1406        // +---+---+---+---+
1407        // |   |   |   |   |
1408        // +---+---+---+---+
1409        // ```
1410        // becomes:
1411        // ```
1412        // +---+---+---+---+
1413        // | 1 |   |   |   |
1414        // +---+---+---+---+
1415        // ```
1416        sut.insert(0, 1);
1417        assert_eq!(sut[0], 1);
1418        assert_eq!(sut.len(), 1);
1419    }
1420
1421    #[test]
1422    fn test_cyclic_array_insert_empty_head_not_zero() {
1423        let mut sut = CyclicArray::<usize>::new(4);
1424        sut.push_back(1);
1425        sut.push_back(2);
1426        sut.pop_front();
1427        sut.pop_front();
1428        sut.insert(0, 1);
1429        assert_eq!(sut[0], 1);
1430        assert_eq!(sut.len(), 1);
1431    }
1432
1433    #[test]
1434    fn test_cyclic_array_insert_loop() {
1435        let mut sut = CyclicArray::<usize>::new(4);
1436        for value in 0..100 {
1437            sut.insert(0, value);
1438            sut.insert(0, value);
1439            sut.insert(0, value);
1440            sut.pop_front();
1441            sut.pop_front();
1442            sut.pop_front();
1443        }
1444        assert_eq!(sut.len(), 0);
1445        sut.push_back(1);
1446        sut.push_back(2);
1447        sut.push_back(3);
1448        sut.push_back(4);
1449        assert_eq!(sut.len(), 4);
1450        assert_eq!(sut[0], 1);
1451        assert_eq!(sut[1], 2);
1452        assert_eq!(sut[2], 3);
1453        assert_eq!(sut[3], 4);
1454    }
1455
1456    #[test]
1457    fn test_cyclic_array_insert_1() {
1458        let mut sut = CyclicArray::<usize>::new(4);
1459        // start with:
1460        // ```
1461        // +---+---+---+---+
1462        // | 1 | 2 |   |   |
1463        // +---+---+---+---+
1464        // ```
1465        // becomes:
1466        // ```
1467        // +---+---+---+---+
1468        // | 1 | 3 | 2 |   |
1469        // +---+---+---+---+
1470        // ```
1471        sut.push_back(1);
1472        sut.push_back(2);
1473        sut.insert(1, 3);
1474        assert_eq!(sut.len(), 3);
1475        assert_eq!(sut[0], 1);
1476        assert_eq!(sut[1], 3);
1477        assert_eq!(sut[2], 2);
1478    }
1479
1480    #[test]
1481    fn test_cyclic_array_insert_2() {
1482        let mut sut = CyclicArray::<usize>::new(4);
1483        // start with:
1484        // ```
1485        // +---+---+---+---+
1486        // | 2 |   |   | 1 |
1487        // +---+---+---+---+
1488        // ```
1489        // becomes:
1490        // ```
1491        // +---+---+---+---+
1492        // | 3 | 2 |   | 1 |
1493        // +---+---+---+---+
1494        // ```
1495        sut.push_back(1);
1496        sut.push_back(1);
1497        sut.push_back(1);
1498        sut.push_back(1);
1499        sut.pop_front();
1500        sut.pop_front();
1501        sut.pop_front();
1502        sut.push_back(2);
1503        sut.insert(1, 3);
1504        assert_eq!(sut.len(), 3);
1505        assert_eq!(sut[0], 1);
1506        assert_eq!(sut[1], 3);
1507        assert_eq!(sut[2], 2);
1508    }
1509
1510    #[test]
1511    fn test_cyclic_array_insert_3() {
1512        let mut sut = CyclicArray::<usize>::new(4);
1513        // start with:
1514        // ```
1515        // +---+---+---+---+
1516        // |   |   | 1 | 2 |
1517        // +---+---+---+---+
1518        // ```
1519        // becomes:
1520        // ```
1521        // +---+---+---+---+
1522        // |   | 1 | 3 | 2 |
1523        // +---+---+---+---+
1524        // ```
1525        sut.push_back(1);
1526        sut.push_back(1);
1527        sut.push_back(1);
1528        sut.push_back(2);
1529        sut.pop_front();
1530        sut.pop_front();
1531        sut.insert(1, 3);
1532        assert_eq!(sut.len(), 3);
1533        assert_eq!(sut[0], 1);
1534        assert_eq!(sut[1], 3);
1535        assert_eq!(sut[2], 2);
1536    }
1537
1538    #[test]
1539    fn test_cyclic_array_insert_4() {
1540        let mut sut = CyclicArray::<usize>::new(4);
1541        // start with:
1542        // ```
1543        // +---+---+---+---+
1544        // | 2 |   |   | 1 |
1545        // +---+---+---+---+
1546        // ```
1547        // becomes:
1548        // ```
1549        // +---+---+---+---+
1550        // | 2 |   | 3 | 1 |
1551        // +---+---+---+---+
1552        // ```
1553        sut.push_back(1);
1554        sut.push_back(1);
1555        sut.push_back(1);
1556        sut.push_back(1);
1557        sut.pop_front();
1558        sut.pop_front();
1559        sut.pop_front();
1560        sut.push_back(2);
1561        sut.insert(0, 3);
1562        assert_eq!(sut.len(), 3);
1563        assert_eq!(sut[0], 3);
1564        assert_eq!(sut[1], 1);
1565        assert_eq!(sut[2], 2);
1566    }
1567
1568    #[test]
1569    fn test_cyclic_array_insert_start() {
1570        let mut sut = CyclicArray::<usize>::new(4);
1571        // start with:
1572        // ```
1573        // +---+---+---+---+
1574        // | 1 | 2 |   |   |
1575        // +---+---+---+---+
1576        // ```
1577        // becomes:
1578        // ```
1579        // +---+---+---+---+
1580        // | 3 | 1 | 2 |   |
1581        // +---+---+---+---+
1582        // ```
1583        sut.push_back(1);
1584        sut.push_back(2);
1585        sut.insert(0, 3);
1586        assert_eq!(sut.len(), 3);
1587        assert_eq!(sut[0], 3);
1588        assert_eq!(sut[1], 1);
1589        assert_eq!(sut[2], 2);
1590    }
1591
1592    #[test]
1593    fn test_cyclic_array_insert_end() {
1594        let mut sut = CyclicArray::<usize>::new(4);
1595        // start with:
1596        // ```
1597        // +---+---+---+---+
1598        // | 1 | 2 |   |   |
1599        // +---+---+---+---+
1600        // ```
1601        // becomes:
1602        // ```
1603        // +---+---+---+---+
1604        // | 1 | 2 | 3 |   |
1605        // +---+---+---+---+
1606        // ```
1607        sut.push_back(1);
1608        sut.push_back(2);
1609        sut.insert(2, 3);
1610        assert_eq!(sut.len(), 3);
1611        assert_eq!(sut[0], 1);
1612        assert_eq!(sut[1], 2);
1613        assert_eq!(sut[2], 3);
1614    }
1615
1616    #[test]
1617    fn test_cyclic_array_insert_end_wrap() {
1618        let mut sut = CyclicArray::<usize>::new(4);
1619        // start with:
1620        // ```
1621        // +---+-V-+---+---+
1622        // |   | 2 | 3 | 4 |
1623        // +---+---+---+---+
1624        // ```
1625        // becomes:
1626        // ```
1627        // +---+-V-+---+---+
1628        // | 1 | 2 | 3 | 4 |
1629        // +---+---+---+---+
1630        // ```
1631        sut.push_back(1);
1632        sut.push_back(2);
1633        sut.push_back(3);
1634        sut.push_back(4);
1635        sut.pop_front();
1636        sut.insert(3, 1);
1637        assert_eq!(sut.len(), 4);
1638        assert_eq!(sut[0], 2);
1639        assert_eq!(sut[1], 3);
1640        assert_eq!(sut[2], 4);
1641        assert_eq!(sut[3], 1);
1642    }
1643
1644    #[test]
1645    #[should_panic(expected = "cyclic array is full")]
1646    fn test_cyclic_array_insert_full_panic() {
1647        let mut sut = CyclicArray::<usize>::new(1);
1648        sut.push_back(10);
1649        sut.insert(0, 20);
1650    }
1651
1652    #[test]
1653    #[should_panic(expected = "insertion index (is 2) should be <= len (is 0)")]
1654    fn test_cyclic_array_insert_bounds_panic() {
1655        let mut sut = CyclicArray::<usize>::new(1);
1656        sut.insert(2, 20);
1657    }
1658
1659    #[test]
1660    fn test_cyclic_array_remove_start() {
1661        let mut sut = CyclicArray::<usize>::new(4);
1662        // start with:
1663        // ```
1664        // +---+---+---+---+
1665        // | 1 | 2 | 3 |   |
1666        // +---+---+---+---+
1667        // ```
1668        // becomes:
1669        // ```
1670        // +---+---+---+---+
1671        // | 2 | 3 |   |   |
1672        // +---+---+---+---+
1673        // ```
1674        sut.push_back(1);
1675        sut.push_back(2);
1676        sut.push_back(3);
1677        sut.remove(0);
1678        assert_eq!(sut.len(), 2);
1679        assert_eq!(sut[0], 2);
1680        assert_eq!(sut[1], 3);
1681    }
1682
1683    #[test]
1684    fn test_cyclic_array_remove_1() {
1685        let mut sut = CyclicArray::<usize>::new(4);
1686        // start with:
1687        // ```
1688        // +---+---+---+---+
1689        // |   | 1 | 2 | 3 |
1690        // +---+---+---+---+
1691        // ```
1692        // becomes:
1693        // ```
1694        // +---+---+---+---+
1695        // |   |   | 1 | 3 |
1696        // +---+---+---+---+
1697        // ```
1698        sut.push_back(1);
1699        sut.push_back(1);
1700        sut.push_back(2);
1701        sut.push_back(3);
1702        sut.pop_front();
1703        sut.remove(1);
1704        assert_eq!(sut.len(), 2);
1705        assert_eq!(sut[0], 1);
1706        assert_eq!(sut[1], 3);
1707    }
1708
1709    #[test]
1710    fn test_cyclic_array_remove_2() {
1711        let mut sut = CyclicArray::<usize>::new(4);
1712        // start with:
1713        // ```
1714        // +---+---+---+---+
1715        // |   | 1 | 2 | 3 |
1716        // +---+---+---+---+
1717        // ```
1718        // becomes:
1719        // ```
1720        // +---+---+---+---+
1721        // |   |   | 2 | 3 |
1722        // +---+---+---+---+
1723        // ```
1724        sut.push_back(1);
1725        sut.push_back(1);
1726        sut.push_back(2);
1727        sut.push_back(3);
1728        sut.pop_front();
1729        sut.remove(0);
1730        assert_eq!(sut.len(), 2);
1731        assert_eq!(sut[0], 2);
1732        assert_eq!(sut[1], 3);
1733    }
1734
1735    #[test]
1736    fn test_cyclic_array_remove_3() {
1737        let mut sut = CyclicArray::<usize>::new(4);
1738        // start with:
1739        // ```
1740        // +---+---+---+---+
1741        // | 2 | 3 |   | 1 |
1742        // +---+---+---+---+
1743        // ```
1744        // becomes:
1745        // ```
1746        // +---+---+---+---+
1747        // | 3 |   |   | 1 |
1748        // +---+---+---+---+
1749        // ```
1750        sut.push_back(1);
1751        sut.push_back(1);
1752        sut.push_back(1);
1753        sut.push_back(1);
1754        sut.pop_front();
1755        sut.pop_front();
1756        sut.pop_front();
1757        sut.push_back(2);
1758        sut.push_back(3);
1759        sut.remove(1);
1760        assert_eq!(sut.len(), 2);
1761        assert_eq!(sut[0], 1);
1762        assert_eq!(sut[1], 3);
1763    }
1764
1765    #[test]
1766    fn test_cyclic_array_remove_start_full() {
1767        let mut sut = CyclicArray::<usize>::new(4);
1768        // start with:
1769        // ```
1770        // +---+---+---+---+
1771        // | 1 | 2 | 3 | 4 |
1772        // +---+---+---+---+
1773        // ```
1774        // becomes:
1775        // ```
1776        // +---+---+---+---+
1777        // | 2 | 3 | 4 |   |
1778        // +---+---+---+---+
1779        // ```
1780        sut.push_back(1);
1781        sut.push_back(2);
1782        sut.push_back(3);
1783        sut.push_back(4);
1784        sut.remove(0);
1785        assert_eq!(sut.len(), 3);
1786        assert_eq!(sut[0], 2);
1787        assert_eq!(sut[1], 3);
1788        assert_eq!(sut[2], 4);
1789    }
1790
1791    #[test]
1792    fn test_cyclic_array_remove_middle_full() {
1793        let mut sut = CyclicArray::<usize>::new(4);
1794        // start with:
1795        // ```
1796        // +---+---+---+---+
1797        // | 1 | 2 | 3 | 4 |
1798        // +---+---+---+---+
1799        // ```
1800        // becomes:
1801        // ```
1802        // +---+---+---+---+
1803        // | 1 | 2 | 4 |   |
1804        // +---+---+---+---+
1805        // ```
1806        sut.push_back(1);
1807        sut.push_back(2);
1808        sut.push_back(3);
1809        sut.push_back(4);
1810        sut.remove(2);
1811        assert_eq!(sut.len(), 3);
1812        assert_eq!(sut[0], 1);
1813        assert_eq!(sut[1], 2);
1814        assert_eq!(sut[2], 4);
1815    }
1816
1817    #[test]
1818    fn test_cyclic_array_remove_end() {
1819        let mut sut = CyclicArray::<usize>::new(4);
1820        // start with:
1821        // ```
1822        // +---+---+---+---+
1823        // | 1 | 2 | 3 |   |
1824        // +---+---+---+---+
1825        // ```
1826        // becomes:
1827        // ```
1828        // +---+---+---+---+
1829        // | 1 | 2 |   |   |
1830        // +---+---+---+---+
1831        // ```
1832        sut.push_back(1);
1833        sut.push_back(2);
1834        sut.push_back(3);
1835        sut.remove(2);
1836        assert_eq!(sut.len(), 2);
1837        assert_eq!(sut[0], 1);
1838        assert_eq!(sut[1], 2);
1839    }
1840
1841    #[test]
1842    fn test_cyclic_array_remove_end_full() {
1843        let mut sut = CyclicArray::<usize>::new(4);
1844        // start with:
1845        // ```
1846        // +---+---+---+---+
1847        // | 1 | 2 | 3 | 4 |
1848        // +---+---+---+---+
1849        // ```
1850        // becomes:
1851        // ```
1852        // +---+---+---+---+
1853        // | 1 | 2 | 3 |   |
1854        // +---+---+---+---+
1855        // ```
1856        sut.push_back(1);
1857        sut.push_back(2);
1858        sut.push_back(3);
1859        sut.push_back(4);
1860        sut.remove(3);
1861        assert_eq!(sut.len(), 3);
1862        assert_eq!(sut[0], 1);
1863        assert_eq!(sut[1], 2);
1864        assert_eq!(sut[2], 3);
1865    }
1866
1867    #[test]
1868    fn test_cyclic_array_remove_end_wrap() {
1869        let mut sut = CyclicArray::<usize>::new(4);
1870        // start with:
1871        // ```
1872        // +---+-V-+---+---+
1873        // | 5 | 2 | 3 | 4 |
1874        // +---+---+---+---+
1875        // ```
1876        // becomes:
1877        // ```
1878        // +---+-V-+---+---+
1879        // |   | 2 | 3 | 4 |
1880        // +---+---+---+---+
1881        // ```
1882        sut.push_back(1);
1883        sut.push_back(2);
1884        sut.push_back(3);
1885        sut.push_back(4);
1886        sut.pop_front();
1887        sut.push_back(5);
1888        assert_eq!(sut.len(), 4);
1889        assert_eq!(sut[0], 2);
1890        assert_eq!(sut[1], 3);
1891        assert_eq!(sut[2], 4);
1892        assert_eq!(sut[3], 5);
1893        sut.remove(3);
1894        assert_eq!(sut.len(), 3);
1895        assert_eq!(sut[0], 2);
1896        assert_eq!(sut[1], 3);
1897        assert_eq!(sut[2], 4);
1898    }
1899
1900    #[test]
1901    fn test_cyclic_array_push_pop_remove() {
1902        let mut sut = CyclicArray::<usize>::new(4);
1903        sut.push_back(7);
1904        sut.push_back(7);
1905        sut.push_back(7);
1906        sut.push_back(8);
1907        sut.pop_front();
1908        sut.pop_front();
1909        sut.push_back(10);
1910        sut.push_back(11);
1911        sut.remove(2);
1912        assert_eq!(sut.len(), 3);
1913        assert_eq!(sut[0], 7);
1914        assert_eq!(sut[1], 8);
1915        assert_eq!(sut[2], 11);
1916    }
1917
1918    #[test]
1919    fn test_cyclic_array_push_pop_insert() {
1920        let mut sut = CyclicArray::<usize>::new(4);
1921        sut.push_back(11);
1922        sut.push_back(11);
1923        sut.push_back(11);
1924        sut.push_back(12);
1925        sut.pop_front();
1926        sut.pop_front();
1927        sut.push_back(4);
1928        sut.insert(2, 3);
1929        assert_eq!(sut.len(), 4);
1930        assert_eq!(sut[0], 11);
1931        assert_eq!(sut[1], 12);
1932        assert_eq!(sut[2], 3);
1933        assert_eq!(sut[3], 4);
1934    }
1935
1936    #[test]
1937    #[should_panic(expected = "removal index (is 2) should be < len (is 0)")]
1938    fn test_cyclic_array_remove_bounds_panic() {
1939        let mut sut = CyclicArray::<usize>::new(1);
1940        sut.remove(2);
1941    }
1942
1943    #[test]
1944    fn test_cyclic_array_from_string() {
1945        let mut sut = CyclicArray::<String>::new(4);
1946        sut.push_back(ulid::Ulid::new().to_string());
1947        sut.push_back(ulid::Ulid::new().to_string());
1948        sut.push_back(ulid::Ulid::new().to_string());
1949        let copy = CyclicArray::<String>::from(8, sut);
1950        assert_eq!(copy.len(), 3);
1951        assert_eq!(copy.capacity(), 8);
1952        assert!(!copy[0].is_empty());
1953        assert!(!copy[1].is_empty());
1954        assert!(!copy[2].is_empty());
1955    }
1956
1957    #[test]
1958    fn test_cyclic_array_from_smaller_1() {
1959        let mut sut = CyclicArray::<usize>::new(4);
1960        sut.push_back(1);
1961        sut.push_back(2);
1962        sut.push_back(3);
1963        let copy = CyclicArray::<usize>::from(8, sut);
1964        assert_eq!(copy.len(), 3);
1965        assert_eq!(copy.capacity(), 8);
1966        assert_eq!(copy[0], 1);
1967        assert_eq!(copy[1], 2);
1968        assert_eq!(copy[2], 3);
1969    }
1970
1971    #[test]
1972    fn test_cyclic_array_from_smaller_2() {
1973        let mut sut = CyclicArray::<usize>::new(4);
1974        sut.push_back(1);
1975        sut.push_back(1);
1976        sut.push_back(1);
1977        sut.push_back(2);
1978        sut.pop_front();
1979        sut.pop_front();
1980        sut.push_back(3);
1981        sut.push_back(4);
1982        let copy = CyclicArray::<usize>::from(8, sut);
1983        assert_eq!(copy.len(), 4);
1984        assert_eq!(copy.capacity(), 8);
1985        assert_eq!(copy[0], 1);
1986        assert_eq!(copy[1], 2);
1987        assert_eq!(copy[2], 3);
1988        assert_eq!(copy[3], 4);
1989    }
1990
1991    #[test]
1992    fn test_cyclic_array_from_larger_1() {
1993        let mut sut = CyclicArray::<usize>::new(8);
1994        sut.push_back(1);
1995        sut.push_back(2);
1996        sut.push_back(3);
1997        let copy = CyclicArray::<usize>::from(4, sut);
1998        assert_eq!(copy.len(), 3);
1999        assert_eq!(copy.capacity(), 4);
2000        assert_eq!(copy[0], 1);
2001        assert_eq!(copy[1], 2);
2002        assert_eq!(copy[2], 3);
2003    }
2004
2005    #[test]
2006    fn test_cyclic_array_from_larger_2() {
2007        let mut sut = CyclicArray::<usize>::new(8);
2008        for _ in 0..7 {
2009            sut.push_back(1);
2010        }
2011        sut.push_back(2);
2012        for _ in 0..6 {
2013            sut.pop_front();
2014        }
2015        sut.push_back(3);
2016        let copy = CyclicArray::<usize>::from(4, sut);
2017        assert_eq!(copy.len(), 3);
2018        assert_eq!(copy.capacity(), 4);
2019        assert_eq!(copy[0], 1);
2020        assert_eq!(copy[1], 2);
2021        assert_eq!(copy[2], 3);
2022    }
2023
2024    #[test]
2025    fn test_cyclic_array_combine_string() {
2026        let mut a = CyclicArray::<String>::new(4);
2027        a.push_back(ulid::Ulid::new().to_string());
2028        a.push_back(ulid::Ulid::new().to_string());
2029        a.push_back(ulid::Ulid::new().to_string());
2030        let mut b = CyclicArray::<String>::new(4);
2031        b.push_back(ulid::Ulid::new().to_string());
2032        b.push_back(ulid::Ulid::new().to_string());
2033        b.push_back(ulid::Ulid::new().to_string());
2034        let sut = CyclicArray::combine(a, b);
2035        assert_eq!(sut.len(), 6);
2036        assert_eq!(sut.capacity(), 8);
2037        for i in 0..6 {
2038            assert!(!sut[i].is_empty());
2039        }
2040    }
2041
2042    #[test]
2043    fn test_cyclic_array_combine_1_1() {
2044        let mut a = CyclicArray::<usize>::new(4);
2045        a.push_back(1);
2046        a.push_back(2);
2047        a.push_back(3);
2048        let mut b = CyclicArray::<usize>::new(4);
2049        b.push_back(4);
2050        b.push_back(5);
2051        b.push_back(6);
2052        let sut = CyclicArray::combine(a, b);
2053        assert_eq!(sut.len(), 6);
2054        assert_eq!(sut.capacity(), 8);
2055        for i in 0..6 {
2056            assert_eq!(sut[i], i + 1);
2057        }
2058    }
2059
2060    #[test]
2061    fn test_cyclic_array_combine_1_2() {
2062        let mut a = CyclicArray::<usize>::new(4);
2063        a.push_back(1);
2064        a.push_back(2);
2065        a.push_back(3);
2066        let mut b = CyclicArray::<usize>::new(4);
2067        b.push_back(4);
2068        b.push_back(4);
2069        b.push_back(4);
2070        b.push_back(5);
2071        b.pop_front();
2072        b.pop_front();
2073        b.push_back(6);
2074        let sut = CyclicArray::combine(a, b);
2075        assert_eq!(sut.len(), 6);
2076        assert_eq!(sut.capacity(), 8);
2077        for i in 0..6 {
2078            assert_eq!(sut[i], i + 1);
2079        }
2080    }
2081
2082    #[test]
2083    fn test_cyclic_array_combine_2_1() {
2084        let mut a = CyclicArray::<usize>::new(4);
2085        a.push_back(1);
2086        a.push_back(1);
2087        a.push_back(1);
2088        a.push_back(2);
2089        a.pop_front();
2090        a.pop_front();
2091        a.push_back(3);
2092        let mut b = CyclicArray::<usize>::new(4);
2093        b.push_back(4);
2094        b.push_back(5);
2095        b.push_back(6);
2096        let sut = CyclicArray::combine(a, b);
2097        assert_eq!(sut.len(), 6);
2098        assert_eq!(sut.capacity(), 8);
2099        for i in 0..6 {
2100            assert_eq!(sut[i], i + 1);
2101        }
2102    }
2103
2104    #[test]
2105    fn test_cyclic_array_combine_2_2() {
2106        let mut a = CyclicArray::<usize>::new(4);
2107        a.push_back(1);
2108        a.push_back(1);
2109        a.push_back(1);
2110        a.push_back(2);
2111        a.pop_front();
2112        a.pop_front();
2113        a.push_back(3);
2114        let mut b = CyclicArray::<usize>::new(4);
2115        b.push_back(4);
2116        b.push_back(4);
2117        b.push_back(4);
2118        b.push_back(5);
2119        b.pop_front();
2120        b.pop_front();
2121        b.push_back(6);
2122        let sut = CyclicArray::combine(a, b);
2123        assert_eq!(sut.len(), 6);
2124        assert_eq!(sut.capacity(), 8);
2125        for i in 0..6 {
2126            assert_eq!(sut[i], i + 1);
2127        }
2128    }
2129
2130    #[test]
2131    fn test_cyclic_array_split_empty() {
2132        let big = CyclicArray::<usize>::new(8);
2133        let (a, b) = big.split();
2134        assert_eq!(a.len(), 0);
2135        assert_eq!(a.capacity(), 4);
2136        assert_eq!(b.len(), 0);
2137        assert_eq!(b.capacity(), 4);
2138    }
2139
2140    #[test]
2141    fn test_cyclic_array_split_string() {
2142        let mut big = CyclicArray::<String>::new(8);
2143        for _ in 0..8 {
2144            big.push_back(ulid::Ulid::new().to_string());
2145        }
2146        let (a, b) = big.split();
2147        assert_eq!(a.len(), 4);
2148        assert_eq!(a.capacity(), 4);
2149        assert!(!a[0].is_empty());
2150        assert!(!a[1].is_empty());
2151        assert!(!a[2].is_empty());
2152        assert!(!a[3].is_empty());
2153        assert_eq!(b.len(), 4);
2154        assert_eq!(b.capacity(), 4);
2155        assert!(!b[0].is_empty());
2156        assert!(!b[1].is_empty());
2157        assert!(!b[2].is_empty());
2158        assert!(!b[3].is_empty());
2159    }
2160
2161    #[test]
2162    fn test_cyclic_array_split_full() {
2163        let mut big = CyclicArray::<usize>::new(8);
2164        for value in 1..=8 {
2165            big.push_back(value);
2166        }
2167        let (a, b) = big.split();
2168        assert_eq!(a.len(), 4);
2169        assert_eq!(a.capacity(), 4);
2170        assert_eq!(a[0], 1);
2171        assert_eq!(a[1], 2);
2172        assert_eq!(a[2], 3);
2173        assert_eq!(a[3], 4);
2174        assert_eq!(b.len(), 4);
2175        assert_eq!(b.capacity(), 4);
2176        assert_eq!(b[0], 5);
2177        assert_eq!(b[1], 6);
2178        assert_eq!(b[2], 7);
2179        assert_eq!(b[3], 8);
2180    }
2181
2182    #[test]
2183    fn test_cyclic_array_split_partial_whole() {
2184        let mut big = CyclicArray::<usize>::new(8);
2185        for value in 1..=6 {
2186            big.push_back(value);
2187        }
2188        let (a, b) = big.split();
2189        assert_eq!(a.len(), 4);
2190        assert_eq!(a.capacity(), 4);
2191        assert_eq!(a[0], 1);
2192        assert_eq!(a[1], 2);
2193        assert_eq!(a[2], 3);
2194        assert_eq!(a[3], 4);
2195        assert_eq!(b.len(), 2);
2196        assert_eq!(b.capacity(), 4);
2197        assert_eq!(b[0], 5);
2198        assert_eq!(b[1], 6);
2199    }
2200
2201    #[test]
2202    fn test_cyclic_array_split_partial_split() {
2203        let mut big = CyclicArray::<usize>::new(8);
2204        for value in 1..=6 {
2205            big.push_back(value);
2206        }
2207        big.pop_front();
2208        big.pop_front();
2209        big.pop_front();
2210        big.push_back(7);
2211        big.push_back(8);
2212        big.push_back(9);
2213        let (a, b) = big.split();
2214        assert_eq!(a.len(), 4);
2215        assert_eq!(a.capacity(), 4);
2216        assert_eq!(a[0], 4);
2217        assert_eq!(a[1], 5);
2218        assert_eq!(a[2], 6);
2219        assert_eq!(a[3], 7);
2220        assert_eq!(b.len(), 2);
2221        assert_eq!(b.capacity(), 4);
2222        assert_eq!(b[0], 8);
2223        assert_eq!(b[1], 9);
2224    }
2225
2226    #[test]
2227    fn test_cyclic_array_get_mut() {
2228        let mut sut = CyclicArray::<usize>::new(4);
2229        sut.push_back(1);
2230        sut.push_back(2);
2231        sut.push_back(3);
2232        sut.push_back(4);
2233        if let Some(value) = sut.get_mut(1) {
2234            *value = 12;
2235        } else {
2236            panic!("get_mut() returned None")
2237        }
2238        sut[2] = 13;
2239        assert_eq!(sut[0], 1);
2240        assert_eq!(sut[1], 12);
2241        assert_eq!(sut[2], 13);
2242        assert_eq!(sut[3], 4);
2243    }
2244
2245    #[test]
2246    fn test_zero_sized_type() {
2247        // A zero-sized type must not allocate; exercise enough operations to
2248        // drive the expand/combine and compress/split/from paths.
2249        let mut sut: Vector<()> = Vector::new();
2250        assert!(sut.is_empty());
2251        for _ in 0..1000 {
2252            sut.push(());
2253        }
2254        assert_eq!(sut.len(), 1000);
2255        assert_eq!(sut.get(500), Some(&()));
2256        // insert and remove in the middle to shuffle elements across deques
2257        sut.insert(250, ());
2258        assert_eq!(sut.len(), 1001);
2259        for _ in 0..900 {
2260            assert_eq!(sut.remove(0), ());
2261        }
2262        assert_eq!(sut.len(), 101);
2263        while sut.pop().is_some() {}
2264        assert!(sut.is_empty());
2265    }
2266
2267    #[test]
2268    fn test_zero_sized_cyclic_array() {
2269        let mut sut: CyclicArray<()> = CyclicArray::new(4);
2270        sut.push_back(());
2271        sut.push_front(());
2272        assert_eq!(sut.len(), 2);
2273        assert_eq!(sut.pop_back(), Some(()));
2274        assert_eq!(sut.pop_front(), Some(()));
2275        assert!(sut.is_empty());
2276    }
2277
2278    #[test]
2279    fn test_vector_is_send_and_sync() {
2280        // Compile-time assertion: a Vector over a Send+Sync element must itself
2281        // be Send and Sync, matching std::vec::Vec.
2282        fn assert_send_sync<T: Send + Sync>() {}
2283        assert_send_sync::<Vector<usize>>();
2284        assert_send_sync::<CyclicArray<usize>>();
2285    }
2286
2287    #[test]
2288    #[should_panic(expected = "removal index (is 4) should be < len (is 4)")]
2289    fn test_vector_remove_index_equals_len_panics() {
2290        let mut sut: Vector<usize> = (0..4).collect();
2291        sut.remove(4);
2292    }
2293}