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