max_size_vec/
lib.rs

1//! This crate contains a vector type that has its own self-contained and stack-based allocation system.
2//! This type of vector is called a max-sized vector, and reserves a fixed amount of space at its creation.
3//! Once created, there are no elements, but the amount of elements can increase until the buffer is full.
4//! When the buffer is full, and another element is attempted to be added, a panic happens describing the error.
5//! This vector has the vast majority of vector methods and traits that aren't allocation specfic (e.g. reserve isn't a method).
6//! This crate has no dependencies other than core, and is therefore standalone and suitable for use without the standard
7//! library.
8//!
9//! Example:
10//!
11//! ```rust
12//! use max_size_vec::MaxSizeVec;
13//! fn main() {
14//!     let mut x: MaxSizeVec<usize, 1024> = MaxSizeVec::new();
15//!     x.push(0usize);
16//!     x.swap_remove(0usize);
17//!     x.extend(5..10usize);
18//!     x.pop();
19//!     x.retain(|x| *x > 6);
20//!     x.drain(0..1);
21//!     x.drain(..1);
22//!     x.push(2);
23//!     x.insert(1usize, 1usize);
24//!     x.insert(0usize, 1usize);
25//!     x.remove(0usize);
26//!     assert_eq!(x, &[2, 1]);
27//! }
28//! ```
29#![no_std]
30#![deny(missing_docs)]
31#![feature(min_const_generics)]
32
33/// This type of vector is called a max-sized vector, and reserves a fixed amount of space at its creation.
34/// Once created, there are no elements, but the amount of elements can increase until the buffer is full.
35/// When the buffer is full, and another element is attempted to be added, a panic happens describing the error.
36/// This vector has the vast majority of vector methods and traits that aren't allocation specfic (e.g. reserve isn't a method).
37pub struct MaxSizeVec<T, const SIZE: usize> {
38    data: [core::mem::ManuallyDrop<T>; SIZE],
39    length: usize
40}
41
42/// An iterator used for the iterator method of a max-sized iterator.
43pub struct MaxSizeVecIter<T, const SIZE: usize> {
44    data: [core::mem::ManuallyDrop<T>; SIZE],
45    length: usize,
46    offset: usize
47}
48
49impl<T, const SIZE: usize> core::iter::Iterator for MaxSizeVecIter<T, {SIZE}> {
50    type Item = T;
51    fn next(&mut self) -> Option<T> {
52        if self.offset >= self.length {
53            None
54        } else {
55            self.offset += 1;
56            // The bounds checks above made sure that this is valid.
57            Some(unsafe { 
58                core::ptr::read((self.data.as_ptr() as *const T).offset_unsigned(self.offset - 1))
59            })
60        }
61    }
62}
63
64/// Used for draining elements out of a max-sized vector.
65pub struct Drain<'a, T, const SIZE: usize> {
66    vector: &'a mut MaxSizeVec<T, {SIZE}>,
67    original_start: usize,
68    start: usize,
69    end: usize
70}
71
72impl<'a, T, const SIZE: usize> core::iter::Iterator for Drain<'a, T, {SIZE}> {
73    type Item = T;
74    fn next(&mut self) -> Option<T> {
75        if self.start >= self.end {
76            None
77        } else {
78            self.start += 1;
79            // Safe, as exclusive access is given once and only once to the user of the next method. Since everything in the vector is manually dropped, and this gives exclusive 
80            // access to the element once, it is guaranteed that this will be dropped once after being used, and therefore should be skipped for dropping when the drain itself is 
81            // dropped. That's why only the elements not accessed yet are dropped when the drain is dropped.
82            Some(unsafe {
83                core::ptr::read(self.vector.as_ptr().offset(self.start as isize - 1))
84            })
85        }
86    }
87}
88
89impl<'a, T, const SIZE: usize> core::ops::Drop for Drain<'a, T, {SIZE}> {
90    fn drop(&mut self) {
91        let amount_to_remove = self.end - self.original_start;
92        unsafe {
93            // None of these were accessed or dropped yet, so this is safe.
94            for x in self.start..self.end {
95                core::ptr::drop_in_place(
96                    self.vector.as_mut_ptr().offset_unsigned(x)
97                );
98            }
99            // Copy the region after the drain to the start. The regions after both pointers overlap, so a copy_nonoverlapping call here 
100            // would be invalid.
101            //
102            // By doing this and subtracting from the vector's length, it looks like a bunch of elements were removed. This is safe, as
103            // the memory regions and pointers are all valid.
104            core::ptr::copy(
105                self.vector.as_ptr().offset_unsigned(self.end),
106                self.vector.as_mut_ptr().offset_unsigned(self.original_start),
107                self.vector.length - self.end
108            );
109        }
110        self.vector.length -= amount_to_remove;
111    }
112}
113
114trait OffsetUnsigned {
115    unsafe fn offset_unsigned(&self, offset: usize) -> Self;
116}
117
118impl<T> OffsetUnsigned for *const T {
119    unsafe fn offset_unsigned(&self, offset: usize) -> *const T {
120        self.offset(offset as isize)
121    }
122}
123
124impl<T> OffsetUnsigned for *mut T {
125    unsafe fn offset_unsigned(&self, offset: usize) -> *mut T {
126        self.offset(offset as isize)
127    }
128}
129
130impl<T, const SIZE: usize> Drop for MaxSizeVec<T, {SIZE}> {
131    fn drop(&mut self) {
132        // Since everything in this vector is manually dropped, everything that wasn't dropped is dropped here.
133        for x in 0..self.length {
134            unsafe {
135                core::mem::ManuallyDrop::drop(&mut self.data[x]);
136            }
137        }
138    }
139}
140
141impl<T: Clone, const SIZE: usize> Clone for MaxSizeVec<T, {SIZE}> {
142    fn clone(&self) -> MaxSizeVec<T, {SIZE}> {
143        MaxSizeVec {
144            data: self.data.clone(),
145            length: self.length
146        }
147    }
148}
149
150impl<T: PartialEq, const SIZE: usize> PartialEq<&[T]> for MaxSizeVec<T, {SIZE}> {
151    fn eq(&self, other: &&[T]) -> bool {
152        self.as_slice() == *other
153    }
154}
155
156impl<T: PartialEq, const SIZE: usize, const OTHER: usize> PartialEq<MaxSizeVec<T, {OTHER}>> for MaxSizeVec<T, {SIZE}> {
157    fn eq(&self, other: &MaxSizeVec<T, {OTHER}>) -> bool {
158        self.as_slice() == other.as_slice()
159    }
160}
161
162impl<T: PartialEq, const SIZE: usize, const OTHER: usize> PartialEq<[T; {OTHER}]> for MaxSizeVec<T, {SIZE}> {
163    fn eq(&self, other: &[T; {OTHER}]) -> bool {
164        self.as_slice() == other
165    }
166}
167
168impl<T: PartialEq, const SIZE: usize, const OTHER: usize> PartialEq<&[T; {OTHER}]> for MaxSizeVec<T, {SIZE}> {
169    fn eq(&self, other: &&[T; {OTHER}]) -> bool {
170        self.as_slice() == *other
171    }
172}
173
174impl<T: core::fmt::Debug, const SIZE: usize> core::fmt::Debug for MaxSizeVec<T, {SIZE}> {
175    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
176        // This gets the vector in the data array up its length, and transmutes it to make format correctly.
177        unsafe {
178            core::mem::transmute::<&[core::mem::ManuallyDrop<T>], &[T]>(&self.data[..self.length])
179        }.fmt(fmt)
180    }
181}
182
183impl<T, const SIZE: usize> MaxSizeVec<T, {SIZE}> {
184    /// Creates a new, empty max-size vector.
185    pub fn new() -> MaxSizeVec<T, {SIZE}> {
186        // The zeroed memory here is never directly used until correct initialization. 
187        MaxSizeVec {
188            data: unsafe {
189                core::mem::MaybeUninit::zeroed().assume_init()
190            },
191            length: 0usize
192        }
193    }
194    
195    /// Pushes an element to the max-size vector.
196    pub fn push(&mut self, val: T) {
197        if self.length == self.data.len() {
198            panic!("Attempt to push when there's no room left in a max size vector!");
199        }
200        self.data[self.length] = core::mem::ManuallyDrop::new(val);
201        self.length += 1;
202    }
203    
204    /// Pops off an element from the max-size vector.
205    pub fn pop(&mut self) {
206        if self.length == 0 {
207            panic!("Attempt to pop a max-size vector with underflow!");
208        }
209        // Drop the last element and subtract from the length.
210        unsafe {
211            core::mem::ManuallyDrop::drop(&mut self.data[self.length - 1]);
212        }
213        self.length -= 1;
214    }
215
216    /// Gets the length of the max-size vector.
217    pub fn len(&self) -> usize {
218        self.length
219    }
220
221    /// Drains elements from the vector based on a range.
222    pub fn drain<'a, R: core::ops::RangeBounds<usize>>(&'a mut self, range: R) -> Drain<'a, T, {SIZE}> {
223        use core::ops::Bound;
224        let start = match range.start_bound() {
225            Bound::Unbounded => 0usize,
226            Bound::Included(x) => {
227                let x = *x;
228                if x >= self.len() { 
229                    panic!("Range out of bounds!")
230                } else { 
231                    x
232                }
233            },
234            _ => unreachable!()
235        };
236
237        let end = match range.end_bound() {
238            Bound::Unbounded => self.len(),
239            Bound::Included(x) => if *x + 1 > self.len() { 
240                panic!("Range out of bounds!") 
241            } else {
242                *x + 1
243            },
244            Bound::Excluded(x) => {
245                let x = *x;
246                if x > self.len() { 
247                    panic!("Range out of bounds!")
248                } else { 
249                    x
250                }
251            },
252        };
253
254        Drain {
255            start,
256            end,
257            vector: self,
258            original_start: start
259        }
260    }
261
262    /// Appends a max-size vector onto this one, making the other one empty.
263    pub fn append<const OTHER_SIZE: usize>(&mut self, other: &mut MaxSizeVec<T, {OTHER_SIZE}>) {
264        // This bounds check makes the following unsafe code safe.
265        if self.length + other.length > self.data.len() {
266            panic!("Attempt to append beyond the bounds of a max-size vector!");
267        }
268        // Both of these are valid nonoverlapping pointers in valid memory regions that don't overlap.
269        // This copies the other vector's elements to the end of the current vector.
270        unsafe {
271            core::ptr::copy_nonoverlapping(
272                other.as_ptr(), 
273                self.as_mut_ptr().offset_unsigned(self.length), 
274                other.len()
275            )
276        }
277        // Increase the length to include the new elements.
278        self.length += other.len();
279        // Clear the other vector.
280        *other = MaxSizeVec::new();
281    }
282
283    /// Gets a mutable pointer to the base of this vector.
284    pub fn as_mut_ptr(&mut self) -> *mut T {
285        self.data.as_mut_ptr() as *mut T
286    }
287
288    /// Gets a mutable slice that can be used to edit or read the elements of this vector.
289    pub fn as_mut_slice(&mut self) -> &mut [T] {
290        // This transmutes the slice of the vector's elements to make it drop accordingly when used.
291        unsafe {
292            core::mem::transmute::<&mut [core::mem::ManuallyDrop<T>], &mut [T]>(&mut self.data[..self.length])
293        }
294    }
295
296    /// This gets a pointer to the base of this vector.
297    pub fn as_ptr(&self) -> *const T {
298        self.data.as_ptr() as *const T
299    }
300
301    /// Gets an immutable slice that can be used to read the elements of this vector
302    pub fn as_slice(&self) -> &[T] {
303        // This transmutes the slice of the vector's elements to make it drop accordingly when used.
304        unsafe {
305            core::mem::transmute::<&[core::mem::ManuallyDrop<T>], &[T]>(&self.data[..self.length])
306        }
307    }
308
309    /// The capacity of this vector, i.e. the maximum number of elements that it can hold.
310    pub fn capacity(&self) -> usize {
311        self.data.len()
312    }
313
314    /// This clears the vector.
315    pub fn clear(&mut self) {
316        *self = MaxSizeVec::new();
317    }
318
319    /// This inserts an element at an index in the vector,
320    pub fn insert(&mut self, index: usize, element: T) {
321        // These bounds checks make the unsafe code in this function valid.
322        if self.length + 1 >= self.data.len() {
323            panic!("Attempt to insert into a max-sized vector with overflow!");
324        }
325        if index > self.length {
326            panic!("Index out of bounds during insertion into max-sized vector!");
327        }
328        if index == self.length {
329            self.push(element);
330        } else {
331            unsafe {
332                // Make room for the extra element
333                self.length += 1;
334                // Copy elements at the index of insertion to the index after it.
335                core::ptr::copy(
336                    self.as_ptr().offset_unsigned(index), 
337                    self.as_mut_ptr().offset_unsigned(index + 1), 
338                    self.length - index
339                );
340                // Overwrite the index of insertion with the inserted element.
341                *self.as_mut_ptr().offset_unsigned(index) = element;
342            }
343        }
344    }
345
346    /// This truncates a vector to a certain length.
347    pub fn truncate(&mut self, size: usize) {
348        if size > self.length {
349            panic!("Attempt to truncate a max-sized vector to larger length!");
350        }
351        if size != self.length {
352            for x in 0..self.length - size - 1 {
353                // This makes sure that all elements lost are dropped before being made inaccessible.
354                unsafe {
355                    let ptr: *mut core::mem::ManuallyDrop<T> = self.data.as_mut_ptr().offset_unsigned(
356                        self.length - x
357                    );
358                    core::mem::ManuallyDrop::drop(core::mem::transmute::<_, &mut core::mem::ManuallyDrop<T>>(ptr))
359                }
360            }
361            self.length = size;
362        }
363    }
364
365    /// This resizes a vector with one condition: if the size is larger than the vectors size, a closure passed will be called
366    /// to fill in the missing parts.
367    pub fn resize_with(&mut self, size: usize, mut f: impl FnMut() -> T) {
368        if size >= self.data.len() {
369            panic!("The size passed to the resize function of a max-sized vector was larger than the vector's bounds!");
370        }
371        if size >= self.length {
372            for _ in 0..size - self.length {
373                self.push(f());
374            }
375        } else {
376            self.truncate(size);
377        }
378    }
379
380    /// This removes all elements that don't fit a predicate, leaving the ones that fit it.
381    pub fn retain(&mut self, mut predicate: impl FnMut(&T) -> bool) {
382        let mut current_length = 0usize;
383        // This copies the predicate elements to the start of the array in order.
384        for x in 0..self.length {
385            if predicate(&self[x]) {
386                // This is safe because both of these indices are valid and will never exceed the length. The memory region also only covers the indexes.
387                unsafe {
388                    core::ptr::copy(self.as_ptr().offset_unsigned(x), self.as_mut_ptr().offset_unsigned(current_length), 1usize)
389                };
390                current_length += 1;
391            } else {
392                // Everything that will be discarded should be dropped.
393                unsafe {
394                    core::ptr::drop_in_place(self.as_mut_ptr().offset_unsigned(x))
395                }
396            }
397        }
398        // Change the length accordingly to prevent invalid accesses.
399        self.length = current_length;
400    }
401
402    /// This removes an element from a vector at a certain index, while preserving order.
403    pub fn remove(&mut self, index: usize) {
404        if index >= self.length {
405            panic!("Index for removal out of bounds for max-sized vector!");
406        }
407        unsafe {
408            // The element being removed should be dropped.
409            core::ptr::drop_in_place(self.as_mut_ptr().offset_unsigned(index));
410        }
411        if index != self.length - 1 {
412            unsafe {
413                // The elements after it should be shifted back by one index.
414                core::ptr::copy(
415                    self.as_ptr().offset_unsigned(index + 1),
416                    self.as_mut_ptr().offset_unsigned(index),
417                    self.length - index - 1
418                );
419            }
420        }
421        // This is needed regardless if the index is the last one to make sure invalid memory
422        // isn't accessible.
423        self.length -= 1;
424    }
425
426    /// This swaps an element at an index with the last element and pops the vector, which messes up order,
427    /// but successfully removes an element from the vector.
428    pub fn swap_remove(&mut self, index: usize) {
429        if index >= self.length {
430            panic!("Index out of bounds for swap remove operation on max-sized vector!");
431        }
432        if index == self.length - 1 {
433            self.pop();
434        } else {
435            // This swaps the memory of valid indices, and so is safe.
436            unsafe {
437                core::ptr::swap_nonoverlapping(
438                    self.as_mut_ptr().offset_unsigned(index), self.as_mut_ptr().offset_unsigned(self.length - 1), 1usize
439                );
440            }
441            self.pop();
442        }
443    }
444
445    /// This checks to see whether or not the vector is empty.
446    pub fn is_empty(&self) -> bool {
447        self.length == 0
448    }
449}
450
451impl<T, const SIZE: usize> core::ops::Deref for MaxSizeVec<T, {SIZE}> {
452    type Target = [T];
453    fn deref(&self) -> &Self::Target {
454        self.as_slice()
455    }
456}
457
458impl<T, const SIZE: usize> core::ops::DerefMut for MaxSizeVec<T, {SIZE}> {
459    fn deref_mut(&mut self) -> &mut [T] {
460        self.as_mut_slice()
461    }
462}
463
464impl<T: Clone, const SIZE: usize> MaxSizeVec<T, {SIZE}> {
465    /// This resizes a vector with a value to fill in missing parts if the size is larger than the current size.
466    pub fn resize(&mut self, size: usize, value: T) {
467        if size >= self.data.len() {
468            panic!("The size passed to the resize function of a max-sized vector was larger than the vector's bounds!");
469        }
470        if size >= self.length {
471            for _ in 0..size - self.length {
472                self.push(value.clone());
473            }
474        } else {
475            self.truncate(size);
476        }
477    }
478
479    /// This extends a vector from a slice.
480    pub fn extend_from_slice(&mut self, other: &[T]) {
481        if self.len() + other.len() >= self.data.len() {
482            panic!("Attempt to extend by a slice beyond the bounds of a max-sized vector!");
483        }
484        for (n, x) in other.iter().cloned().enumerate() {
485            // Bounds checks are done above. This is not a premature optimization. The compiler failed to remove the bounds checks with a regular indexing,
486            // and so I manually implemented them and put it outside of the loop.
487            unsafe {
488                *self.data.as_mut_ptr().offset_unsigned(self.length + n) = core::mem::ManuallyDrop::new(x);
489            }
490        }
491    }
492}
493
494impl<T, const SIZE: usize> core::iter::Extend<T> for MaxSizeVec<T, {SIZE}> {
495    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
496        let mut iter = iter.into_iter();
497        let mut x = iter.next();
498        while x.is_some() {
499            if self.length >= self.data.len() {
500                panic!("Attempt to extend beyond the bounds of a max-sized vector!");
501            }
502            self.data[self.length] = core::mem::ManuallyDrop::new(x.unwrap());
503            self.length += 1;
504            x = iter.next();
505        }
506    }
507}
508
509impl<'a, T: 'a + Copy, const SIZE: usize> core::iter::Extend<&'a T> for MaxSizeVec<T, {SIZE}> {
510    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
511        let mut iter = iter.into_iter();
512        let mut x = iter.next();
513        while x.is_some() {
514            if self.length >= self.data.len() {
515                panic!("Attempt to extend beyond the bounds of a max-sized vector!");
516            }
517            self.data[self.length] = core::mem::ManuallyDrop::new(x.unwrap().clone());
518            self.length += 1;
519            x = iter.next();
520        }
521    }
522}
523
524impl<T, const SIZE: usize> core::ops::Index<usize> for MaxSizeVec<T, {SIZE}> {
525    type Output = T;
526    fn index(&self, index: usize) -> &T {
527        if index >= self.length {
528            panic!("Index {} out of bounds of fixed size vec!", index);
529        }
530        // When an index is accessed, the data at this index should be droppable and not wrapped in the ManuallyDrop
531        // structure.
532        unsafe {
533            core::mem::transmute(self.data.index(index))
534        }
535    }
536}
537
538impl<T, const SIZE: usize> core::ops::IndexMut<usize> for MaxSizeVec<T, {SIZE}> {
539    fn index_mut(&mut self, index: usize) -> &mut T {
540        if index >= self.length {
541            panic!("Index {} out of bounds of fixed size vec!", index);
542        }
543        // When an index is accessed, the data at this index should be droppable and not wrapped in the ManuallyDrop
544        // structure.
545        unsafe {
546            core::mem::transmute(self.data.index_mut(index))
547        }
548    }
549}
550
551impl<T, const SIZE: usize> core::convert::AsMut<[T]> for MaxSizeVec<T, {SIZE}> {
552    fn as_mut(&mut self) -> &mut [T] {
553        self.as_mut_slice()
554    }
555}
556
557impl<T, const SIZE: usize> core::convert::AsMut<MaxSizeVec<T, {SIZE}>> for MaxSizeVec<T, {SIZE}> {
558    fn as_mut(&mut self) -> &mut Self {
559        self
560    }
561}
562
563impl<T, const SIZE: usize> core::convert::AsRef<[T]> for MaxSizeVec<T, {SIZE}> {
564    fn as_ref(&self) -> &[T] {
565        self.as_slice()
566    }
567}
568
569impl<T, const SIZE: usize> core::convert::AsRef<MaxSizeVec<T, {SIZE}>> for MaxSizeVec<T, {SIZE}> {
570    fn as_ref(&self) -> &Self {
571        self
572    }
573}
574
575impl<T, const SIZE: usize> core::borrow::Borrow<[T]> for MaxSizeVec<T, {SIZE}> {
576    fn borrow(&self) -> &[T] {
577        self.as_slice()
578    }
579}
580
581impl<T, const SIZE: usize> core::borrow::BorrowMut<[T]> for MaxSizeVec<T, {SIZE}> {
582    fn borrow_mut(&mut self) -> &mut [T] {
583        self.as_mut_slice()
584    }
585}
586
587impl<T: Eq, const SIZE: usize> Eq for MaxSizeVec<T, {SIZE}> {}
588
589impl<'a, T: Clone, const SIZE: usize> From<&'a [T]> for MaxSizeVec<T, {SIZE}> {
590    fn from(x: &[T]) -> Self {
591        let mut v = MaxSizeVec::new();
592        v.extend(x.iter().cloned());
593        v
594    }
595}
596
597impl<'a, T: Clone, const SIZE: usize> From<&'a mut [T]> for MaxSizeVec<T, {SIZE}> {
598    fn from(x: &mut [T]) -> Self {
599        let mut v = MaxSizeVec::new();
600        v.extend(x.iter().cloned());
601        v
602    }
603}
604
605impl<'a, const SIZE: usize> From<&'a str> for MaxSizeVec<u8, {SIZE}> {
606    fn from(x: &str) -> Self {
607        let mut v = MaxSizeVec::new();
608        v.extend(x.as_bytes().iter().cloned());
609        v
610    }
611}
612
613impl<T, const SIZE: usize> core::iter::FromIterator<T> for MaxSizeVec<T, {SIZE}> {
614    fn from_iter<I: IntoIterator<Item = T>>(x: I) -> Self {
615        let mut v = MaxSizeVec::new();
616        v.extend(x);
617        v
618    }
619}
620
621impl<T, const SIZE: usize> core::iter::IntoIterator for MaxSizeVec<T, {SIZE}> {
622    type Item = T;
623    type IntoIter = MaxSizeVecIter<T, {SIZE}>;
624    fn into_iter(self) -> MaxSizeVecIter<T, {SIZE}> {
625        // Transmute copy is used here rather than a regular transmute because the compiler
626        // couldn't tell that [T; SIZE] has the same size as [ManuallyDrop<T>; SIZE]. The 
627        // transmute is needed to make the data droppable after usage.
628        MaxSizeVecIter {
629            offset: 0usize,
630            length: self.length,
631            data: unsafe {
632                core::mem::transmute_copy(&self.data)
633            }
634        }
635    }
636}
637
638impl<'a, T, const SIZE: usize> core::iter::IntoIterator for &'a MaxSizeVec<T, {SIZE}> {
639    type Item = &'a T;
640    type IntoIter = core::slice::Iter<'a, T>;
641    fn into_iter(self) -> core::slice::Iter<'a, T> {
642        self.iter()
643    }
644}
645
646impl<T: PartialOrd, const SIZE: usize> PartialOrd for MaxSizeVec<T, {SIZE}> {
647    fn partial_cmp(&self, other: &MaxSizeVec<T, {SIZE}>) -> Option<core::cmp::Ordering> {
648        PartialOrd::partial_cmp(self.as_slice(), other.as_slice())
649    }
650}
651
652impl<T: Ord, const SIZE: usize> Ord for MaxSizeVec<T, {SIZE}> {
653    fn cmp(&self, other: &MaxSizeVec<T, {SIZE}>) -> core::cmp::Ordering {
654        Ord::cmp(self.as_slice(), other.as_slice())
655    }
656}
657
658#[test]
659fn dropping_order() {
660    use core::sync::atomic::*;
661    
662    #[derive(Clone, Debug)]
663    struct DropTest;
664
665    static DROP_COUNT: AtomicUsize = AtomicUsize::new(0usize);
666    impl Drop for DropTest {
667        fn drop(&mut self) {
668            DROP_COUNT.fetch_add(1usize, Ordering::SeqCst);
669        }
670    }
671    
672    let mut x: MaxSizeVec<DropTest, 1024> = MaxSizeVec::new();
673    x.extend((1..=1024).map(|_| DropTest));
674    x.resize(512, DropTest);
675    x.swap_remove(0usize);
676    x.pop();
677
678    let mut collection: MaxSizeVec<DropTest, 1024> = MaxSizeVec::new();
679    for v in x.drain(..) {
680        collection.push(v);
681    }
682    x.append(&mut collection);
683    x.drain(..);
684    
685    assert_eq!(x.len(), 0);
686    assert_eq!(DROP_COUNT.load(Ordering::SeqCst), 1534);
687}
688
689#[test]
690fn operational_correctness() {
691    let mut x: MaxSizeVec<usize, 1024> = MaxSizeVec::new();
692
693    x.push(0usize);
694    x.swap_remove(0usize);
695    x.extend(5..10usize);
696    x.pop();
697    x.retain(|x| *x > 6);
698    x.drain(0..1);
699    x.drain(..1);
700    x.push(2);
701    x.insert(1usize, 1usize);
702    x.insert(0usize, 1usize);
703    x.remove(0usize);
704
705    assert_eq!(x, &[2, 1]);
706}