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}