spinoso_array/array/smallvec/
mod.rs

1//! Ruby `Array` based on [`SmallVec`].
2
3use alloc::boxed::Box;
4use alloc::vec::Vec;
5use core::cmp;
6use core::slice::{Iter, IterMut};
7
8use smallvec::SmallVec;
9
10use crate::array::INLINE_CAPACITY;
11
12mod convert;
13mod eq;
14mod impls;
15mod iter;
16
17/// A contiguous growable array type based on
18/// [`SmallVec<[T; INLINE_CAPACITY]>`](SmallVec) that implements the small vector
19/// optimization.
20///
21/// `SmallArray` is an alternate implementation of [`Array`] that implements the
22/// small vector optimization. For `SmallArray`s less than [`INLINE_CAPACITY`]
23/// elements long, there is no heap allocation.
24///
25/// `SmallArray` provides a nearly identical API to the one in [`Array`]. There
26/// are two important differences:
27///
28/// 1. `SmallVec<[T; INLINE_CAPACITY]>` is used in some places where
29///    [`Vec<T>`](Vec) would have been used.
30/// 2. Trait bounds on some methods are more restrictive and require elements to
31///    be [`Copy`].
32///
33/// Similar to `Array`, `SmallArray` implements indexing and mutating APIs that
34/// make an ideal backend for the [Ruby `Array` core class][ruby-array]. In
35/// practice, this results in less generic, more single-use APIs. For example,
36/// instead of [`Vec::drain`], `SmallArray` implements [`shift`], [`shift_n`],
37/// [`pop`], and [`pop_n`].
38///
39/// Similarly, slicing APIs are more specialized, such as [`first_n`] and
40/// [`last_n`]. Slicing APIs do not return [`Option`], instead preferring to
41/// return an empty slice.
42///
43/// # Examples
44///
45/// ```
46/// # use spinoso_array::SmallArray;
47/// let mut ary = SmallArray::new();
48/// ary.push(1);
49/// ary.push(2);
50///
51/// assert_eq!(ary.len(), 2);
52/// assert_eq!(ary[0], 1);
53///
54/// assert_eq!(ary.pop(), Some(2));
55/// assert_eq!(ary.len(), 1);
56///
57/// ary[0] = 7;
58/// assert_eq!(ary[0], 7);
59///
60/// ary.extend([1, 2, 3].iter().copied());
61///
62/// for x in &ary {
63///     println!("{}", x);
64/// }
65/// assert_eq!(ary, &[7, 1, 2, 3]);
66/// ```
67///
68/// [`Array`]: crate::Array
69/// [ruby-array]: https://ruby-doc.org/core-3.1.2/Array.html
70/// [`shift`]: SmallArray::shift
71/// [`shift_n`]: SmallArray::shift_n
72/// [`drop_n`]: SmallArray::drop_n
73/// [`pop`]: SmallArray::pop
74/// [`pop_n`]: SmallArray::pop_n
75/// [`first_n`]: SmallArray::first_n
76/// [`last_n`]: SmallArray::last_n
77#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
78#[cfg_attr(docsrs, doc(cfg(feature = "small-array")))]
79pub struct SmallArray<T>(SmallVec<[T; INLINE_CAPACITY]>);
80
81impl<T> Default for SmallArray<T> {
82    #[inline]
83    fn default() -> Self {
84        Self::new()
85    }
86}
87
88impl<T> SmallArray<T> {
89    /// Construct a new, empty `SmallArray<T>`.
90    ///
91    /// The vector will not allocate until more than [`INLINE_CAPACITY`]
92    /// elements are pushed into it.
93    ///
94    /// # Examples
95    ///
96    /// ```
97    /// use spinoso_array::{SmallArray, INLINE_CAPACITY};
98    /// let ary: SmallArray<i32> = SmallArray::new();
99    /// assert!(ary.is_empty());
100    /// assert_eq!(ary.capacity(), INLINE_CAPACITY);
101    /// ```
102    #[inline]
103    #[must_use]
104    pub fn new() -> Self {
105        Self(SmallVec::new())
106    }
107
108    /// Construct a new, empty `SmallArray<T>` with the specified capacity.
109    ///
110    /// The vector will be able to hold `max(capacity, INLINE_CAPACITY)`
111    /// elements without reallocating. If `capacity` is less than or equal to
112    /// [`INLINE_CAPACITY`], the vector will not allocate.
113    ///
114    /// It is important to note that although the returned vector has the
115    /// _capacity_ specified, the vector will have a zero _length_.
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// # use spinoso_array::SmallArray;
121    /// let mut ary: SmallArray<i32> = SmallArray::with_capacity(10);
122    /// assert_eq!(ary.len(), 0);
123    /// assert_eq!(ary.capacity(), 10);
124    ///
125    /// // These are pushes all done without reallocating...
126    /// for i in 0..10 {
127    ///     ary.push(i);
128    /// }
129    ///
130    /// // ...but this may make the vector reallocate
131    /// ary.push(11);
132    /// ```
133    #[inline]
134    #[must_use]
135    pub fn with_capacity(capacity: usize) -> Self {
136        Self(SmallVec::with_capacity(capacity))
137    }
138
139    /// Construct a new two-element `SmallArray` from the given arguments.
140    ///
141    /// The vector is constructed without a heap allocation.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use spinoso_array::{SmallArray, INLINE_CAPACITY};
147    /// let ary = SmallArray::assoc(0, 100);
148    /// assert_eq!(ary.capacity(), INLINE_CAPACITY);
149    /// assert_eq!(ary.len(), 2);
150    /// assert_eq!(ary[0], 0);
151    /// assert_eq!(ary[1], 100);
152    /// ```
153    #[inline]
154    #[must_use]
155    pub fn assoc(first: T, second: T) -> Self {
156        let pair: [T; 2] = [first, second];
157        Self::from(pair)
158    }
159
160    /// Returns an iterator over the slice.
161    ///
162    /// # Examples
163    ///
164    /// ```
165    /// # use spinoso_array::SmallArray;
166    /// let ary = SmallArray::from(&[1, 2, 4]);
167    /// let mut iterator = ary.iter();
168    ///
169    /// assert_eq!(iterator.next(), Some(&1));
170    /// assert_eq!(iterator.next(), Some(&2));
171    /// assert_eq!(iterator.next(), Some(&4));
172    /// assert_eq!(iterator.next(), None);
173    /// ```
174    #[inline]
175    pub fn iter(&self) -> Iter<'_, T> {
176        self.into_iter()
177    }
178
179    /// Returns an iterator that allows modifying each value.
180    ///
181    /// # Examples
182    ///
183    /// ```
184    /// # use spinoso_array::SmallArray;
185    /// let mut ary = SmallArray::from(&[1, 2, 4]);
186    /// for elem in ary.iter_mut() {
187    ///     *elem += 2;
188    /// }
189    ///
190    /// assert_eq!(ary, &[3, 4, 6]);
191    /// ```
192    #[inline]
193    pub fn iter_mut(&mut self) -> IterMut<'_, T> {
194        self.into_iter()
195    }
196
197    /// Extracts a slice containing the entire vector.
198    ///
199    /// Equivalent to `&ary[..]`.
200    ///
201    /// # Examples
202    ///
203    /// ```
204    /// # use spinoso_array::SmallArray;
205    /// let ary = SmallArray::from(&[1, 2, 4]);
206    /// let four_index = ary.as_slice().binary_search(&4);
207    /// assert_eq!(four_index, Ok(2));
208    /// ```
209    #[inline]
210    #[must_use]
211    pub fn as_slice(&self) -> &[T] {
212        self.0.as_slice()
213    }
214
215    /// Extracts a mutable slice containing the entire vector.
216    ///
217    /// Equivalent to `&mut ary[..]`.
218    ///
219    /// # Examples
220    ///
221    /// ```
222    /// # use spinoso_array::SmallArray;
223    /// let mut ary = SmallArray::from(&[2, 1, 4]);
224    /// ary.as_mut_slice().sort();
225    /// assert_eq!(ary, &[1, 2, 4]);
226    /// ```
227    #[inline]
228    #[must_use]
229    pub fn as_mut_slice(&mut self) -> &mut [T] {
230        self.0.as_mut_slice()
231    }
232
233    /// Returns a raw pointer to the vector's buffer.
234    ///
235    /// The caller must ensure that the vector outlives the pointer this
236    /// function returns, or else it will end up pointing to garbage. Modifying
237    /// the vector may cause its buffer to be reallocated, which would also make
238    /// any pointers to it invalid.
239    ///
240    /// The caller must also ensure that the memory the pointer
241    /// (non-transitively) points to is never written to (except inside an
242    /// `UnsafeCell`) using this pointer or any pointer derived from it. If you
243    /// need to mutate the contents of the slice, use
244    /// [`as_mut_ptr`](Self::as_mut_ptr).
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// # use spinoso_array::SmallArray;
250    /// let ary = SmallArray::from(&[1, 2, 4]);
251    /// let ary_ptr = ary.as_ptr();
252    ///
253    /// unsafe {
254    ///     for i in 0..ary.len() {
255    ///         assert_eq!(*ary_ptr.add(i), 1 << i);
256    ///     }
257    /// }
258    /// ```
259    #[inline]
260    #[must_use]
261    pub fn as_ptr(&self) -> *const T {
262        self.0.as_ptr()
263    }
264
265    /// Returns an unsafe mutable pointer to the vector's buffer.
266    ///
267    /// The caller must ensure that the vector outlives the pointer this
268    /// function returns, or else it will end up pointing to garbage.
269    /// Modifying the vector may cause its buffer to be reallocated, which would
270    /// also make any pointers to it invalid.
271    ///
272    /// # Examples
273    ///
274    /// This method is primarily used when mutating a `Array` via a raw pointer
275    /// passed over FFI.
276    ///
277    /// See the [`ARY_PTR`] macro in mruby.
278    ///
279    /// [`ARY_PTR`]: https://github.com/artichoke/mruby/blob/d66440864d08f1c3ac5820d45f11df031b7d43c6/include/mruby/array.h#L52
280    #[inline]
281    #[must_use]
282    pub fn as_mut_ptr(&mut self) -> *mut T {
283        self.0.as_mut_ptr()
284    }
285
286    /// Set the vector's length without dropping or moving out elements
287    ///
288    /// This method is unsafe because it changes the notion of the number of
289    /// "valid" elements in the vector. Use with care.
290    ///
291    /// # Safety
292    ///
293    /// - `new_len` must be less than or equal to `capacity()`.
294    /// - The elements at `old_len..new_len` must be initialized.
295    ///
296    /// # Examples
297    ///
298    /// This method is primarily used when mutating a `Array` via a raw pointer
299    /// passed over FFI.
300    ///
301    /// See the [`ARY_PTR`] macro in mruby.
302    ///
303    /// [`ARY_PTR`]: https://github.com/artichoke/mruby/blob/d66440864d08f1c3ac5820d45f11df031b7d43c6/include/mruby/array.h#L52
304    #[inline]
305    pub unsafe fn set_len(&mut self, new_len: usize) {
306        // SAFETY: The caller must uphold the documented safety contract, which
307        // is the same as each array's inner buffer.
308        unsafe {
309            self.0.set_len(new_len);
310        }
311    }
312
313    /// Consume the array and return the inner
314    /// [`SmallVec<[T; INLINE_CAPACITY]>`](SmallVec).
315    ///
316    /// # Examples
317    ///
318    /// ```
319    /// # use smallvec::SmallVec;
320    /// use spinoso_array::{SmallArray, INLINE_CAPACITY};
321    /// let ary = SmallArray::from(&[1, 2, 4]);
322    /// let vec: SmallVec<[i32; INLINE_CAPACITY]> = ary.into_inner();
323    /// ```
324    #[inline]
325    #[must_use]
326    pub fn into_inner(self) -> SmallVec<[T; INLINE_CAPACITY]> {
327        self.0
328    }
329
330    /// Consume the array and return its elements as a [`Vec<T>`].
331    ///
332    /// For `SmallArray`s with `len() > INLINE_CAPACITY`, this is a cheap
333    /// operation that unwraps the spilled `Vec` from the `SmallVec`. For
334    /// shorter arrays, this method will allocate.
335    ///
336    /// # Examples
337    ///
338    /// ```
339    /// # use spinoso_array::SmallArray;
340    /// let ary = SmallArray::from(&[1, 2, 4]);
341    /// let vec: Vec<i32> = ary.into_vec();
342    /// ```
343    ///
344    /// [`Vec<T>`]: alloc::vec::Vec
345    #[inline]
346    #[must_use]
347    pub fn into_vec(self) -> Vec<T> {
348        self.0.into_vec()
349    }
350
351    /// Converts the vector into [`Box<[T]>`](Box).
352    ///
353    /// This will drop any excess capacity.
354    ///
355    /// # Examples
356    ///
357    /// ```
358    /// # use spinoso_array::SmallArray;
359    /// let ary = SmallArray::from(&[1, 2, 4]);
360    /// let slice: Box<[i32]> = ary.into_boxed_slice();
361    /// ```
362    #[inline]
363    #[must_use]
364    pub fn into_boxed_slice(self) -> Box<[T]> {
365        self.0.into_boxed_slice()
366    }
367
368    /// Returns the number of elements the vector can hold without reallocating.
369    ///
370    /// The minimum capacity of a `SmallArray` is [`INLINE_CAPACITY`].
371    /// `SmallArray`s with capacity less than or equal to `INLINE_CAPACITY` are
372    /// not allocated on the heap.
373    ///
374    /// # Examples
375    ///
376    /// ```
377    /// use spinoso_array::{SmallArray, INLINE_CAPACITY};
378    /// let ary: SmallArray<i32> = SmallArray::with_capacity(1);
379    /// assert_eq!(ary.capacity(), INLINE_CAPACITY);
380    ///
381    /// let ary: SmallArray<i32> = SmallArray::with_capacity(10);
382    /// assert_eq!(ary.capacity(), 10);
383    /// ```
384    #[inline]
385    #[must_use]
386    pub fn capacity(&self) -> usize {
387        self.0.capacity()
388    }
389
390    /// Reserves capacity for at least `additional` more elements to be inserted
391    /// in the given `SmallArray<T>`. The collection may reserve more space to
392    /// avoid frequent reallocations. After calling reserve, capacity will be
393    /// greater than or equal to `self.len() + additional`. Does nothing if
394    /// capacity is already sufficient.
395    ///
396    /// # Panics
397    ///
398    /// Panics if the new capacity overflows `usize`.
399    ///
400    /// # Examples
401    ///
402    /// ```
403    /// # use spinoso_array::SmallArray;
404    /// let mut ary = SmallArray::from(&[1]);
405    /// ary.reserve(10);
406    /// assert!(ary.capacity() >= 11);
407    /// ```
408    #[inline]
409    pub fn reserve(&mut self, additional: usize) {
410        self.0.reserve(additional);
411    }
412
413    /// Shrinks the capacity of the vector as much as possible.
414    ///
415    /// It will drop down as close as possible to the length but the allocator
416    /// may still inform the vector that there is space for a few more elements.
417    ///
418    /// # Examples
419    ///
420    /// ```
421    /// # use spinoso_array::SmallArray;
422    /// let mut ary = SmallArray::with_capacity(10);
423    /// ary.extend([1, 2, 3].iter().copied());
424    /// assert_eq!(ary.capacity(), 10);
425    /// ary.shrink_to_fit();
426    /// assert!(ary.capacity() >= 3);
427    /// ```
428    #[inline]
429    pub fn shrink_to_fit(&mut self) {
430        self.0.shrink_to_fit();
431    }
432
433    /// Clears the vector, removing all values.
434    ///
435    /// Note that this method has no effect on the allocated capacity of the
436    /// vector.
437    ///
438    /// # Examples
439    ///
440    /// ```
441    /// # use spinoso_array::SmallArray;
442    /// let mut ary = SmallArray::from(&[1, 2, 4]);
443    /// let capacity = ary.capacity();
444    /// ary.clear();
445    /// assert!(ary.is_empty());
446    /// assert_eq!(ary.capacity(), capacity);
447    /// ```
448    #[inline]
449    pub fn clear(&mut self) {
450        self.0.clear();
451    }
452
453    /// Returns the number of elements in the vector, also referred to as its
454    /// "length".
455    ///
456    /// # Examples
457    ///
458    /// ```
459    /// # use spinoso_array::SmallArray;
460    /// let ary = SmallArray::from(&[1, 2, 4]);
461    /// assert_eq!(ary.len(), 3);
462    /// ```
463    #[inline]
464    #[must_use]
465    pub fn len(&self) -> usize {
466        self.0.len()
467    }
468
469    /// Returns `true` if the vector contains no elements.
470    ///
471    /// # Examples
472    ///
473    /// ```
474    /// use spinoso_array::SmallArray;
475    /// let mut ary = SmallArray::new();
476    /// assert!(ary.is_empty());
477    /// ary.push(1);
478    /// assert!(!ary.is_empty());
479    /// ```
480    #[inline]
481    #[must_use]
482    pub fn is_empty(&self) -> bool {
483        self.0.is_empty()
484    }
485
486    /// Returns a reference to an element at the index.
487    ///
488    /// Unlike [`Vec`], this method does not support indexing with a range.  See
489    /// the [`slice`](Self::slice) method for retrieving a sub-slice from the
490    /// array.
491    ///
492    /// # Examples
493    ///
494    /// ```
495    /// # use spinoso_array::SmallArray;
496    /// let ary = SmallArray::from(&[1, 2, 4]);
497    /// assert_eq!(ary.get(1), Some(&2));
498    /// assert_eq!(ary.get(3), None);
499    /// ```
500    #[inline]
501    #[must_use]
502    pub fn get(&self, index: usize) -> Option<&T> {
503        self.0.get(index)
504    }
505
506    /// Deletes the element at the specified `index`, returning that element, or
507    /// [`None`] if the `index` is out of range.
508    ///
509    /// # Examples
510    ///
511    /// ```
512    /// # use spinoso_array::SmallArray;
513    /// let mut ary = SmallArray::from(&[1, 2, 4]);
514    /// assert_eq!(ary.delete_at(1), Some(2));
515    /// assert_eq!(ary.delete_at(10), None);
516    /// ```
517    #[inline]
518    #[must_use]
519    pub fn delete_at(&mut self, index: usize) -> Option<T> {
520        if index < self.0.len() {
521            Some(self.0.remove(index))
522        } else {
523            None
524        }
525    }
526
527    /// Returns the first element from the vector, or [`None`] if the vector is
528    /// empty.
529    ///
530    /// To retrieve a slice of the first elements in the vector, use
531    /// [`first_n`](Self::first_n).
532    ///
533    /// # Examples
534    ///
535    /// ```
536    /// # use spinoso_array::SmallArray;
537    /// let mut ary = SmallArray::new();
538    /// assert_eq!(ary.first(), None);
539    /// ary.push(1);
540    /// assert_eq!(ary.first(), Some(&1));
541    /// ary.push(2);
542    /// assert_eq!(ary.first(), Some(&1));
543    /// ```
544    #[inline]
545    #[must_use]
546    pub fn first(&self) -> Option<&T> {
547        self.0.first()
548    }
549
550    /// Returns up to `n` of the first elements from the vector, or `&[]` if the
551    /// vector is empty.
552    ///
553    /// To retrieve only the first element in the vector, use
554    /// [`first`](Self::first).
555    ///
556    /// # Examples
557    ///
558    /// ```
559    /// # use spinoso_array::SmallArray;
560    /// let mut ary = SmallArray::new();
561    /// assert_eq!(ary.first_n(0), &[]);
562    /// assert_eq!(ary.first_n(4), &[]);
563    ///
564    /// ary.push(1);
565    /// ary.push(2);
566    /// assert_eq!(ary.first_n(0), &[]);
567    /// assert_eq!(ary.first_n(4), &[1, 2]);
568    ///
569    /// ary.concat(&[3, 4, 5, 6, 7, 8, 9, 10]);
570    /// assert_eq!(ary.first_n(0), &[]);
571    /// assert_eq!(ary.first_n(4), &[1, 2, 3, 4]);
572    /// ```
573    #[inline]
574    #[must_use]
575    pub fn first_n(&self, n: usize) -> &[T] {
576        self.0.get(..n).unwrap_or_else(|| &self.0[..])
577    }
578
579    /// Returns the last element from the vector, or [`None`] if the vector is
580    /// empty.
581    ///
582    /// To retrieve a slice of the last elements in the vector, use
583    /// [`last_n`](Self::last_n).
584    ///
585    /// # Examples
586    ///
587    /// ```
588    /// # use spinoso_array::SmallArray;
589    /// let mut ary = SmallArray::new();
590    /// assert_eq!(ary.last(), None);
591    /// ary.push(1);
592    /// assert_eq!(ary.last(), Some(&1));
593    /// ary.push(2);
594    /// assert_eq!(ary.last(), Some(&2));
595    /// ```
596    #[inline]
597    #[must_use]
598    pub fn last(&self) -> Option<&T> {
599        self.0.last()
600    }
601
602    /// Returns up to `n` of the last elements from the vector, or `&[]` if the
603    /// vector is empty.
604    ///
605    /// To retrieve only the last element in the vector, use
606    /// [`last`](Self::last).
607    ///
608    /// # Examples
609    ///
610    /// ```
611    /// # use spinoso_array::SmallArray;
612    /// let mut ary = SmallArray::new();
613    /// assert_eq!(ary.last_n(0), &[]);
614    /// assert_eq!(ary.last_n(4), &[]);
615    ///
616    /// ary.push(1);
617    /// ary.push(2);
618    /// assert_eq!(ary.last_n(0), &[]);
619    /// assert_eq!(ary.last_n(4), &[1, 2]);
620    ///
621    /// ary.concat(&[3, 4, 5, 6, 7, 8, 9, 10]);
622    /// assert_eq!(ary.last_n(0), &[]);
623    /// assert_eq!(ary.last_n(4), &[7, 8, 9, 10]);
624    /// ```
625    #[inline]
626    #[must_use]
627    pub fn last_n(&self, n: usize) -> &[T] {
628        let begin = self.len().checked_sub(n).unwrap_or_default();
629        &self.0[begin..]
630    }
631
632    /// Returns a slice of the underlying vector that includes only the first
633    /// `n` elements.
634    ///
635    /// If `n` is greater than or equal to the length of the vector, `&self[..]`
636    /// is returned.
637    ///
638    /// The inverse of this operation is [`drop_n`](Self::drop_n).
639    ///
640    /// # Examples
641    ///
642    /// ```
643    /// # use spinoso_array::SmallArray;
644    /// let ary = SmallArray::from(&[1, 2, 4, 7, 8, 9]);
645    /// assert_eq!(ary.take_n(0), &[]);
646    /// assert_eq!(ary.take_n(2), &[1, 2]);
647    /// assert_eq!(ary.take_n(10), &[1, 2, 4, 7, 8, 9]);
648    /// ```
649    #[inline]
650    #[must_use]
651    pub fn take_n(&self, n: usize) -> &[T] {
652        self.0.get(..n).unwrap_or_else(|| &self.0[..])
653    }
654
655    /// Returns a slice of the underlying vector that excludes the first `n`
656    /// elements.
657    ///
658    /// If `n` is greater than or equal to the length of the vector, `&[]` is
659    /// returned.
660    ///
661    /// The inverse of this operation is [`take_n`](Self::take_n).
662    ///
663    /// # Examples
664    ///
665    /// ```
666    /// # use spinoso_array::SmallArray;
667    /// let ary = SmallArray::from(&[1, 2, 4, 7, 8, 9]);
668    /// assert_eq!(ary.drop_n(0), &[1, 2, 4, 7, 8, 9]);
669    /// assert_eq!(ary.drop_n(4), &[8, 9]);
670    /// assert_eq!(ary.drop_n(10), &[]);
671    /// ```
672    #[inline]
673    #[must_use]
674    pub fn drop_n(&self, n: usize) -> &[T] {
675        self.0.get(n..).unwrap_or_default()
676    }
677
678    /// Removes the last element from the vector and returns it, or [`None`] if
679    /// the vector is empty.
680    ///
681    /// To pop more than one element from the end of the vector, use
682    /// [`pop_n`](Self::pop_n).
683    ///
684    /// # Examples
685    ///
686    /// ```
687    /// # use spinoso_array::SmallArray;
688    /// let mut ary = SmallArray::from(&[1, 2, 4]);
689    /// assert_eq!(ary.pop(), Some(4));
690    /// assert_eq!(ary, &[1, 2]);
691    /// ```
692    #[inline]
693    #[must_use]
694    pub fn pop(&mut self) -> Option<T> {
695        self.0.pop()
696    }
697
698    /// Removes the last `n` elements from the vector.
699    ///
700    /// To pop a single element from the end of the vector, use
701    /// [`pop`](Self::pop).
702    ///
703    /// # Examples
704    ///
705    /// ```
706    /// # use spinoso_array::SmallArray;
707    /// let mut ary = SmallArray::from(&[1, 2, 4, 7, 8, 9]);
708    /// assert_eq!(ary.pop_n(0), &[]);
709    /// assert_eq!(ary, &[1, 2, 4, 7, 8, 9]);
710    ///
711    /// assert_eq!(ary.pop_n(3), &[7, 8, 9]);
712    /// assert_eq!(ary, &[1, 2, 4]);
713    ///
714    /// assert_eq!(ary.pop_n(100), &[1, 2, 4]);
715    /// assert!(ary.is_empty());
716    ///
717    /// assert_eq!(ary.pop_n(1), &[]);
718    /// assert!(ary.is_empty());
719    /// ```
720    #[inline]
721    #[must_use]
722    pub fn pop_n(&mut self, n: usize) -> Self {
723        if n == 0 {
724            return Self::new();
725        }
726        let begin = self.len().checked_sub(n).unwrap_or_default();
727        self.0.drain(begin..).collect()
728    }
729
730    /// Appends an element to the back of the vector.
731    ///
732    /// To push more than one element to the end of the vector, use
733    /// [`concat`](Self::concat) or `extend`.
734    ///
735    /// # Panics
736    ///
737    /// Panics if the number of elements in the vector overflows a `usize`.
738    ///
739    /// # Examples
740    ///
741    /// ```
742    /// # use spinoso_array::SmallArray;
743    /// let mut ary = SmallArray::from(&[1, 2]);
744    /// ary.push(3);
745    /// assert_eq!(ary, &[1, 2, 3]);
746    /// ```
747    #[inline]
748    pub fn push(&mut self, elem: T) {
749        self.0.push(elem);
750    }
751
752    /// Reverses the order of elements of the vector, in place.
753    ///
754    /// # Examples
755    ///
756    /// ```
757    /// # use spinoso_array::SmallArray;
758    /// let mut ary = SmallArray::from(&[1, 2, 4]);
759    /// ary.reverse();
760    /// assert_eq!(ary, &[4, 2, 1]);
761    /// ```
762    #[inline]
763    pub fn reverse(&mut self) {
764        self.0.reverse();
765    }
766
767    /// Removes the first element of the vector and returns it (shifting all
768    /// other elements down by one). Returns [`None`] if the vector is empty.
769    ///
770    /// This operation is also known as "pop front".
771    ///
772    /// To remove more than one element from the front of the vector, use
773    /// [`shift_n`](Self::shift_n).
774    ///
775    /// # Examples
776    ///
777    /// ```
778    /// # use spinoso_array::SmallArray;
779    /// let mut ary = SmallArray::from(&[1, 2]);
780    /// assert_eq!(ary.shift(), Some(1));
781    /// assert_eq!(ary.shift(), Some(2));
782    /// assert_eq!(ary.shift(), None);
783    /// ```
784    #[inline]
785    #[must_use]
786    pub fn shift(&mut self) -> Option<T> {
787        if self.is_empty() { None } else { Some(self.0.remove(0)) }
788    }
789
790    /// Removes the first `n` elements from the vector.
791    ///
792    /// To shift a single element from the front of the vector, use
793    /// [`shift`](Self::shift).
794    ///
795    /// # Examples
796    ///
797    /// ```
798    /// # use spinoso_array::SmallArray;
799    /// let mut ary = SmallArray::from(&[1, 2, 4, 7, 8, 9]);
800    /// assert_eq!(ary.shift_n(0), &[]);
801    /// assert_eq!(ary, &[1, 2, 4, 7, 8, 9]);
802    ///
803    /// assert_eq!(ary.shift_n(3), &[1, 2, 4]);
804    /// assert_eq!(ary, &[7, 8, 9]);
805    ///
806    /// assert_eq!(ary.shift_n(100), &[7, 8, 9]);
807    /// assert!(ary.is_empty());
808    ///
809    /// assert_eq!(ary.shift_n(1), &[]);
810    /// assert!(ary.is_empty());
811    /// ```
812    #[inline]
813    #[must_use]
814    pub fn shift_n(&mut self, n: usize) -> Self {
815        match n {
816            0 => Self::new(),
817            n if n < self.0.len() => self.0.drain(..n).collect(),
818            _ => self.0.drain(..).collect(),
819        }
820    }
821
822    /// Inserts an element to the front of the vector.
823    ///
824    /// To insert more than one element to the front of the vector, use
825    /// [`unshift_n`](Self::unshift_n).
826    ///
827    /// This operation is also known as "prepend".
828    ///
829    /// # Panics
830    ///
831    /// Panics if the number of elements in the vector overflows a `usize`.
832    ///
833    /// # Examples
834    ///
835    /// ```
836    /// # use spinoso_array::SmallArray;
837    /// let mut ary = SmallArray::from(&[1, 2]);
838    /// ary.unshift(3);
839    /// assert_eq!(ary, &[3, 1, 2]);
840    /// ```
841    #[inline]
842    pub fn unshift(&mut self, elem: T) {
843        self.0.insert(0, elem);
844    }
845
846    /// Return a reference to a subslice of the vector.
847    ///
848    /// This function always returns a slice. If the range specified by `start`
849    /// and `end` overlaps the vector (even if only partially), the overlapping
850    /// slice is returned. If the range does not overlap the vector, an empty
851    /// slice is returned.
852    ///
853    /// # Examples
854    ///
855    /// ```
856    /// # use spinoso_array::SmallArray;
857    /// let empty: SmallArray<i32> = SmallArray::new();
858    /// assert_eq!(empty.slice(0, 0), &[]);
859    /// assert_eq!(empty.slice(0, 4), &[]);
860    /// assert_eq!(empty.slice(2, 4), &[]);
861    ///
862    /// let ary = SmallArray::from(&[1, 2, 3]);
863    /// assert_eq!(ary.slice(0, 0), &[]);
864    /// assert_eq!(ary.slice(0, 4), &[1, 2, 3]);
865    /// assert_eq!(ary.slice(2, 0), &[]);
866    /// assert_eq!(ary.slice(2, 4), &[3]);
867    /// assert_eq!(ary.slice(10, 100), &[]);
868    /// ```
869    #[inline]
870    #[must_use]
871    pub fn slice(&self, start: usize, len: usize) -> &[T] {
872        if self.0.is_empty() || len == 0 {
873            return &[];
874        }
875        if let Some(end) = start.checked_add(len) {
876            self.0
877                .get(start..end)
878                .or_else(|| self.0.get(start..))
879                .unwrap_or_default()
880        } else {
881            self.0.get(start..).unwrap_or_default()
882        }
883    }
884}
885
886impl<T> SmallArray<T>
887where
888    T: Copy,
889{
890    /// Construct a new `SmallArray<T>` with length `len` and all elements set
891    /// to `default`. The `SmallArray` will have capacity at least `len`.
892    ///
893    /// # Examples
894    ///
895    /// ```
896    /// # use spinoso_array::SmallArray;
897    /// let ary: SmallArray<&str> = SmallArray::with_len_and_default(3, "spinoso");
898    /// assert_eq!(ary.len(), 3);
899    /// assert!(ary.capacity() >= 3);
900    /// assert_eq!(ary, &["spinoso", "spinoso", "spinoso"]);
901    /// ```
902    #[inline]
903    #[must_use]
904    pub fn with_len_and_default(len: usize, default: T) -> Self {
905        Self(SmallVec::from_elem(default, len))
906    }
907
908    /// Appends the elements of `other` to self.
909    ///
910    /// Slice version of `extend`. This operation is analogous to "push n".
911    ///
912    /// # Examples
913    ///
914    /// ```
915    /// # use spinoso_array::SmallArray;
916    /// let mut ary = SmallArray::from(&[1, 2, 4]);
917    /// ary.concat(&[7, 8, 9]);
918    /// assert_eq!(ary.len(), 6);
919    /// ```
920    #[inline]
921    pub fn concat(&mut self, other: &[T]) {
922        self.0.extend_from_slice(other);
923    }
924
925    /// Creates a new array by repeating this array `n` times.
926    ///
927    /// This function will not panic. If the resulting `Array`'s capacity would
928    /// overflow, [`None`] is returned.
929    ///
930    /// # Examples
931    ///
932    /// Basic usage:
933    ///
934    /// ```
935    /// # use spinoso_array::SmallArray;
936    /// # fn example() -> Option<()> {
937    /// let mut ary = SmallArray::from(&[1, 2]);
938    /// let repeated_ary = ary.repeat(3)?;
939    /// assert_eq!(repeated_ary, &[1, 2, 1, 2, 1, 2]);
940    /// # Some(())
941    /// # }
942    /// # example().unwrap();
943    /// ```
944    ///
945    /// [`None`] should be returned on overflow:
946    ///
947    /// ```
948    /// # use spinoso_array::SmallArray;
949    /// let mut ary = SmallArray::from(&[1, 2]);
950    /// let repeated_ary = ary.repeat(usize::MAX);
951    /// assert_eq!(repeated_ary, None);
952    /// ```
953    #[must_use]
954    pub fn repeat(&self, n: usize) -> Option<Self> {
955        let slice = self.0.as_slice();
956        if slice.len().checked_mul(n).is_some() {
957            Some(Self::from(slice.repeat(n)))
958        } else {
959            None
960        }
961    }
962
963    /// Prepends the elements of `other` to self.
964    ///
965    /// To insert one element to the front of the vector, use
966    /// [`unshift`](Self::unshift).
967    ///
968    /// This operation is also known as "prepend".
969    ///
970    /// # Panics
971    ///
972    /// Panics if the number of elements in the vector overflows a `usize`.
973    ///
974    /// # Examples
975    ///
976    /// ```
977    /// # use spinoso_array::SmallArray;
978    /// let mut ary = SmallArray::from(&[1, 2]);
979    /// ary.unshift_n(&[0, 5, 9]);
980    /// assert_eq!(ary, &[0, 5, 9, 1, 2]);
981    /// ```
982    #[inline]
983    pub fn unshift_n(&mut self, other: &[T]) {
984        self.0.reserve(other.len());
985        self.0.insert_from_slice(0, other);
986    }
987}
988
989impl<T> SmallArray<T>
990where
991    T: Default,
992{
993    /// Set element at position `index` within the vector, extending the vector
994    /// with `T::default()` if `index` is out of bounds.
995    ///
996    /// # Panics
997    ///
998    /// If inserting the element would overflow the capacity of the vector, this
999    /// method will panic.
1000    ///
1001    /// # Examples
1002    ///
1003    /// ```
1004    /// # use spinoso_array::SmallArray;
1005    /// let mut ary = SmallArray::from(&[1, 2, 4]);
1006    /// ary.set(1, 11);
1007    /// assert_eq!(ary, &[1, 11, 4]);
1008    /// ary.set(5, 263);
1009    /// assert_eq!(ary, &[1, 11, 4, 0, 0, 263]);
1010    ///
1011    /// let mut ary: SmallArray<i32> = SmallArray::from(&[]);
1012    /// ary.set(5, 11);
1013    /// assert_eq!(ary, &[0, 0, 0, 0, 0, 11]);
1014    /// ```
1015    #[inline]
1016    pub fn set(&mut self, index: usize, elem: T) {
1017        if let Some(cell) = self.0.get_mut(index) {
1018            *cell = elem;
1019        } else {
1020            let buflen = self.len();
1021            // index is *at least* `buflen`, so this calculation never underflows
1022            // and ensures we allocate an additional slot.
1023            let additional = (index - buflen).checked_add(1).expect("capacity overflow");
1024            self.0.reserve(additional);
1025            self.0.resize_with(index, T::default);
1026            self.0.push(elem);
1027        }
1028    }
1029
1030    /// Insert element at position `start` within the vector and remove the
1031    /// following `drain` elements. If `start` is out of bounds, the vector will
1032    /// be extended with `T::default()`.
1033    ///
1034    /// This method sets a slice of the `SmallArray` to a single element,
1035    /// including the zero-length slice. It is similar in intent to calling
1036    /// [`Vec::splice`] with a one-element iterator.
1037    ///
1038    /// `set_with_drain` will only drain up to the end of the vector.
1039    ///
1040    /// To set a single element without draining, use [`set`](Self::set).
1041    ///
1042    /// # Panics
1043    ///
1044    /// If inserting the element would overflow the capacity of the vector, this
1045    /// method will panic.
1046    ///
1047    /// # Examples
1048    ///
1049    /// ```
1050    /// # use spinoso_array::SmallArray;
1051    /// let mut ary = SmallArray::from(&[1, 2, 4]);
1052    /// ary.set_with_drain(1, 0, 10);
1053    /// assert_eq!(ary, &[1, 10, 2, 4]);
1054    /// ary.set_with_drain(2, 5, 20);
1055    /// assert_eq!(ary, &[1, 10, 20]);
1056    /// ary.set_with_drain(5, 5, 30);
1057    /// assert_eq!(ary, &[1, 10, 20, 0, 0, 30]);
1058    /// ```
1059    #[inline]
1060    pub fn set_with_drain(&mut self, start: usize, drain: usize, elem: T) -> usize {
1061        let buflen = self.0.len();
1062        let drained = cmp::min(buflen.checked_sub(start).unwrap_or_default(), drain);
1063
1064        if let Some(cell) = self.0.get_mut(start) {
1065            match drain {
1066                0 => self.0.insert(start, elem),
1067                1 => *cell = elem,
1068                _ => {
1069                    *cell = elem;
1070                    let drain_end_idx = cmp::min(start.saturating_add(drain), buflen);
1071                    self.0.drain(start.saturating_add(1)..drain_end_idx);
1072                }
1073            }
1074        } else {
1075            // start is *at least* `buflen`, so this calculation never underflows
1076            // and ensures we allocate an additional slot.
1077            let additional = (start - buflen).checked_add(1).expect("capacity overflow");
1078            self.0.reserve(additional);
1079            self.0.resize_with(start, T::default);
1080            self.0.push(elem);
1081        }
1082
1083        drained
1084    }
1085}
1086
1087impl<T> SmallArray<T>
1088where
1089    T: Default + Copy,
1090{
1091    /// Insert the elements from a slice at a position `index` in the vector,
1092    /// extending the vector with `T::default()` if `index` is out of bounds.
1093    ///
1094    /// This method is similar to [`Vec::splice`] when called with a zero-length
1095    /// range.
1096    ///
1097    /// # Panics
1098    ///
1099    /// If inserting the slice would overflow the capacity of the vector, this
1100    /// method will panic.
1101    ///
1102    /// # Examples
1103    ///
1104    /// ```
1105    /// # use spinoso_array::SmallArray;
1106    /// let mut ary = SmallArray::from(&[1, 2, 4]);
1107    /// ary.insert_slice(1, &[7, 8, 9]);
1108    /// assert_eq!(ary, &[1, 7, 8, 9, 2, 4]);
1109    /// ary.insert_slice(8, &[100, 200]);
1110    /// assert_eq!(ary, &[1, 7, 8, 9, 2, 4, 0, 0, 100, 200]);
1111    /// ```
1112    #[inline]
1113    pub fn insert_slice(&mut self, index: usize, values: &[T]) {
1114        if let Some(overflow) = index.checked_sub(self.0.len()) {
1115            let additional = overflow.checked_add(values.len()).expect("capacity overflow");
1116            self.0.reserve(additional);
1117            self.0.resize_with(index, T::default);
1118        } else {
1119            self.0.reserve(values.len());
1120        }
1121
1122        self.0.insert_from_slice(index, values);
1123    }
1124
1125    /// Insert the elements from a slice at a position `index` in the vector and
1126    /// remove the following `drain` elements. The vector is extended with
1127    /// `T::default()` if `index` is out of bounds.
1128    ///
1129    /// This method is similar to [`Vec::splice`] when called with a
1130    /// nonzero-length range.
1131    ///
1132    /// When called with `drain == 0`, this method is equivalent to
1133    /// [`insert_slice`](Self::insert_slice).
1134    ///
1135    /// If `drain >= src.len()` or the tail of the vector is replaced, this
1136    /// method is efficient. Otherwise, a temporary buffer is used to move the
1137    /// elements.
1138    ///
1139    /// # Panics
1140    ///
1141    /// If inserting the slice would overflow the capacity of the vector, this
1142    /// method will panic.
1143    ///
1144    /// # Examples
1145    ///
1146    /// ```
1147    /// # use spinoso_array::SmallArray;
1148    /// let mut ary = SmallArray::from(&[1, 2, 4]);
1149    /// ary.set_slice(1, 5, &[7, 8, 9]);
1150    /// assert_eq!(ary, &[1, 7, 8, 9]);
1151    /// ary.set_slice(6, 1, &[100, 200]);
1152    /// assert_eq!(ary, &[1, 7, 8, 9, 0, 0, 100, 200]);
1153    /// ary.set_slice(4, 2, &[88, 99]);
1154    /// assert_eq!(ary, &[1, 7, 8, 9, 88, 99, 100, 200]);
1155    /// ary.set_slice(6, 2, &[1000, 2000, 3000, 4000]);
1156    /// assert_eq!(ary, &[1, 7, 8, 9, 88, 99, 1000, 2000, 3000, 4000]);
1157    /// ```
1158    #[inline]
1159    pub fn set_slice(&mut self, index: usize, drain: usize, values: &[T]) -> usize {
1160        if let Some(overflow) = index.checked_sub(self.0.len()) {
1161            let additional = overflow.saturating_add(values.len());
1162            self.0.reserve(additional);
1163            self.0.resize_with(index, T::default);
1164        }
1165        // `self.len()` is at least `index` so the below sub can never overflow.
1166        let tail = self.len() - index;
1167        // This is a direct append to the end of the vector, either because the
1168        // given `index` was the vector's length or because we have extended the
1169        // vector from an out of bounds index.
1170        if tail == 0 {
1171            self.0.extend_from_slice(values);
1172            return 0;
1173        }
1174        // If the tail of the vector is shorter than or as long as the number of
1175        // elements to drain, we can truncate and extend the underlying vector.
1176        // `truncate` does not affect the existing capacity of the vector.
1177        if tail <= drain {
1178            self.0.truncate(index);
1179            self.0.extend_from_slice(values);
1180            return tail;
1181        }
1182
1183        // Short circuit to a direct insert if `drain == 0`.
1184        if drain == 0 {
1185            self.0.insert_from_slice(index, values);
1186            return 0;
1187        }
1188
1189        // At this point, `index + drain` is guaranteed to be a valid index
1190        // within the vector. There are two cases:
1191        //
1192        // - If `values.len() == drain`, we can drain elements by overwriting
1193        //   them in the vector.
1194        // - If `values.len() >= drain`, we can drain elements by overwriting
1195        //   them in the vector and inserting the remainder.
1196        // - Otherwise, overwrite `values` into the vector and remove the
1197        //   remaining elements we must drain.
1198        match values.len() {
1199            0 => {
1200                self.0.drain(index..index + drain);
1201            }
1202            len if len == drain => {
1203                let slice = &mut self.0[index..index + drain];
1204                slice.copy_from_slice(values);
1205            }
1206            len if len > drain => {
1207                let slice = &mut self.0[index..index + drain];
1208                let (overwrite, insert) = values.split_at(drain);
1209                slice.copy_from_slice(overwrite);
1210                self.0.insert_from_slice(index + drain, insert);
1211            }
1212            len => {
1213                let slice = &mut self.0[index..index + len];
1214                slice.copy_from_slice(values);
1215                // Drain the remaining elements.
1216                self.0.drain(index + len..index + drain);
1217            }
1218        }
1219
1220        drain
1221    }
1222}
1223
1224#[cfg(test)]
1225mod test {
1226    use crate::array::smallvec::SmallArray;
1227
1228    // `insert_slice`
1229
1230    #[test]
1231    fn non_empty_array_insert_slice_end_empty() {
1232        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1233        ary.insert_slice(5, &[]);
1234        assert_eq!(ary, [1, 2, 3, 4, 5]);
1235    }
1236
1237    #[test]
1238    fn non_empty_array_insert_slice_out_of_bounds_empty() {
1239        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1240        ary.insert_slice(10, &[]);
1241        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]);
1242    }
1243
1244    #[test]
1245    fn non_empty_array_insert_slice_interior_empty() {
1246        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1247        ary.insert_slice(2, &[]);
1248        assert_eq!(ary, [1, 2, 3, 4, 5]);
1249    }
1250
1251    #[test]
1252    fn non_empty_array_insert_slice_begin_empty() {
1253        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1254        ary.insert_slice(0, &[]);
1255        assert_eq!(ary, [1, 2, 3, 4, 5]);
1256    }
1257
1258    #[test]
1259    fn empty_array_insert_slice_end_empty() {
1260        let mut ary = SmallArray::<i32>::new();
1261        ary.insert_slice(0, &[]);
1262        assert_eq!(ary, []);
1263    }
1264
1265    #[test]
1266    fn empty_array_insert_slice_out_of_bounds_empty() {
1267        let mut ary = SmallArray::<i32>::new();
1268        ary.insert_slice(10, &[]);
1269        assert_eq!(ary, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
1270    }
1271
1272    #[test]
1273    fn empty_array_insert_slice_begin_empty() {
1274        let mut ary = SmallArray::<i32>::new();
1275        ary.insert_slice(0, &[]);
1276        assert_eq!(ary, []);
1277    }
1278
1279    #[test]
1280    fn non_empty_array_insert_slice_end() {
1281        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1282        ary.insert_slice(5, &[8, 9, 10]);
1283        assert_eq!(ary, [1, 2, 3, 4, 5, 8, 9, 10]);
1284    }
1285
1286    #[test]
1287    fn non_empty_array_insert_slice_out_of_bounds() {
1288        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1289        ary.insert_slice(10, &[8, 9, 10]);
1290        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 8, 9, 10]);
1291    }
1292
1293    #[test]
1294    fn non_empty_array_insert_slice_interior() {
1295        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1296        ary.insert_slice(2, &[8, 9, 10]);
1297        assert_eq!(ary, [1, 2, 8, 9, 10, 3, 4, 5]);
1298    }
1299
1300    #[test]
1301    fn non_empty_array_insert_slice_begin() {
1302        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1303        ary.insert_slice(0, &[8, 9, 10]);
1304        assert_eq!(ary, [8, 9, 10, 1, 2, 3, 4, 5]);
1305    }
1306
1307    #[test]
1308    fn empty_array_insert_slice_end() {
1309        let mut ary = SmallArray::<i32>::new();
1310        ary.insert_slice(0, &[8, 9, 10]);
1311        assert_eq!(ary, [8, 9, 10]);
1312    }
1313
1314    #[test]
1315    fn empty_array_insert_slice_out_of_bounds() {
1316        let mut ary = SmallArray::<i32>::new();
1317        ary.insert_slice(10, &[8, 9, 10]);
1318        assert_eq!(ary, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10]);
1319    }
1320
1321    #[test]
1322    fn empty_array_insert_slice_begin() {
1323        let mut ary = SmallArray::<i32>::new();
1324        ary.insert_slice(0, &[8, 9, 10]);
1325        assert_eq!(ary, [8, 9, 10]);
1326    }
1327
1328    // `set_slice`
1329
1330    #[test]
1331    fn non_empty_array_set_slice_end_empty_drain_0() {
1332        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1333        let drained = ary.set_slice(5, 0, &[]);
1334        assert_eq!(drained, 0);
1335        assert_eq!(ary, [1, 2, 3, 4, 5]);
1336    }
1337
1338    #[test]
1339    fn non_empty_array_set_slice_end_empty_drain_less_than_insert_length() {
1340        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1341        let drained = ary.set_slice(5, 0, &[]);
1342        assert_eq!(drained, 0);
1343        assert_eq!(ary, [1, 2, 3, 4, 5]);
1344    }
1345
1346    #[test]
1347    fn non_empty_array_set_slice_end_empty_drain_equal_to_insert_length() {
1348        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1349        let drained = ary.set_slice(5, 0, &[]);
1350        assert_eq!(drained, 0);
1351        assert_eq!(ary, [1, 2, 3, 4, 5]);
1352    }
1353
1354    #[test]
1355    fn non_empty_array_set_slice_end_empty_drain_greater_than_insert_length() {
1356        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1357        let drained = ary.set_slice(5, 5, &[]);
1358        assert_eq!(drained, 0);
1359        assert_eq!(ary, [1, 2, 3, 4, 5]);
1360    }
1361
1362    #[test]
1363    fn non_empty_array_set_slice_out_of_bounds_empty_drain_0() {
1364        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1365        let drained = ary.set_slice(10, 0, &[]);
1366        assert_eq!(drained, 0);
1367        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]);
1368    }
1369
1370    #[test]
1371    fn non_empty_array_set_slice_out_of_bounds_empty_drain_less_than_insert_length() {
1372        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1373        let drained = ary.set_slice(10, 0, &[]);
1374        assert_eq!(drained, 0);
1375        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]);
1376    }
1377
1378    #[test]
1379    fn non_empty_array_set_slice_out_of_bounds_empty_drain_equal_to_insert_length() {
1380        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1381        let drained = ary.set_slice(10, 0, &[]);
1382        assert_eq!(drained, 0);
1383        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]);
1384    }
1385
1386    #[test]
1387    fn non_empty_array_set_slice_out_of_bounds_empty_drain_greater_than_insert_length() {
1388        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1389        let drained = ary.set_slice(10, 0, &[]);
1390        assert_eq!(drained, 0);
1391        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]);
1392    }
1393
1394    #[test]
1395    fn non_empty_array_set_slice_interior_empty_drain_0() {
1396        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1397        let drained = ary.set_slice(1, 0, &[]);
1398        assert_eq!(drained, 0);
1399        assert_eq!(ary, [1, 2, 3, 4, 5]);
1400    }
1401
1402    #[test]
1403    fn non_empty_array_set_slice_interior_empty_drain_less_than_insert_length() {
1404        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1405        let drained = ary.set_slice(1, 0, &[]);
1406        assert_eq!(drained, 0);
1407        assert_eq!(ary, [1, 2, 3, 4, 5]);
1408    }
1409
1410    #[test]
1411    fn non_empty_array_set_slice_interior_empty_drain_equal_to_insert_length() {
1412        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1413        let drained = ary.set_slice(1, 0, &[]);
1414        assert_eq!(drained, 0);
1415        assert_eq!(ary, [1, 2, 3, 4, 5]);
1416    }
1417
1418    #[test]
1419    fn non_empty_array_set_slice_interior_empty_drain_greater_than_insert_length() {
1420        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1421        let drained = ary.set_slice(1, 2, &[]);
1422        assert_eq!(drained, 2);
1423        assert_eq!(ary, [1, 4, 5]);
1424    }
1425
1426    #[test]
1427    fn non_empty_array_set_slice_interior_empty_drain_greater_than_insert_length_to_end() {
1428        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1429        let drained = ary.set_slice(1, 4, &[]);
1430        assert_eq!(drained, 4);
1431        assert_eq!(ary, [1]);
1432    }
1433
1434    #[test]
1435    fn non_empty_array_set_slice_interior_empty_drain_greater_than_insert_length_overrun_end() {
1436        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1437        let drained = ary.set_slice(1, 10, &[]);
1438        assert_eq!(drained, 4);
1439        assert_eq!(ary, [1]);
1440    }
1441
1442    #[test]
1443    fn non_empty_array_set_slice_end_non_empty_drain_0() {
1444        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1445        let drained = ary.set_slice(5, 0, &[7, 8, 9]);
1446        assert_eq!(drained, 0);
1447        assert_eq!(ary, [1, 2, 3, 4, 5, 7, 8, 9]);
1448    }
1449
1450    #[test]
1451    fn non_empty_array_set_slice_end_non_empty_drain_less_than_insert_length() {
1452        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1453        let drained = ary.set_slice(5, 2, &[7, 8, 9]);
1454        assert_eq!(drained, 0);
1455        assert_eq!(ary, [1, 2, 3, 4, 5, 7, 8, 9]);
1456    }
1457
1458    #[test]
1459    fn non_empty_array_set_slice_end_non_empty_drain_equal_to_insert_length() {
1460        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1461        let drained = ary.set_slice(5, 3, &[7, 8, 9]);
1462        assert_eq!(drained, 0);
1463        assert_eq!(ary, [1, 2, 3, 4, 5, 7, 8, 9]);
1464    }
1465
1466    #[test]
1467    fn non_empty_array_set_slice_end_non_empty_drain_greater_than_insert_length() {
1468        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1469        let drained = ary.set_slice(5, 5, &[7, 8, 9]);
1470        assert_eq!(drained, 0);
1471        assert_eq!(ary, [1, 2, 3, 4, 5, 7, 8, 9]);
1472    }
1473
1474    #[test]
1475    fn non_empty_array_set_slice_out_of_bounds_non_empty_drain_0() {
1476        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1477        let drained = ary.set_slice(10, 0, &[7, 8, 9]);
1478        assert_eq!(drained, 0);
1479        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 7, 8, 9]);
1480    }
1481
1482    #[test]
1483    fn non_empty_array_set_slice_out_of_bounds_non_empty_drain_less_than_insert_length() {
1484        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1485        let drained = ary.set_slice(10, 2, &[7, 8, 9]);
1486        assert_eq!(drained, 0);
1487        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 7, 8, 9]);
1488    }
1489
1490    #[test]
1491    fn non_empty_array_set_slice_out_of_bounds_non_empty_drain_equal_to_insert_length() {
1492        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1493        let drained = ary.set_slice(10, 3, &[7, 8, 9]);
1494        assert_eq!(drained, 0);
1495        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 7, 8, 9]);
1496    }
1497
1498    #[test]
1499    fn non_empty_array_set_slice_out_of_bounds_non_empty_drain_greater_than_insert_length() {
1500        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1501        let drained = ary.set_slice(10, 5, &[7, 8, 9]);
1502        assert_eq!(drained, 0);
1503        assert_eq!(ary, [1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 7, 8, 9]);
1504    }
1505
1506    #[test]
1507    fn non_empty_array_set_slice_interior_non_empty_drain_0() {
1508        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1509        let drained = ary.set_slice(1, 0, &[7, 8, 9]);
1510        assert_eq!(drained, 0);
1511        assert_eq!(ary, [1, 7, 8, 9, 2, 3, 4, 5]);
1512    }
1513
1514    #[test]
1515    fn non_empty_array_set_slice_interior_non_empty_drain_less_than_insert_length() {
1516        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1517        let drained = ary.set_slice(1, 2, &[7, 8, 9]);
1518        assert_eq!(drained, 2);
1519        assert_eq!(ary, [1, 7, 8, 9, 4, 5]);
1520    }
1521
1522    #[test]
1523    fn non_empty_array_set_slice_interior_non_empty_drain_equal_to_insert_length() {
1524        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1525        let drained = ary.set_slice(1, 3, &[7, 8, 9]);
1526        assert_eq!(drained, 3);
1527        assert_eq!(ary, [1, 7, 8, 9, 5]);
1528    }
1529
1530    #[test]
1531    fn non_empty_array_set_slice_interior_non_empty_drain_greater_than_insert_length() {
1532        let mut ary = SmallArray::from([1, 2, 3, 4, 5, 6]);
1533        let drained = ary.set_slice(1, 4, &[7, 8, 9]);
1534        assert_eq!(drained, 4);
1535        assert_eq!(ary, [1, 7, 8, 9, 6]);
1536        assert_eq!(ary.len(), 5);
1537    }
1538
1539    #[test]
1540    fn non_empty_array_set_slice_interior_non_empty_drain_equal_to_insert_length_to_tail() {
1541        let mut ary = SmallArray::from([1, 2, 3, 4]);
1542        let drained = ary.set_slice(1, 3, &[7, 8, 9]);
1543        assert_eq!(drained, 3);
1544        assert_eq!(ary, [1, 7, 8, 9]);
1545    }
1546
1547    #[test]
1548    fn non_empty_array_set_slice_interior_non_empty_drain_greater_than_insert_length_to_tail() {
1549        let mut ary = SmallArray::from([1, 2, 3, 4]);
1550        let drained = ary.set_slice(1, 10, &[7, 8, 9]);
1551        assert_eq!(drained, 3);
1552        assert_eq!(ary, [1, 7, 8, 9]);
1553    }
1554
1555    #[test]
1556    fn non_empty_array_set_slice_interior_non_empty_drain_less_than_insert_length_overrun_tail() {
1557        let mut ary = SmallArray::from([1, 2, 3, 4]);
1558        let drained = ary.set_slice(3, 2, &[7, 8, 9]);
1559        assert_eq!(drained, 1);
1560        assert_eq!(ary, [1, 2, 3, 7, 8, 9]);
1561    }
1562
1563    #[test]
1564    fn non_empty_array_set_slice_interior_non_empty_drain_equal_to_insert_length_overrun_tail() {
1565        let mut ary = SmallArray::from([1, 2, 3, 4]);
1566        let drained = ary.set_slice(3, 3, &[7, 8, 9]);
1567        assert_eq!(drained, 1);
1568        assert_eq!(ary, [1, 2, 3, 7, 8, 9]);
1569    }
1570
1571    #[test]
1572    fn non_empty_array_set_slice_interior_non_empty_drain_greater_than_insert_length_overrun_tail() {
1573        let mut ary = SmallArray::from([1, 2, 3, 4]);
1574        let drained = ary.set_slice(3, 10, &[7, 8, 9]);
1575        assert_eq!(drained, 1);
1576        assert_eq!(ary, [1, 2, 3, 7, 8, 9]);
1577    }
1578
1579    #[test]
1580    fn non_empty_array_set_slice_begin_non_empty_drain_0() {
1581        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1582        let drained = ary.set_slice(0, 0, &[7, 8, 9]);
1583        assert_eq!(drained, 0);
1584        assert_eq!(ary, [7, 8, 9, 1, 2, 3, 4, 5]);
1585    }
1586
1587    #[test]
1588    fn non_empty_array_set_slice_begin_non_empty_drain_less_than_insert_length() {
1589        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1590        let drained = ary.set_slice(0, 2, &[7, 8, 9]);
1591        assert_eq!(drained, 2);
1592        assert_eq!(ary, [7, 8, 9, 3, 4, 5]);
1593    }
1594
1595    #[test]
1596    fn non_empty_array_set_slice_begin_non_empty_drain_equal_to_insert_length() {
1597        let mut ary = SmallArray::from([1, 2, 3, 4, 5]);
1598        let drained = ary.set_slice(0, 3, &[7, 8, 9]);
1599        assert_eq!(drained, 3);
1600        assert_eq!(ary, [7, 8, 9, 4, 5]);
1601    }
1602
1603    #[test]
1604    fn non_empty_array_set_slice_begin_non_empty_drain_greater_than_insert_length() {
1605        let mut ary = SmallArray::from([1, 2, 3, 4, 5, 6]);
1606        let drained = ary.set_slice(0, 4, &[7, 8, 9]);
1607        assert_eq!(drained, 4);
1608        assert_eq!(ary, [7, 8, 9, 5, 6]);
1609    }
1610
1611    #[test]
1612    fn non_empty_array_set_slice_begin_non_empty_drain_equal_to_insert_length_to_tail() {
1613        let mut ary = SmallArray::from([1, 2, 3, 4]);
1614        let drained = ary.set_slice(0, 4, &[7, 8, 9, 10]);
1615        assert_eq!(drained, 4);
1616        assert_eq!(ary, [7, 8, 9, 10]);
1617    }
1618
1619    #[test]
1620    fn non_empty_array_set_slice_begin_non_empty_drain_greater_than_insert_length_to_tail() {
1621        let mut ary = SmallArray::from([1, 2, 3, 4]);
1622        let drained = ary.set_slice(0, 10, &[7, 8, 9, 10]);
1623        assert_eq!(drained, 4);
1624        assert_eq!(ary, [7, 8, 9, 10]);
1625    }
1626
1627    #[test]
1628    fn non_empty_array_set_slice_begin_non_empty_drain_less_than_insert_length_overrun_tail() {
1629        let mut ary = SmallArray::from([1, 2, 3, 4]);
1630        let drained = ary.set_slice(0, 4, &[7, 8, 9, 10, 11]);
1631        assert_eq!(drained, 4);
1632        assert_eq!(ary, [7, 8, 9, 10, 11]);
1633    }
1634
1635    #[test]
1636    fn non_empty_array_set_slice_begin_non_empty_drain_equal_to_insert_length_overrun_tail() {
1637        let mut ary = SmallArray::from([1, 2, 3, 4]);
1638        let drained = ary.set_slice(0, 5, &[7, 8, 9, 10, 11]);
1639        assert_eq!(drained, 4);
1640        assert_eq!(ary, [7, 8, 9, 10, 11]);
1641    }
1642
1643    #[test]
1644    fn non_empty_array_set_slice_begin_non_empty_drain_greater_than_insert_length_overrun_tail() {
1645        let mut ary = SmallArray::from([1, 2, 3, 4]);
1646        let drained = ary.set_slice(0, 10, &[7, 8, 9, 10, 11]);
1647        assert_eq!(drained, 4);
1648        assert_eq!(ary, [7, 8, 9, 10, 11]);
1649    }
1650
1651    #[test]
1652    fn empty_array_set_slice_non_empty_drain_0() {
1653        let mut ary = SmallArray::<i32>::new();
1654        let drained = ary.set_slice(0, 0, &[7, 8, 9]);
1655        assert_eq!(drained, 0);
1656        assert_eq!(ary, [7, 8, 9]);
1657    }
1658
1659    #[test]
1660    fn empty_array_set_slice_non_empty_drain_less_than_insert_length() {
1661        let mut ary = SmallArray::<i32>::new();
1662        let drained = ary.set_slice(0, 1, &[7, 8, 9]);
1663        assert_eq!(drained, 0);
1664        assert_eq!(ary, [7, 8, 9]);
1665    }
1666
1667    #[test]
1668    fn empty_array_set_slice_non_empty_drain_equal_to_insert_length() {
1669        let mut ary = SmallArray::<i32>::new();
1670        let drained = ary.set_slice(0, 3, &[7, 8, 9]);
1671        assert_eq!(drained, 0);
1672        assert_eq!(ary, [7, 8, 9]);
1673    }
1674
1675    #[test]
1676    fn empty_array_set_slice_begin_non_empty_drain_greater_than_insert_length() {
1677        let mut ary = SmallArray::<i32>::new();
1678        let drained = ary.set_slice(0, 10, &[7, 8, 9]);
1679        assert_eq!(drained, 0);
1680        assert_eq!(ary, [7, 8, 9]);
1681    }
1682
1683    #[test]
1684    fn empty_array_set_slice_out_of_bounds_non_empty_drain_0() {
1685        let mut ary = SmallArray::<i32>::new();
1686        let drained = ary.set_slice(5, 0, &[7, 8, 9]);
1687        assert_eq!(drained, 0);
1688        assert_eq!(ary, [0, 0, 0, 0, 0, 7, 8, 9]);
1689    }
1690
1691    #[test]
1692    fn empty_array_set_slice_out_of_bounds_non_empty_drain_less_than_insert_length() {
1693        let mut ary = SmallArray::<i32>::new();
1694        let drained = ary.set_slice(5, 1, &[7, 8, 9]);
1695        assert_eq!(drained, 0);
1696        assert_eq!(ary, [0, 0, 0, 0, 0, 7, 8, 9]);
1697    }
1698
1699    #[test]
1700    fn empty_array_set_slice_out_of_bounds_non_empty_drain_equal_to_insert_length() {
1701        let mut ary = SmallArray::<i32>::new();
1702        let drained = ary.set_slice(5, 3, &[7, 8, 9]);
1703        assert_eq!(drained, 0);
1704        assert_eq!(ary, [0, 0, 0, 0, 0, 7, 8, 9]);
1705    }
1706
1707    #[test]
1708    fn empty_array_set_slice_out_of_bounds_non_empty_drain_greater_than_insert_length() {
1709        let mut ary = SmallArray::<i32>::new();
1710        let drained = ary.set_slice(5, 10, &[7, 8, 9]);
1711        assert_eq!(drained, 0);
1712        assert_eq!(ary, [0, 0, 0, 0, 0, 7, 8, 9]);
1713    }
1714
1715    #[test]
1716    fn empty_array_set_slice_empty_drain_0() {
1717        let mut ary = SmallArray::<i32>::new();
1718        let drained = ary.set_slice(0, 0, &[]);
1719        assert_eq!(drained, 0);
1720        assert_eq!(ary, []);
1721    }
1722
1723    #[test]
1724    fn empty_array_set_slice_empty_drain_less_than_insert_length() {
1725        let mut ary = SmallArray::<i32>::new();
1726        let drained = ary.set_slice(0, 0, &[]);
1727        assert_eq!(drained, 0);
1728        assert_eq!(ary, []);
1729    }
1730
1731    #[test]
1732    fn empty_array_set_slice_empty_drain_equal_to_insert_length() {
1733        let mut ary = SmallArray::<i32>::new();
1734        let drained = ary.set_slice(0, 0, &[]);
1735        assert_eq!(drained, 0);
1736        assert_eq!(ary, []);
1737    }
1738
1739    #[test]
1740    fn empty_array_set_slice_begin_empty_drain_greater_than_insert_length() {
1741        let mut ary = SmallArray::<i32>::new();
1742        let drained = ary.set_slice(0, 10, &[]);
1743        assert_eq!(drained, 0);
1744        assert_eq!(ary, []);
1745    }
1746
1747    #[test]
1748    fn empty_array_set_slice_out_of_bounds_empty_drain_0() {
1749        let mut ary = SmallArray::<i32>::new();
1750        let drained = ary.set_slice(5, 0, &[]);
1751        assert_eq!(drained, 0);
1752        assert_eq!(ary, [0, 0, 0, 0, 0]);
1753    }
1754
1755    #[test]
1756    fn empty_array_set_slice_out_of_bounds_empty_drain_less_than_insert_length() {
1757        let mut ary = SmallArray::<i32>::new();
1758        let drained = ary.set_slice(5, 1, &[]);
1759        assert_eq!(drained, 0);
1760        assert_eq!(ary, [0, 0, 0, 0, 0]);
1761    }
1762
1763    #[test]
1764    fn empty_array_set_slice_out_of_bounds_empty_drain_equal_to_insert_length() {
1765        let mut ary = SmallArray::<i32>::new();
1766        let drained = ary.set_slice(5, 3, &[]);
1767        assert_eq!(drained, 0);
1768        assert_eq!(ary, [0, 0, 0, 0, 0]);
1769    }
1770
1771    #[test]
1772    fn empty_array_set_slice_out_of_bounds_empty_drain_greater_than_insert_length() {
1773        let mut ary = SmallArray::<i32>::new();
1774        let drained = ary.set_slice(5, 10, &[]);
1775        assert_eq!(drained, 0);
1776        assert_eq!(ary, [0, 0, 0, 0, 0]);
1777    }
1778}