copyvec/lib.rs
1//! A stack-allocated sequence that mirror's [`Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html)'s API,
2//! but:
3//! - Implements [`Copy`] (and can only hold [`Copy`] types).
4//! - Does not grow.
5//! - Is `#[no_std]`/no-`alloc` compatible.
6//!
7//! ```
8//! # use copyvec::{CopyVec, copyvec};
9//!
10//! // const-friendly
11//! const VEC: CopyVec<&str, 10> = CopyVec::new();
12//!
13//! // easy initialising
14//! let mut vec = copyvec!["a", "b", "c"; + 2];
15//! // ^~ with excess capacity
16//!
17//! // use the API's you know
18//! vec.push("d");
19//!
20//! // including iteration
21//! for it in &mut vec {
22//! if *it == "a" {
23//! *it = "A"
24//! }
25//! }
26//!
27//! assert_eq!(vec, ["A", "b", "c", "d"]);
28//! vec.retain(|it| *it == "b" || *it == "c");
29//! assert_eq!(vec.remove(0), "b");
30//! ```
31//!
32//! # Other features
33//! - [`serde`](https://docs.rs/serde/)
34//! - [`quickcheck`](https://docs.rs/quickcheck/)
35//!
36//!
37//! If you like this crate, you may also enjoy [`stackstack`](https://docs.rs/stackstack)
38
39#![cfg_attr(not(feature = "std"), no_std)]
40
41#[cfg(feature = "alloc")]
42extern crate alloc;
43#[cfg(feature = "alloc")]
44use alloc::{borrow::Cow, boxed::Box};
45
46#[cfg(all(feature = "quickcheck1", feature = "alloc"))]
47mod _quickcheck1;
48#[cfg(feature = "serde1")]
49mod _serde1;
50
51use core::{
52 array,
53 borrow::{Borrow, BorrowMut},
54 cmp::Ordering,
55 fmt,
56 hash::Hash,
57 iter::{self, FusedIterator, Take},
58 mem::{self, MaybeUninit},
59 ops::{Deref, DerefMut, Index, IndexMut},
60 ptr,
61 slice::{self, SliceIndex},
62};
63
64#[cfg(feature = "std")]
65use std::io;
66
67/// Create a [`CopyVec`] filled with the given arguments.
68///
69/// The syntax is similar to [`vec!`](std::vec!)'s,
70/// but additional capacity may be specified with `+ <extra>`.
71///
72/// ```
73/// # use copyvec::copyvec;
74/// let mut exact = copyvec!["a", "b", "c"];
75/// assert_eq!(exact.capacity(), 3);
76///
77/// let with_spare = copyvec!["a", "b", "c"; + 5];
78/// assert_eq!(with_spare.capacity(), 8);
79///
80/// let exact = copyvec!["a"; 3];
81/// assert_eq!(exact, ["a", "a", "a"]);
82///
83/// let with_spare = copyvec!["a"; 3; + 5];
84/// assert_eq!(with_spare, ["a", "a", "a"]);
85/// ```
86///
87/// It may also be used in `const` expressions:
88/// ```
89/// # use copyvec::copyvec;
90/// const _: () = {
91/// copyvec!["a", "b", "c"];
92/// copyvec!["a", "b", "c"; + 5];
93/// copyvec!["a"; 3];
94/// copyvec!["a"; 3; + 5];
95/// };
96/// ```
97#[macro_export]
98macro_rules! copyvec {
99 [$($el:expr),* $(,)?; + $extra:expr] => {
100 $crate::__private::from_slice::<_, {
101 [
102 $($crate::__private::stringify!($el)),*
103 ].len() + $extra
104 }>(&[
105 $($el),*
106 ])
107 };
108 [$($el:expr),* $(,)?] => {
109 $crate::CopyVec::from_array([$($el,)*])
110 };
111 [$fill:expr; $len:expr; + $extra:expr] => {
112 $crate::__private::from_slice::<_, { $len + $extra }>(
113 &[$fill; $len]
114 )
115 };
116 [$fill:expr; $len:expr] => {
117 $crate::CopyVec::from_array([$fill; $len])
118 };
119}
120
121#[doc(hidden)]
122pub mod __private {
123 use super::*;
124 pub use core::stringify;
125
126 pub const fn from_slice<T, const N: usize>(slice: &[T]) -> CopyVec<T, N>
127 where
128 T: Copy,
129 {
130 if slice.len() > N {
131 panic!("initializer length is greater than backing storage length")
132 }
133 let mut buf = [const { MaybeUninit::uninit() }; N];
134 let mut ix = slice.len();
135 while let Some(nix) = ix.checked_sub(1) {
136 ix = nix;
137 buf[ix] = MaybeUninit::new(slice[ix]);
138 }
139 CopyVec {
140 occupied: slice.len(),
141 buf,
142 }
143 }
144}
145
146/// A contiguous growable array type, with a fixed, stack-alllocated capacity.
147#[derive(Copy)]
148pub struct CopyVec<T, const N: usize> {
149 occupied: usize,
150 buf: [MaybeUninit<T>; N],
151}
152
153impl<T, const N: usize> CopyVec<T, N> {
154 /// Constructs a new, empty `CopyVec<T>`, with space for `N` elements.
155 ///
156 /// # Examples
157 ///
158 /// ```
159 /// # use copyvec::CopyVec;
160 /// let mut vec: CopyVec<i32, 10> = CopyVec::new();
161 /// ```
162 pub const fn new() -> Self {
163 Self {
164 occupied: 0,
165 buf: [const { MaybeUninit::uninit() }; N],
166 }
167 }
168
169 // pub fn with_capacity(capacity: usize) -> Vec<T>
170 // pub fn try_with_capacity(capacity: usize) -> Result<Vec<T>, TryReserveError>
171 // pub unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize ) -> Vec<T>
172 // pub const fn new_in(alloc: A) -> Vec<T, A>
173 // pub fn with_capacity_in(capacity: usize, alloc: A) -> Vec<T, A>
174 // pub fn try_with_capacity_in(capacity: usize, alloc: A) -> Result<Vec<T, A>, TryReserveError>
175 // pub unsafe fn from_raw_parts_in(ptr: *mut T, length: usize, capacity: usize, alloc: A) -> Vec<T, A>
176 // pub fn into_raw_parts(self) -> (*mut T, usize, usize)
177 // pub fn into_raw_parts_with_alloc(self) -> (*mut T, usize, usize, A)
178
179 /// Returns the total number of elements the vector can hold.
180 ///
181 /// This is always equal to `N` for non-zero sized types.
182 ///
183 /// # Examples
184 ///
185 /// ```
186 /// # use copyvec::CopyVec;
187 /// let mut vec: CopyVec<i32, 10> = CopyVec::new();
188 /// vec.push(42);
189 /// assert_eq!(vec.capacity(), 10);
190 /// ```
191 pub const fn capacity(&self) -> usize {
192 match T::IS_ZST {
193 true => usize::MAX,
194 false => N,
195 }
196 }
197
198 // pub fn reserve(&mut self, additional: usize)
199 // pub fn reserve_exact(&mut self, additional: usize)
200 // pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError>
201 // pub fn try_reserve_exact( &mut self, additional: usize) -> Result<(), TryReserveError>
202 // pub fn shrink_to_fit(&mut self)
203 // pub fn shrink_to(&mut self, min_capacity: usize)
204
205 /// Converts the vector into [`Box<[T]>`][Box].
206 ///
207 /// # Examples
208 ///
209 /// ```
210 /// # use copyvec::copyvec;
211 /// let v = copyvec![1, 2, 3];
212 ///
213 /// let slice = v.into_boxed_slice();
214 /// assert_eq!(&*slice, &[1, 2, 3])
215 /// ```
216 #[cfg(feature = "alloc")]
217 pub fn into_boxed_slice(mut self) -> Box<[T]> {
218 let mut v = alloc::vec::Vec::<T>::with_capacity(self.len());
219 unsafe {
220 ptr::copy_nonoverlapping(self.as_ptr(), v.as_mut_ptr(), self.len());
221 v.set_len(self.len());
222 self.set_len(0);
223 }
224 v.into_boxed_slice()
225 }
226
227 /// Shortens the vector, keeping the first `len` elements and dropping the rest.
228 ///
229 /// If `len` is greater or equal to the vector’s current length, this has no effect.
230 ///
231 // The [`drain`](Self::drain) method can emulate truncate, but causes the excess elements to be returned instead of dropped.
232 //
233 /// # Examples
234 ///
235 /// Truncating a five element vector to two elements:
236 ///
237 /// ```
238 /// # use copyvec::copyvec;
239 /// let mut vec = copyvec![1, 2, 3, 4, 5];
240 /// vec.truncate(2);
241 /// assert_eq!(vec, [1, 2]);
242 /// ```
243 ///
244 /// No truncation occurs when `len` is greater than the vector's current
245 /// length:
246 ///
247 /// ```
248 /// # use copyvec::copyvec;
249 /// let mut vec = copyvec![1, 2, 3];
250 /// vec.truncate(8);
251 /// assert_eq!(vec, [1, 2, 3]);
252 /// ```
253 ///
254 /// Truncating when `len == 0` is equivalent to calling the [`clear`](Self::clear)
255 /// method.
256 ///
257 /// ```
258 /// # use copyvec::copyvec;
259 /// let mut vec = copyvec![1, 2, 3];
260 /// vec.truncate(0);
261 /// assert_eq!(vec, []);
262 /// ```
263 pub fn truncate(&mut self, len: usize) {
264 if len > self.occupied {
265 return;
266 }
267 let remaining_len = self.occupied - len;
268 unsafe {
269 let s = ptr::slice_from_raw_parts_mut(self.as_mut_ptr().add(len), remaining_len);
270 self.occupied = len;
271 ptr::drop_in_place(s);
272 }
273 }
274 /// Extracts a slice containing the entire vector.
275 ///
276 /// Equivalent to `&s[..]`.
277 ///
278 /// # Examples
279 ///
280 /// ```
281 /// # use copyvec::copyvec;
282 /// use std::io::{self, Write};
283 /// let buffer = copyvec![1, 2, 3, 5, 8];
284 /// io::sink().write(buffer.as_slice()).unwrap();
285 /// ```
286 pub const fn as_slice(&self) -> &[T] {
287 unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
288 }
289 /// Extracts a mutable slice of the entire vector.
290 ///
291 /// Equivalent to `&mut s[..]`.
292 ///
293 /// # Examples
294 ///
295 /// ```
296 /// # use copyvec::copyvec;
297 /// use std::io::{self, Read};
298 /// let mut buffer = copyvec![0; 3];
299 /// io::repeat(0b101).read_exact(buffer.as_mut_slice()).unwrap();
300 /// ```
301 pub fn as_mut_slice(&mut self) -> &mut [T] {
302 unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len()) }
303 }
304 /// See [`std::vec::Vec::as_ptr`].
305 pub const fn as_ptr(&self) -> *const T {
306 self.buf.as_ptr().cast()
307 }
308 /// See [`std::vec::Vec::as_mut_ptr`].
309 pub fn as_mut_ptr(&mut self) -> *mut T {
310 self.buf.as_mut_ptr().cast()
311 }
312 // pub fn allocator(&self) -> &A
313
314 /// See [`std::vec::Vec::set_len`].
315 ///
316 /// # Safety
317 /// - `new_len` must be less than or equal to [`capacity()`](Self::capacity).
318 /// - The elements at `old_len..new_len` must be initialized.
319 pub unsafe fn set_len(&mut self, new_len: usize) {
320 debug_assert!(new_len <= self.capacity());
321 self.occupied = new_len
322 }
323
324 /// Removes an element from the vector and returns it.
325 ///
326 /// The removed element is replaced by the last element of the vector.
327 ///
328 /// This does not preserve ordering of the remaining elements, but is *O*(1).
329 /// If you need to preserve the element order, use [`remove`](Self::remove) instead.
330 ///
331 /// # Panics
332 ///
333 /// Panics if `index` is out of bounds.
334 ///
335 /// # Examples
336 ///
337 /// ```
338 /// # use copyvec::copyvec;
339 /// let mut v = copyvec!["foo", "bar", "baz", "qux"];
340 ///
341 /// assert_eq!(v.swap_remove(1), "bar");
342 /// assert_eq!(v, ["foo", "qux", "baz"]);
343 ///
344 /// assert_eq!(v.swap_remove(0), "foo");
345 /// assert_eq!(v, ["baz", "qux"]);
346 /// ```
347 pub fn swap_remove(&mut self, index: usize) -> T {
348 let len = self.len();
349 if index >= len {
350 panic!("swap_remove index (is {index}) should be < len (is {len})")
351 }
352 unsafe {
353 let value = ptr::read(self.as_ptr().add(index));
354 let base_ptr = self.as_mut_ptr();
355 ptr::copy(base_ptr.add(len - 1), base_ptr.add(index), 1);
356 self.set_len(len - 1);
357 value
358 }
359 }
360
361 /// Inserts an element at position `index` within the vector, shifting all
362 /// elements after it to the right.
363 ///
364 /// # Panics
365 ///
366 /// Panics if `index > len`, or the capacity is exceeded.
367 ///
368 /// # Examples
369 ///
370 /// ```
371 /// # use copyvec::copyvec;
372 /// let mut vec = copyvec![1, 2, 3; + 2];
373 /// vec.insert(1, 4);
374 /// assert_eq!(vec, [1, 4, 2, 3]);
375 /// vec.insert(4, 5);
376 /// assert_eq!(vec, [1, 4, 2, 3, 5]);
377 /// ```
378 ///
379 /// # Time complexity
380 ///
381 /// Takes *O*([`len`](Self::len)) time. All items after the insertion index must be
382 /// shifted to the right. In the worst case, all elements are shifted when
383 /// the insertion index is 0.
384 pub fn insert(&mut self, index: usize, element: T)
385 where
386 T: Copy,
387 {
388 let len = self.len();
389 if index > len {
390 panic!("insertion index (is {index}) should be <= len (is {len})",)
391 }
392 self.push(element);
393 self.as_mut_slice()[index..].rotate_right(1)
394 }
395 /// Removes and returns the element at position `index` within the vector,
396 /// shifting all elements after it to the left.
397 ///
398 /// Note: Because this shifts over the remaining elements, it has a
399 /// worst-case performance of *O*(*n*). If you don't need the order of elements
400 /// to be preserved, use [`swap_remove`](Self::swap_remove) instead.
401 ///
402 /// # Panics
403 ///
404 /// Panics if `index` is out of bounds.
405 ///
406 /// # Examples
407 ///
408 /// ```
409 /// # use copyvec::copyvec;
410 /// let mut v = copyvec![1, 2, 3];
411 /// assert_eq!(v.remove(1), 2);
412 /// assert_eq!(v, [1, 3]);
413 /// ```
414 pub fn remove(&mut self, index: usize) -> T {
415 let len = self.len();
416 if index >= len {
417 panic!("removal index (is {index}) should be < len (is {len})");
418 }
419 unsafe {
420 let ret;
421 {
422 let ptr = self.as_mut_ptr().add(index);
423 ret = ptr::read(ptr);
424 ptr::copy(ptr.add(1), ptr, len - index - 1);
425 }
426 self.set_len(len - 1);
427 ret
428 }
429 }
430
431 /// Retains only the elements specified by the predicate.
432 ///
433 /// In other words, remove all elements `e` for which `f(&e)` returns `false`.
434 /// This method operates in place, visiting each element exactly once in the
435 /// original order, and preserves the order of the retained elements.
436 ///
437 /// # Examples
438 ///
439 /// ```
440 /// let mut vec = vec![1, 2, 3, 4];
441 /// vec.retain(|&x| x % 2 == 0);
442 /// assert_eq!(vec, [2, 4]);
443 /// ```
444 ///
445 /// Because the elements are visited exactly once in the original order,
446 /// external state may be used to decide which elements to keep.
447 ///
448 /// ```
449 /// let mut vec = vec![1, 2, 3, 4, 5];
450 /// let keep = [false, true, true, false, true];
451 /// let mut iter = keep.iter();
452 /// vec.retain(|_| *iter.next().unwrap());
453 /// assert_eq!(vec, [2, 3, 5]);
454 /// ```
455 pub fn retain<F>(&mut self, mut f: F)
456 where
457 F: FnMut(&T) -> bool,
458 {
459 self.retain_mut(|it| f(it))
460 }
461
462 /// Retains only the elements specified by the predicate, passing a mutable reference to it.
463 ///
464 /// In other words, remove all elements `e` such that `f(&mut e)` returns `false`.
465 /// This method operates in place, visiting each element exactly once in the
466 /// original order, and preserves the order of the retained elements.
467 ///
468 /// # Examples
469 ///
470 /// ```
471 /// # use copyvec::copyvec;
472 /// let mut vec = copyvec![1, 2, 3, 4];
473 /// vec.retain_mut(|x| if *x <= 3 {
474 /// *x += 1;
475 /// true
476 /// } else {
477 /// false
478 /// });
479 /// assert_eq!(vec, [2, 3, 4]);
480 /// ```
481 pub fn retain_mut<F>(&mut self, mut f: F)
482 where
483 F: FnMut(&mut T) -> bool,
484 {
485 let mut retain = [true; N];
486 let retain = &mut retain[..self.len()];
487 for (it, retain) in iter::zip(self.iter_mut(), &mut *retain) {
488 *retain = f(it);
489 }
490 let mut ct = 0;
491 for (ix, retain) in retain.iter().enumerate() {
492 if !retain {
493 self.remove(ix - ct);
494 ct += 1;
495 }
496 }
497 }
498
499 /// Removes all but the first of consecutive elements in the vector that resolve to the same
500 /// key.
501 ///
502 /// If the vector is sorted, this removes all duplicates.
503 ///
504 /// # Examples
505 ///
506 /// ```
507 /// # use copyvec::copyvec;
508 /// let mut vec = copyvec![10, 20, 21, 30, 20];
509 ///
510 /// vec.dedup_by_key(|i| *i / 10);
511 ///
512 /// assert_eq!(vec, [10, 20, 30, 20]);
513 /// ```
514 pub fn dedup_by_key<F, K>(&mut self, mut key: F)
515 where
516 F: FnMut(&mut T) -> K,
517 K: PartialEq,
518 {
519 self.dedup_by(|l, r| key(l) == key(r))
520 }
521
522 /// Removes all but the first of consecutive elements in the vector satisfying a given equality
523 /// relation.
524 ///
525 /// The `same_bucket` function is passed references to two elements from the vector and
526 /// must determine if the elements compare equal. The elements are passed in opposite order
527 /// from their order in the slice, so if `same_bucket(a, b)` returns `true`, `a` is removed.
528 ///
529 /// If the vector is sorted, this removes all duplicates.
530 ///
531 /// # Examples
532 ///
533 /// ```
534 /// # use copyvec::copyvec;
535 /// let mut vec = copyvec!["foo", "bar", "Bar", "baz", "bar"];
536 ///
537 /// vec.dedup_by(|a, b| a.eq_ignore_ascii_case(b));
538 ///
539 /// assert_eq!(vec, ["foo", "bar", "baz", "bar"]);
540 /// ```
541 pub fn dedup_by<F>(&mut self, mut same_bucket: F)
542 where
543 F: FnMut(&mut T, &mut T) -> bool,
544 {
545 let mut buf = [const { MaybeUninit::<T>::uninit() }; N];
546 let mut occupied = 0;
547 let mut iter = self.iter_mut();
548
549 let Some(mut bucket) = iter.next() else {
550 return;
551 };
552
553 for next in iter {
554 match same_bucket(next, bucket) {
555 true => continue,
556 false => {
557 unsafe { ptr::swap_nonoverlapping(buf[occupied].as_mut_ptr(), bucket, 1) };
558 bucket = next;
559 occupied += 1;
560 }
561 }
562 }
563 unsafe { ptr::swap_nonoverlapping(buf[occupied].as_mut_ptr(), bucket, 1) };
564 occupied += 1;
565 *self = Self { occupied, buf }
566 }
567
568 /// Appends an element to the back of a collection.
569 ///
570 /// # Panics
571 /// - If the underlying storage has been exhausted.
572 /// Use [`Self::push_within_capacity`] or [`Self::try_push`]
573 /// to handle the error instead,
574 ///
575 /// ```
576 /// # use copyvec::copyvec;
577 /// let mut vec = copyvec![1, 2; + 1];
578 /// vec.push(3);
579 /// assert_eq!(vec, [1, 2, 3]);
580 /// ```
581 pub fn push(&mut self, value: T)
582 where
583 T: Copy,
584 {
585 match self.push_within_capacity(value) {
586 Ok(()) => {}
587 Err(_) => panic!("exceeded fixed capacity {} of vector", self.capacity()),
588 }
589 }
590
591 /// Appends an element if there is sufficient spare capacity, otherwise an error is returned
592 /// with the element.
593 ///
594 /// See also [`Self::try_push`].
595 ///
596 /// # Examples
597 ///
598 /// ```
599 /// # use copyvec::CopyVec;
600 /// let mut vec = CopyVec::<_, 1>::new();
601 /// vec.push_within_capacity('a').unwrap();
602 /// vec.push_within_capacity('b').unwrap_err();
603 /// ```
604 ///
605 /// # Time complexity
606 ///
607 /// Takes *O*(1) time.
608 pub fn push_within_capacity(&mut self, value: T) -> Result<(), T>
609 where
610 T: Copy,
611 {
612 match self.len() >= self.capacity() {
613 true => Err(value),
614 false => {
615 if !T::IS_ZST {
616 self.buf[self.len()].write(value);
617 }
618 self.occupied += 1;
619 Ok(())
620 }
621 }
622 }
623 /// Removes the last element from a vector and returns it, or [`None`] if it
624 /// is empty.
625 ///
626 /// # Examples
627 ///
628 /// ```
629 /// # use copyvec::copyvec;
630 /// let mut vec = copyvec![1, 2, 3];
631 /// assert_eq!(vec.pop(), Some(3));
632 /// assert_eq!(vec, [1, 2]);
633 /// ```
634 ///
635 /// # Time complexity
636 ///
637 /// Takes *O*(1) time.
638 pub fn pop(&mut self) -> Option<T> {
639 match self.occupied == 0 {
640 true => None,
641 false => {
642 self.occupied -= 1;
643 Some(unsafe { ptr::read(self.as_ptr().add(self.len())) })
644 }
645 }
646 }
647
648 /// Removes and returns the last element in a vector if the predicate
649 /// returns `true`, or [`None`] if the predicate returns false or the vector
650 /// is empty.
651 ///
652 /// # Examples
653 ///
654 /// ```
655 /// # use copyvec::copyvec;
656 /// let mut vec = copyvec![1, 2, 3, 4];
657 /// let pred = |x: &mut i32| *x % 2 == 0;
658 ///
659 /// assert_eq!(vec.pop_if(pred), Some(4));
660 /// assert_eq!(vec, [1, 2, 3]);
661 /// assert_eq!(vec.pop_if(pred), None);
662 /// ```
663 pub fn pop_if<F>(&mut self, f: F) -> Option<T>
664 where
665 F: FnOnce(&mut T) -> bool,
666 {
667 let last = self.last_mut()?;
668 if f(last) {
669 self.pop()
670 } else {
671 None
672 }
673 }
674
675 // pub fn append(&mut self, other: &mut Vec<T, A>)
676
677 // pub fn drain<R>(&mut self, range: R) -> Drain<'_, T, A> ⓘ
678 // where
679 // R: RangeBounds<usize>,
680
681 /// Clears the vector, removing all values.
682 ///
683 /// # Examples
684 ///
685 /// ```
686 /// # use copyvec::copyvec;
687 /// let mut v = copyvec![1, 2, 3];
688 ///
689 /// v.clear();
690 ///
691 /// assert!(v.is_empty());
692 /// ```
693 pub fn clear(&mut self) {
694 self.truncate(0)
695 }
696 /// Returns the number of elements in the vector, also referred to
697 /// as its 'length'.
698 ///
699 /// # Examples
700 ///
701 /// ```
702 /// # use copyvec::copyvec;
703 /// let a = copyvec![1, 2, 3];
704 /// assert_eq!(a.len(), 3);
705 /// ```
706 pub const fn len(&self) -> usize {
707 self.occupied
708 }
709 /// Returns `true` if the vector contains no elements.
710 ///
711 /// # Examples
712 ///
713 /// ```
714 /// # use copyvec::CopyVec;
715 /// let mut v = CopyVec::<_, 1>::new();
716 /// assert!(v.is_empty());
717 ///
718 /// v.push(1);
719 /// assert!(!v.is_empty());
720 /// ```
721 pub const fn is_empty(&self) -> bool {
722 self.len() == 0
723 }
724 /// Splits the collection into two at the given index.
725 ///
726 /// Returns a newly vector containing the elements in the range `[at, len)`.
727 /// After the call, the original vector will be left containing
728 /// the elements `[0, at)` with its previous capacity unchanged.
729 ///
730 /// - If you want to take ownership of the entire contents and capacity of
731 /// the vector, see [`mem::take`] or [`mem::replace`].
732 /// - If you don't need the returned vector at all, see [`Self::truncate`].
733 // - If you want to take ownership of an arbitrary subslice, or you don't
734 // necessarily want to store the removed items in a vector, see [`Self::drain`].
735 ///
736 /// # Panics
737 ///
738 /// Panics if `at > len`.
739 ///
740 /// # Examples
741 ///
742 /// ```
743 /// # use copyvec::copyvec;
744 /// let mut vec = copyvec![1, 2, 3];
745 /// let vec2 = vec.split_off(1);
746 /// assert_eq!(vec, [1]);
747 /// assert_eq!(vec2, [2, 3]);
748 /// ```
749 pub fn split_off(&mut self, at: usize) -> Self
750 where
751 T: Copy,
752 {
753 let (_, new) = self.as_slice().split_at(at);
754 let new = __private::from_slice(new);
755 self.truncate(at);
756 new
757 }
758
759 // pub fn resize_with<F>(&mut self, new_len: usize, f: F)
760 // where
761 // F: FnMut() -> T,
762
763 // pub fn leak<'a>(self) -> &'a mut [T]
764
765 /// Returns the remaining spare capacity of the vector as a slice of
766 /// `MaybeUninit<T>`.
767 ///
768 /// The returned slice can be used to fill the vector with data (e.g. by
769 /// reading from a file) before marking the data as initialized using the
770 /// [`set_len`](Self::set_len) method.
771 ///
772 /// # Examples
773 ///
774 /// ```
775 /// # use copyvec::CopyVec;
776 /// // Vector is big enough for 10 elements.
777 /// let mut v = CopyVec::<_, 10>::new();
778 ///
779 /// // Fill in the first 3 elements.
780 /// let uninit = v.spare_capacity_mut();
781 /// uninit[0].write(0);
782 /// uninit[1].write(1);
783 /// uninit[2].write(2);
784 ///
785 /// // Mark the first 3 elements of the vector as being initialized.
786 /// unsafe {
787 /// v.set_len(3);
788 /// }
789 ///
790 /// assert_eq!(&v, &[0, 1, 2]);
791 /// ```
792 pub fn spare_capacity_mut(&mut self) -> &mut [MaybeUninit<T>] {
793 unsafe {
794 slice::from_raw_parts_mut(
795 self.as_mut_ptr().add(self.len()).cast(),
796 self.capacity() - self.len(),
797 )
798 }
799 }
800
801 // pub fn split_at_spare_mut(&mut self) -> (&mut [T], &mut [MaybeUninit<T>])
802 // pub fn resize(&mut self, new_len: usize, value: T) where T: Clone
803 // pub fn extend_from_slice(&mut self, other: &[T]) where T: Clone
804
805 // pub fn extend_from_within<R>(&mut self, src: R)
806 // where
807 // R: RangeBounds<usize>,
808
809 // pub fn into_flattened(self) -> Vec<T, A> (for CopyVec<[T; M], N>)
810
811 /// Removes consecutive repeated elements in the vector according to the
812 /// [`PartialEq`] trait implementation.
813 ///
814 /// If the vector is sorted, this removes all duplicates.
815 ///
816 /// # Examples
817 ///
818 /// ```
819 /// # use copyvec::copyvec;
820 /// let mut vec = copyvec![1, 2, 2, 3, 2];
821 ///
822 /// vec.dedup();
823 ///
824 /// assert_eq!(vec, [1, 2, 3, 2]);
825 /// ```
826 pub fn dedup(&mut self)
827 where
828 T: PartialEq,
829 {
830 self.dedup_by(|l, r| l == r)
831 }
832 // pub fn splice<R, I>(&mut self, range: R, replace_with: I) -> Splice<'_, <I as IntoIterator>::IntoIter, A>
833
834 // pub fn extract_if<F>(&mut self, filter: F) -> ExtractIf<'_, T, F, A> ⓘ
835 // where
836 // F: FnMut(&mut T) -> bool,
837}
838
839/// Methods that don't mirror [`std::vec::Vec`](https://doc.rust-lang.org/std/vec/struct.Vec.html)'s API.
840impl<T, const N: usize> CopyVec<T, N> {
841 /// Create a full [`CopyVec`] from an array.
842 ///
843 /// ```rust
844 /// # use copyvec::CopyVec;
845 /// let vec = CopyVec::from_array([1, 2, 3]);
846 /// assert_eq!(vec.capacity(), 3);
847 /// ```
848 pub const fn from_array(array: [T; N]) -> Self
849 where
850 T: Copy,
851 {
852 let mut buf = [const { MaybeUninit::uninit() }; N];
853 let mut ix = N;
854 while let Some(nix) = ix.checked_sub(1) {
855 ix = nix;
856 buf[ix] = MaybeUninit::new(array[ix])
857 }
858 Self { occupied: N, buf }
859 }
860 /// If the vec is full, convert it into an array.
861 ///
862 /// ```rust
863 /// # use copyvec::copyvec;
864 /// let vec = copyvec![1, 2, 3];
865 /// let arr = vec.into_array().unwrap();
866 /// ```
867 pub fn into_array(self) -> Option<[T; N]> {
868 let Self { occupied, buf } = self;
869 match occupied == N {
870 true => {
871 let mut new_buf = MaybeUninit::<[T; N]>::uninit();
872 unsafe {
873 ptr::copy_nonoverlapping(
874 buf.as_ptr().cast::<T>(),
875 new_buf.as_mut_ptr().cast::<T>(),
876 N,
877 );
878 Some(new_buf.assume_init())
879 }
880 }
881 false => None,
882 }
883 }
884 /// Like [`Self::push_within_capacity`], but returns an implementor of
885 /// [`std::error::Error`].
886 ///
887 /// ```
888 /// # use copyvec::CopyVec;
889 /// fn fallible(vec: &mut CopyVec<char, 10>) -> Result<(), Box<dyn std::error::Error>> {
890 /// vec.try_push('a')?;
891 /// Ok(())
892 /// }
893 /// ```
894 pub fn try_push(&mut self, value: T) -> Result<(), Error>
895 where
896 T: Copy,
897 {
898 self.push_within_capacity(value).map_err(|_| Error {
899 capacity: self.capacity(),
900 excess: None,
901 })
902 }
903 /// Fallible verson of [`FromIterator`], since `N` is expected to be small.
904 /// ```
905 /// # use copyvec::CopyVec;
906 /// CopyVec::<_, 2>::try_from_iter([1, 2, 3]).unwrap_err();
907 /// CopyVec::<_, 2>::try_from_iter([1, 2]).unwrap();
908 /// ```
909 pub fn try_from_iter<I: IntoIterator<Item = T>>(iter: I) -> Result<Self, Error>
910 where
911 T: Copy,
912 {
913 let mut this = Self::new();
914 this.try_extend(iter)?;
915 Ok(this)
916 }
917 /// Fallible version of [`Extend`], since `N` is expected to be small.
918 /// ```
919 /// # use copyvec::copyvec;
920 /// let mut vec = copyvec![1, 2, 3];
921 /// vec.try_extend([1]).unwrap_err();
922 /// vec.pop();
923 /// vec.try_extend([1]).unwrap();
924 /// ```
925 pub fn try_extend<I: IntoIterator<Item = T>>(&mut self, iter: I) -> Result<(), Error>
926 where
927 T: Copy,
928 {
929 let mut excess = 0;
930 for it in iter {
931 match self.push_within_capacity(it) {
932 Ok(()) => {}
933 Err(_) => excess += 1,
934 }
935 }
936 match excess == 0 {
937 true => Ok(()),
938 false => Err(Error {
939 capacity: self.capacity(),
940 excess: Some(excess),
941 }),
942 }
943 }
944 /// Returns the number of unoccupied slots in the vec.
945 /// ```
946 /// # use copyvec::copyvec;
947 /// let vec = copyvec![1, 2, 3; + 3];
948 /// assert_eq!(vec.remaining_capacity(), 3);
949 /// ```
950 pub const fn remaining_capacity(&self) -> usize {
951 self.capacity() - self.len()
952 }
953}
954
955/// Error returned from [`CopyVec::try_push`], [`CopyVec::try_extend`] or [`CopyVec::try_from_iter`].
956pub struct Error {
957 capacity: usize,
958 /// [`None`] if returned from [`CopyVec::try_push`].
959 excess: Option<usize>,
960}
961
962impl fmt::Debug for Error {
963 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
964 f.debug_tuple("Error")
965 .field(&DebugWithDisplay(self))
966 .finish()
967 }
968}
969
970impl fmt::Display for Error {
971 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
972 let Self { capacity, excess } = self;
973 match excess {
974 Some(excess) => f.write_fmt(format_args!(
975 "exceeded fixed capacity of {} by {} elements",
976 capacity, excess
977 )),
978 None => f.write_fmt(format_args!("exceeded fixed capacity of {}", capacity)),
979 }
980 }
981}
982
983struct DebugWithDisplay<T>(T);
984impl<T> fmt::Debug for DebugWithDisplay<T>
985where
986 T: fmt::Display,
987{
988 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989 T::fmt(&self.0, f)
990 }
991}
992
993#[cfg(feature = "std")]
994impl std::error::Error for Error {}
995
996impl<T, const N: usize> AsMut<[T]> for CopyVec<T, N> {
997 fn as_mut(&mut self) -> &mut [T] {
998 self.as_mut_slice()
999 }
1000}
1001impl<T, const N: usize> AsMut<CopyVec<T, N>> for CopyVec<T, N> {
1002 fn as_mut(&mut self) -> &mut Self {
1003 self
1004 }
1005}
1006
1007impl<T, const N: usize> AsRef<[T]> for CopyVec<T, N> {
1008 fn as_ref(&self) -> &[T] {
1009 self.as_slice()
1010 }
1011}
1012impl<T, const N: usize> AsRef<CopyVec<T, N>> for CopyVec<T, N> {
1013 fn as_ref(&self) -> &Self {
1014 self
1015 }
1016}
1017
1018impl<T, const N: usize> Borrow<[T]> for CopyVec<T, N> {
1019 fn borrow(&self) -> &[T] {
1020 self.as_slice()
1021 }
1022}
1023impl<T, const N: usize> BorrowMut<[T]> for CopyVec<T, N> {
1024 fn borrow_mut(&mut self) -> &mut [T] {
1025 self.as_mut_slice()
1026 }
1027}
1028
1029impl<T, const N: usize> Clone for CopyVec<T, N>
1030where
1031 T: Copy,
1032{
1033 fn clone(&self) -> Self {
1034 *self
1035 }
1036}
1037
1038impl<T, const N: usize> fmt::Debug for CopyVec<T, N>
1039where
1040 T: fmt::Debug,
1041{
1042 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1043 f.debug_list().entries(self.as_slice()).finish()
1044 }
1045}
1046
1047impl<T, const N: usize> Default for CopyVec<T, N> {
1048 fn default() -> Self {
1049 Self::new()
1050 }
1051}
1052
1053impl<T, const N: usize> Deref for CopyVec<T, N> {
1054 type Target = [T];
1055
1056 fn deref(&self) -> &Self::Target {
1057 self.as_slice()
1058 }
1059}
1060impl<T, const N: usize> DerefMut for CopyVec<T, N> {
1061 fn deref_mut(&mut self) -> &mut Self::Target {
1062 self.as_mut_slice()
1063 }
1064}
1065
1066// impl<'a, T, A> Extend<&'a T> for Vec<T, A>
1067// where
1068// T: Copy + 'a,
1069// A: Allocator,
1070
1071// impl<T, A> Extend<T> for Vec<T, A>
1072// where
1073// A: Allocator,
1074
1075// impl<T> From<&[T]> for Vec<T>
1076// where
1077// T: Clone,
1078
1079// impl<T, const N: usize> From<&[T; N]> for Vec<T>
1080// where
1081// T: Clone,
1082
1083// impl<'a, T> From<&'a Vec<T>> for Cow<'a, [T]>
1084// where
1085// T: Clone,
1086
1087// impl<T> From<&mut [T]> for Vec<T>
1088// where
1089// T: Clone,
1090
1091// impl<T, const N: usize> From<&mut [T; N]> for Vec<T>
1092// where
1093// T: Clone,
1094
1095// impl From<&str> for Vec<u8>
1096
1097// impl<T, const N: usize> From<[T; N]> for Vec<T>
1098
1099// impl<T, A> From<BinaryHeap<T, A>> for Vec<T, A>
1100// where
1101// A: Allocator,
1102
1103// impl<T, A> From<Box<[T], A>> for Vec<T, A>
1104// where
1105// A: Allocator,
1106
1107// impl From<CString> for Vec<u8>
1108
1109// impl<'a, T> From<Cow<'a, [T]>> for Vec<T>
1110// where
1111// [T]: ToOwned<Owned = Vec<T>>,
1112
1113// impl From<String> for Vec<u8>
1114
1115// impl From<Vec<NonZero<u8>>> for CString
1116
1117// impl<'a, T> From<Vec<T>> for Cow<'a, [T]>
1118// where
1119// T: Clone,
1120
1121// impl<T, A> From<Vec<T, A>> for Arc<[T], A>
1122// where
1123// A: Allocator + Clone,
1124
1125// impl<T, A> From<Vec<T, A>> for BinaryHeap<T, A>
1126// where
1127// T: Ord,
1128// A: Allocator,
1129
1130// impl<T, A> From<Vec<T, A>> for Box<[T], A>
1131// where
1132// A: Allocator,
1133
1134// impl<T, A> From<Vec<T, A>> for Rc<[T], A>
1135// where
1136// A: Allocator,
1137
1138// impl<T, A> From<Vec<T, A>> for VecDeque<T, A>
1139// where
1140// A: Allocator,
1141
1142// impl<T, A> From<VecDeque<T, A>> for Vec<T, A>
1143// where
1144// A: Allocator,
1145
1146// impl<T> FromIterator<T> for Vec<T>
1147
1148impl<T, const N: usize> Hash for CopyVec<T, N>
1149where
1150 T: Hash,
1151{
1152 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
1153 self.as_slice().hash(state)
1154 }
1155}
1156
1157impl<T, I, const N: usize> Index<I> for CopyVec<T, N>
1158where
1159 I: SliceIndex<[T]>,
1160{
1161 type Output = <I as SliceIndex<[T]>>::Output;
1162
1163 fn index(&self, index: I) -> &Self::Output {
1164 self.as_slice().index(index)
1165 }
1166}
1167
1168impl<T, I, const N: usize> IndexMut<I> for CopyVec<T, N>
1169where
1170 I: SliceIndex<[T]>,
1171{
1172 fn index_mut(&mut self, index: I) -> &mut Self::Output {
1173 self.as_mut_slice().index_mut(index)
1174 }
1175}
1176
1177impl<'a, T, const N: usize> IntoIterator for &'a CopyVec<T, N> {
1178 type Item = &'a T;
1179 type IntoIter = slice::Iter<'a, T>;
1180 fn into_iter(self) -> Self::IntoIter {
1181 self.as_slice().iter()
1182 }
1183}
1184
1185impl<'a, T, const N: usize> IntoIterator for &'a mut CopyVec<T, N> {
1186 type Item = &'a mut T;
1187 type IntoIter = slice::IterMut<'a, T>;
1188 fn into_iter(self) -> Self::IntoIter {
1189 self.as_mut_slice().iter_mut()
1190 }
1191}
1192
1193impl<T, const N: usize> IntoIterator for CopyVec<T, N> {
1194 type Item = T;
1195 type IntoIter = IntoIter<T, N>;
1196 fn into_iter(self) -> Self::IntoIter {
1197 let Self {
1198 occupied,
1199 buf: inner,
1200 } = self;
1201 IntoIter {
1202 inner: inner.into_iter().take(occupied),
1203 }
1204 }
1205}
1206
1207/// Consuming iterator for a [`CopyVec`].
1208pub struct IntoIter<T, const N: usize> {
1209 inner: Take<array::IntoIter<MaybeUninit<T>, N>>,
1210}
1211
1212impl<T, const N: usize> Iterator for IntoIter<T, N> {
1213 type Item = T;
1214
1215 fn next(&mut self) -> Option<Self::Item> {
1216 self.inner.next().map(|it| unsafe { it.assume_init() })
1217 }
1218 fn nth(&mut self, n: usize) -> Option<Self::Item> {
1219 self.inner.nth(n).map(|it| unsafe { it.assume_init() })
1220 }
1221 fn size_hint(&self) -> (usize, Option<usize>) {
1222 self.inner.size_hint()
1223 }
1224}
1225impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
1226 fn next_back(&mut self) -> Option<Self::Item> {
1227 self.inner.next_back().map(|it| unsafe { it.assume_init() })
1228 }
1229 fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
1230 self.inner.nth_back(n).map(|it| unsafe { it.assume_init() })
1231 }
1232}
1233
1234impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {}
1235impl<T, const N: usize> FusedIterator for IntoIter<T, N> {}
1236
1237impl<T, const N: usize> Ord for CopyVec<T, N>
1238where
1239 T: Ord,
1240{
1241 fn cmp(&self, other: &Self) -> Ordering {
1242 self.as_slice().cmp(other.as_slice())
1243 }
1244}
1245
1246impl<T, U, const N: usize> PartialEq<&[U]> for CopyVec<T, N>
1247where
1248 T: PartialEq<U>,
1249{
1250 fn eq(&self, other: &&[U]) -> bool {
1251 self.as_slice() == *other
1252 }
1253}
1254
1255impl<T, U, const N: usize, const M: usize> PartialEq<&[U; M]> for CopyVec<T, N>
1256where
1257 T: PartialEq<U>,
1258{
1259 fn eq(&self, other: &&[U; M]) -> bool {
1260 self.as_slice() == *other
1261 }
1262}
1263
1264impl<T, U, const N: usize> PartialEq<&mut [U]> for CopyVec<T, N>
1265where
1266 T: PartialEq<U>,
1267{
1268 fn eq(&self, other: &&mut [U]) -> bool {
1269 self.as_slice() == *other
1270 }
1271}
1272
1273impl<T, U, const N: usize> PartialEq<[U]> for CopyVec<T, N>
1274where
1275 T: PartialEq<U>,
1276{
1277 fn eq(&self, other: &[U]) -> bool {
1278 self.as_slice() == other
1279 }
1280}
1281
1282impl<T, U, const N: usize, const M: usize> PartialEq<[U; M]> for CopyVec<T, N>
1283where
1284 T: PartialEq<U>,
1285{
1286 fn eq(&self, other: &[U; M]) -> bool {
1287 self.as_slice() == other
1288 }
1289}
1290
1291impl<T, U, const N: usize> PartialEq<CopyVec<U, N>> for &[T]
1292where
1293 T: PartialEq<U>,
1294{
1295 fn eq(&self, other: &CopyVec<U, N>) -> bool {
1296 *self == other.as_slice()
1297 }
1298}
1299
1300impl<T, U, const N: usize> PartialEq<CopyVec<U, N>> for &mut [T]
1301where
1302 T: PartialEq<U>,
1303{
1304 fn eq(&self, other: &CopyVec<U, N>) -> bool {
1305 *self == other.as_slice()
1306 }
1307}
1308
1309impl<T, U, const N: usize> PartialEq<CopyVec<U, N>> for [T]
1310where
1311 T: PartialEq<U>,
1312{
1313 fn eq(&self, other: &CopyVec<U, N>) -> bool {
1314 self == other.as_slice()
1315 }
1316}
1317
1318#[cfg(feature = "alloc")]
1319impl<T, U, const N: usize> PartialEq<CopyVec<U, N>> for Cow<'_, [T]>
1320where
1321 T: PartialEq<U> + Clone,
1322{
1323 fn eq(&self, other: &CopyVec<U, N>) -> bool {
1324 *self == other.as_slice()
1325 }
1326}
1327
1328// impl<T, U, A> PartialEq<Vec<U, A>> for VecDeque<T, A>
1329// where
1330// A: Allocator,
1331// T: PartialEq<U>,
1332
1333impl<T, U, const N: usize, const M: usize> PartialEq<CopyVec<U, M>> for CopyVec<T, N>
1334where
1335 T: PartialEq<U>,
1336{
1337 fn eq(&self, other: &CopyVec<U, M>) -> bool {
1338 self.as_slice().eq(other.as_slice())
1339 }
1340}
1341
1342impl<T, const N: usize, const M: usize> PartialOrd<CopyVec<T, M>> for CopyVec<T, N>
1343where
1344 T: PartialOrd,
1345{
1346 fn partial_cmp(&self, other: &CopyVec<T, M>) -> Option<Ordering> {
1347 self.as_slice().partial_cmp(other.as_slice())
1348 }
1349}
1350
1351// impl<T, const N: usize> TryFrom<Vec<T>> for Box<[T; N]>
1352
1353// impl<T, A, const N: usize> TryFrom<Vec<T, A>> for [T; N]
1354// where
1355// A: Allocator,
1356
1357#[cfg(feature = "std")]
1358impl<const N: usize> io::Write for CopyVec<u8, N> {
1359 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
1360 let mut written = 0;
1361 for it in buf {
1362 match self.try_push(*it) {
1363 Ok(()) => written += 1,
1364 Err(_) => return Ok(written),
1365 }
1366 }
1367 Ok(written)
1368 }
1369
1370 fn flush(&mut self) -> io::Result<()> {
1371 Ok(())
1372 }
1373
1374 fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
1375 match self.try_extend(buf.iter().copied()) {
1376 Ok(()) => Ok(()),
1377 Err(e) => Err(io::Error::new(io::ErrorKind::WriteZero, e)),
1378 }
1379 }
1380}
1381
1382// impl<T, A> DerefPure for Vec<T, A>
1383// where
1384// A: Allocator,
1385
1386impl<T, const N: usize> Eq for CopyVec<T, N> where T: Eq {}
1387
1388trait Ext: Sized {
1389 const IS_ZST: bool = mem::size_of::<Self>() == 0;
1390}
1391impl<T> Ext for T {}
1392
1393#[cfg(all(test, feature = "std", feature = "quickcheck"))]
1394mod tests {
1395 use fmt::Debug;
1396 use quickcheck::Arbitrary;
1397 use quickcheck1 as quickcheck;
1398
1399 use super::*;
1400
1401 #[derive(Debug, Clone)]
1402 enum Op<T> {
1403 Push(T),
1404 Pop,
1405 Truncate(usize),
1406 Clear,
1407 Insert(usize, T),
1408 SwapRemove(usize),
1409 Remove(usize),
1410 Dedup,
1411 RetainLt(T),
1412 RetainGt(T),
1413 }
1414
1415 impl<T> Arbitrary for Op<T>
1416 where
1417 T: Clone + Arbitrary,
1418 {
1419 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
1420 let options = [
1421 Op::Push(T::arbitrary(g)),
1422 Op::Pop,
1423 Op::Truncate(usize::arbitrary(g)),
1424 Op::Clear,
1425 Op::Insert(usize::arbitrary(g), T::arbitrary(g)),
1426 Op::SwapRemove(usize::arbitrary(g)),
1427 Op::Remove(usize::arbitrary(g)),
1428 Op::Dedup,
1429 Op::RetainLt(T::arbitrary(g)),
1430 Op::RetainGt(T::arbitrary(g)),
1431 ];
1432 g.choose(&options).unwrap().clone()
1433 }
1434 }
1435
1436 fn check_invariants<const N: usize, T: PartialEq + Debug>(
1437 ours: &mut CopyVec<T, N>,
1438 theirs: &mut Vec<T>,
1439 ) {
1440 assert!(ours.iter().eq(theirs.iter()));
1441 assert!(ours.iter_mut().eq(theirs.iter_mut()));
1442 assert_eq!(ours.capacity(), theirs.capacity());
1443 assert_eq!(ours.len(), theirs.len());
1444 assert_eq!(ours.as_slice(), theirs.as_slice());
1445 }
1446
1447 fn do_test<const N: usize, T: PartialEq + Copy + Debug + PartialOrd>(ops: Vec<Op<T>>) {
1448 let mut ours = CopyVec::<T, N>::new();
1449 let mut theirs = Vec::new();
1450 theirs.reserve_exact(N);
1451 check_invariants(&mut ours, &mut theirs);
1452 for op in ops {
1453 match op {
1454 Op::Push(it) => {
1455 assert_eq!(
1456 ours.push_within_capacity(it),
1457 push_within_capacity(&mut theirs, it)
1458 );
1459 }
1460 Op::Pop => {
1461 assert_eq!(ours.pop(), theirs.pop())
1462 }
1463 Op::Truncate(u) => {
1464 ours.truncate(u);
1465 theirs.truncate(u)
1466 }
1467 Op::Clear => {
1468 ours.clear();
1469 theirs.clear();
1470 }
1471 Op::Insert(ix, it) => {
1472 if ix <= theirs.len() && !theirs.spare_capacity_mut().is_empty() {
1473 ours.insert(ix, it);
1474 theirs.insert(ix, it);
1475 }
1476 }
1477 Op::SwapRemove(ix) => {
1478 if ix < theirs.len() {
1479 assert_eq!(ours.swap_remove(ix), theirs.swap_remove(ix))
1480 }
1481 }
1482 Op::Remove(ix) => {
1483 if ix < theirs.len() {
1484 assert_eq!(ours.remove(ix), theirs.remove(ix))
1485 }
1486 }
1487 Op::Dedup => {
1488 ours.dedup();
1489 theirs.dedup();
1490 }
1491 Op::RetainLt(r) => {
1492 ours.retain(|t| *t < r);
1493 theirs.retain(|t| *t < r);
1494 }
1495 Op::RetainGt(r) => {
1496 ours.retain(|t| *t > r);
1497 theirs.retain(|t| *t > r);
1498 }
1499 }
1500 check_invariants(&mut ours, &mut theirs)
1501 }
1502 }
1503
1504 fn push_within_capacity<T>(v: &mut Vec<T>, value: T) -> Result<(), T> {
1505 match v.spare_capacity_mut().is_empty() {
1506 true => Err(value),
1507 false => {
1508 v.push(value);
1509 Ok(())
1510 }
1511 }
1512 }
1513
1514 quickcheck::quickcheck! {
1515 fn quickcheck_0_u8(ops: Vec<Op<u8>>) -> () {
1516 do_test::<10, _>(ops)
1517 }
1518 fn quickcheck_0_unit(ops: Vec<Op<()>>) -> () {
1519 do_test::<10, _>(ops)
1520 }
1521 fn quickcheck_10_u8(ops: Vec<Op<u8>>) -> () {
1522 do_test::<10, _>(ops)
1523 }
1524 fn quickcheck_10_unit(ops: Vec<Op<()>>) -> () {
1525 do_test::<10, _>(ops)
1526 }
1527 }
1528}