1 #![cfg(feature = "alloc")]
2 
3 use super::*;
4 
5 use alloc::vec::Vec;
6 
7 /// Helper to make a `TinyVec`.
8 ///
9 /// You specify the backing array type, and optionally give all the elements you
10 /// want to initially place into the array.
11 ///
12 /// As an unfortunate restriction, the backing array type must support `Default`
13 /// for it to work with this macro.
14 ///
15 /// ```rust
16 /// use tinyvec::*;
17 ///
18 /// // The backing array type can be specified in the macro call
19 /// let empty_tv = tiny_vec!([u8; 16]);
20 /// let some_ints = tiny_vec!([i32; 4], 1, 2, 3);
21 /// let many_ints = tiny_vec!([i32; 4], 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
22 ///
23 /// // Or left to inference
24 /// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!();
25 /// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3);
26 /// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
27 /// ```
28 #[macro_export]
29 macro_rules! tiny_vec {
30   ($array_type:ty) => {
31     {
32       let mut tv: $crate::TinyVec<$array_type> = Default::default();
33       tv
34     }
35   };
36   ($array_type:ty, $($elem:expr),* $(,)?) => {
37     {
38       // Note(Lokathor): This goofy looking thing will count the number of
39       // `$elem` entries we were given. We can't spit out the "+1"s on their
40       // own, we need to use `$elem` in the repetition-expansion somehow.
41       // However, we also can't assume it's `Copy` data, so we must use `$elem`
42       // only once "for real" in the expansion as a whole. To achieve this, we
43       // can `stringify!` each element in an inner block, then have the block
44       // return a 1. The stringification is a compile time thing, it won't
45       // actually move any values.
46       const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
47       // If we have more `$elem` than the `CAPACITY` we will simply go directly
48       // to constructing on the heap.
49       let av: $crate::TinyVec<$array_type> = $crate::TinyVec::from_either_with_capacity(
50         INVOKED_ELEM_COUNT,
51         #[inline(always)] || $crate::array_vec!($array_type, $($elem),*),
52         #[inline(always)] || vec!($($elem),*));
53       av
54     }
55   };
56   () => {
57     tiny_vec!(_)
58   };
59   ($($elem:expr),*) => {
60     tiny_vec!(_, $($elem),*)
61   };
62 }
63 
64 /// A vector that starts inline, but can automatically move to the heap.
65 ///
66 /// * Requires the `alloc` feature
67 ///
68 /// A `TinyVec` is either an Inline([`ArrayVec`](crate::ArrayVec::<A>)) or
69 /// Heap([`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)). The
70 /// interface for the type as a whole is a bunch of methods that just match on
71 /// the enum variant and then call the same method on the inner vec.
72 ///
73 /// ## Construction
74 ///
75 /// Because it's an enum, you can construct a `TinyVec` simply by making an
76 /// `ArrayVec` or `Vec` and then putting it into the enum.
77 ///
78 /// There is also a macro
79 ///
80 /// ```rust
81 /// # use tinyvec::*;
82 /// let empty_tv = tiny_vec!([u8; 16]);
83 /// let some_ints = tiny_vec!([i32; 4], 1, 2, 3);
84 /// ```
85 #[derive(Clone)]
86 pub enum TinyVec<A: Array> {
87   #[allow(missing_docs)]
88   Inline(ArrayVec<A>),
89   #[allow(missing_docs)]
90   Heap(Vec<A::Item>),
91 }
92 impl<A: Array + Default> Default for TinyVec<A> {
93   #[inline]
94   #[must_use]
default() -> Self95   fn default() -> Self {
96     TinyVec::Inline(ArrayVec::default())
97   }
98 }
99 
100 impl<A: Array> Deref for TinyVec<A> {
101   type Target = [A::Item];
102   #[inline(always)]
103   #[must_use]
deref(&self) -> &Self::Target104   fn deref(&self) -> &Self::Target {
105     match self {
106       TinyVec::Inline(a) => a.deref(),
107       TinyVec::Heap(v) => v.deref(),
108     }
109   }
110 }
111 
112 impl<A: Array> DerefMut for TinyVec<A> {
113   #[inline(always)]
114   #[must_use]
deref_mut(&mut self) -> &mut Self::Target115   fn deref_mut(&mut self) -> &mut Self::Target {
116     match self {
117       TinyVec::Inline(a) => a.deref_mut(),
118       TinyVec::Heap(v) => v.deref_mut(),
119     }
120   }
121 }
122 
123 impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for TinyVec<A> {
124   type Output = <I as SliceIndex<[A::Item]>>::Output;
125   #[inline(always)]
126   #[must_use]
index(&self, index: I) -> &Self::Output127   fn index(&self, index: I) -> &Self::Output {
128     &self.deref()[index]
129   }
130 }
131 
132 impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> {
133   #[inline(always)]
134   #[must_use]
index_mut(&mut self, index: I) -> &mut Self::Output135   fn index_mut(&mut self, index: I) -> &mut Self::Output {
136     &mut self.deref_mut()[index]
137   }
138 }
139 
140 impl<A: Array> TinyVec<A> {
141   /// Moves the content of the TinyVec to the heap, if it's inline.
142   #[allow(clippy::missing_inline_in_public_items)]
move_to_the_heap(&mut self)143   pub fn move_to_the_heap(&mut self) {
144     match self {
145       TinyVec::Inline(ref mut arr) => {
146         let mut v = Vec::with_capacity(A::CAPACITY * 2);
147         for item in arr.drain(..) {
148           v.push(item);
149         }
150         replace(self, TinyVec::Heap(v));
151       }
152       TinyVec::Heap(_) => (),
153     }
154   }
155 }
156 
157 impl<A: Array> TinyVec<A> {
158   /// Move all values from `other` into this vec.
159   #[inline]
append(&mut self, other: &mut Self)160   pub fn append(&mut self, other: &mut Self) {
161     for item in other.drain(..) {
162       self.push(item)
163     }
164   }
165 
166   /// A mutable pointer to the backing array.
167   ///
168   /// ## Safety
169   ///
170   /// This pointer has provenance over the _entire_ backing array/buffer.
171   #[inline(always)]
172   #[must_use]
as_mut_ptr(&mut self) -> *mut A::Item173   pub fn as_mut_ptr(&mut self) -> *mut A::Item {
174     match self {
175       TinyVec::Inline(a) => a.as_mut_ptr(),
176       TinyVec::Heap(v) => v.as_mut_ptr(),
177     }
178   }
179 
180   /// Helper for getting the mut slice.
181   #[inline(always)]
182   #[must_use]
as_mut_slice(&mut self) -> &mut [A::Item]183   pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
184     self.deref_mut()
185   }
186 
187   /// A const pointer to the backing array.
188   ///
189   /// ## Safety
190   ///
191   /// This pointer has provenance over the _entire_ backing array/buffer.
192   #[inline(always)]
193   #[must_use]
as_ptr(&self) -> *const A::Item194   pub fn as_ptr(&self) -> *const A::Item {
195     match self {
196       TinyVec::Inline(a) => a.as_ptr(),
197       TinyVec::Heap(v) => v.as_ptr(),
198     }
199   }
200 
201   /// Helper for getting the shared slice.
202   #[inline(always)]
203   #[must_use]
as_slice(&self) -> &[A::Item]204   pub fn as_slice(&self) -> &[A::Item] {
205     self.deref()
206   }
207 
208   /// The capacity of the `TinyVec`.
209   ///
210   /// When not heap allocated this is fixed based on the array type.
211   /// Otherwise its the result of the underlying Vec::capacity.
212   #[inline(always)]
213   #[must_use]
capacity(&self) -> usize214   pub fn capacity(&self) -> usize {
215     match self {
216       TinyVec::Inline(_) => A::CAPACITY,
217       TinyVec::Heap(v) => v.capacity(),
218     }
219   }
220 
221   /// Removes all elements from the vec.
222   #[inline(always)]
clear(&mut self)223   pub fn clear(&mut self) {
224     self.truncate(0)
225   }
226 
227   /// De-duplicates the vec.
228   #[cfg(feature = "nightly_slice_partition_dedup")]
229   #[inline(always)]
dedup(&mut self) where A::Item: PartialEq,230   pub fn dedup(&mut self)
231   where
232     A::Item: PartialEq,
233   {
234     self.dedup_by(|a, b| a == b)
235   }
236 
237   /// De-duplicates the vec according to the predicate given.
238   #[cfg(feature = "nightly_slice_partition_dedup")]
239   #[inline(always)]
dedup_by<F>(&mut self, same_bucket: F) where F: FnMut(&mut A::Item, &mut A::Item) -> bool,240   pub fn dedup_by<F>(&mut self, same_bucket: F)
241   where
242     F: FnMut(&mut A::Item, &mut A::Item) -> bool,
243   {
244     let len = {
245       let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
246       dedup.len()
247     };
248     self.truncate(len);
249   }
250 
251   /// De-duplicates the vec according to the key selector given.
252   #[cfg(feature = "nightly_slice_partition_dedup")]
253   #[inline(always)]
dedup_by_key<F, K>(&mut self, mut key: F) where F: FnMut(&mut A::Item) -> K, K: PartialEq,254   pub fn dedup_by_key<F, K>(&mut self, mut key: F)
255   where
256     F: FnMut(&mut A::Item) -> K,
257     K: PartialEq,
258   {
259     self.dedup_by(|a, b| key(a) == key(b))
260   }
261 
262   /// Creates a draining iterator that removes the specified range in the vector
263   /// and yields the removed items.
264   ///
265   /// ## Panics
266   /// * If the start is greater than the end
267   /// * If the end is past the edge of the vec.
268   ///
269   /// ## Example
270   /// ```rust
271   /// use tinyvec::*;
272   /// let mut tv = tiny_vec!([i32; 4], 1, 2, 3);
273   /// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect();
274   /// assert_eq!(tv.as_slice(), &[1][..]);
275   /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
276   ///
277   /// tv.drain(..);
278   /// assert_eq!(tv.as_slice(), &[]);
279   /// ```
280   #[inline]
drain<R: RangeBounds<usize>>( &mut self, range: R, ) -> TinyVecDrain<'_, A>281   pub fn drain<R: RangeBounds<usize>>(
282     &mut self,
283     range: R,
284   ) -> TinyVecDrain<'_, A> {
285     use core::ops::Bound;
286     let start = match range.start_bound() {
287       Bound::Included(x) => *x,
288       Bound::Excluded(x) => x + 1,
289       Bound::Unbounded => 0,
290     };
291     let end = match range.end_bound() {
292       Bound::Included(x) => x + 1,
293       Bound::Excluded(x) => *x,
294       Bound::Unbounded => self.len(),
295     };
296     assert!(
297       start <= end,
298       "TinyVec::drain> Illegal range, {} to {}",
299       start,
300       end
301     );
302     assert!(
303       end <= self.len(),
304       "TinyVec::drain> Range ends at {} but length is only {}!",
305       end,
306       self.len()
307     );
308     TinyVecDrain {
309       parent: self,
310       target_index: start,
311       target_count: end - start,
312     }
313   }
314 
315   /// Clone each element of the slice into this vec.
316   #[inline]
extend_from_slice(&mut self, sli: &[A::Item]) where A::Item: Clone,317   pub fn extend_from_slice(&mut self, sli: &[A::Item])
318   where
319     A::Item: Clone,
320   {
321     for i in sli {
322       self.push(i.clone())
323     }
324   }
325 
326   /// Wraps up an array and uses the given length as the initial length.
327   ///
328   /// Note that the `From` impl for arrays assumes the full length is used.
329   ///
330   /// ## Panics
331   ///
332   /// The length must be less than or equal to the capacity of the array.
333   #[inline]
334   #[must_use]
335   #[allow(clippy::match_wild_err_arm)]
from_array_len(data: A, len: usize) -> Self336   pub fn from_array_len(data: A, len: usize) -> Self {
337     match Self::try_from_array_len(data, len) {
338       Ok(out) => out,
339       Err(_) => {
340         panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY)
341       }
342     }
343   }
344 
345   #[inline(always)]
346   #[doc(hidden)] // Internal implementation details of `tiny_vec!`
from_either_with_capacity( cap: usize, make_array: impl FnOnce() -> ArrayVec<A>, make_vec: impl FnOnce() -> Vec<A::Item>, ) -> Self347   pub fn from_either_with_capacity(
348     cap: usize,
349     make_array: impl FnOnce() -> ArrayVec<A>,
350     make_vec: impl FnOnce() -> Vec<A::Item>,
351   ) -> Self {
352     if cap <= A::CAPACITY {
353       TinyVec::Inline(make_array())
354     } else {
355       TinyVec::Heap(make_vec())
356     }
357   }
358 
359   /// Inserts an item at the position given, moving all following elements +1
360   /// index.
361   ///
362   /// ## Panics
363   /// * If `index` > `len`
364   ///
365   /// ## Example
366   /// ```rust
367   /// use tinyvec::*;
368   /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3);
369   /// tv.insert(1, 4);
370   /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]);
371   /// tv.insert(4, 5);
372   /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3, 5]);
373   /// ```
374   #[inline]
insert(&mut self, index: usize, item: A::Item)375   pub fn insert(&mut self, index: usize, item: A::Item) {
376     match self {
377       TinyVec::Inline(a) => {
378         if a.len() == A::CAPACITY {
379           self.move_to_the_heap();
380           self.insert(index, item)
381         } else {
382           a.insert(index, item);
383         }
384       }
385       TinyVec::Heap(v) => v.insert(index, item),
386     }
387   }
388 
389   /// If the vec is empty.
390   #[inline(always)]
391   #[must_use]
is_empty(&self) -> bool392   pub fn is_empty(&self) -> bool {
393     self.len() == 0
394   }
395 
396   /// The length of the vec (in elements).
397   #[inline(always)]
398   #[must_use]
len(&self) -> usize399   pub fn len(&self) -> usize {
400     match self {
401       TinyVec::Inline(a) => a.len(),
402       TinyVec::Heap(v) => v.len(),
403     }
404   }
405 
406   /// Makes a new, empty vec.
407   #[inline(always)]
408   #[must_use]
new() -> Self where A: Default,409   pub fn new() -> Self
410   where
411     A: Default,
412   {
413     Self::default()
414   }
415 
416   /// Remove and return the last element of the vec, if there is one.
417   ///
418   /// ## Failure
419   /// * If the vec is empty you get `None`.
420   #[inline]
pop(&mut self) -> Option<A::Item>421   pub fn pop(&mut self) -> Option<A::Item> {
422     match self {
423       TinyVec::Inline(a) => a.pop(),
424       TinyVec::Heap(v) => v.pop(),
425     }
426   }
427 
428   /// Place an element onto the end of the vec.
429   /// ## Panics
430   /// * If the length of the vec would overflow the capacity.
431   #[inline(always)]
push(&mut self, val: A::Item)432   pub fn push(&mut self, val: A::Item) {
433     match self {
434       TinyVec::Inline(a) => {
435         if a.len() == A::CAPACITY {
436           self.move_to_the_heap();
437           self.push(val)
438         } else {
439           a.push(val);
440         }
441       }
442       TinyVec::Heap(v) => v.push(val),
443     }
444   }
445 
446   /// Removes the item at `index`, shifting all others down by one index.
447   ///
448   /// Returns the removed element.
449   ///
450   /// ## Panics
451   ///
452   /// If the index is out of bounds.
453   ///
454   /// ## Example
455   ///
456   /// ```rust
457   /// use tinyvec::*;
458   /// let mut tv = tiny_vec!([i32; 4], 1, 2, 3);
459   /// assert_eq!(tv.remove(1), 2);
460   /// assert_eq!(tv.as_slice(), &[1, 3][..]);
461   /// ```
462   #[inline]
remove(&mut self, index: usize) -> A::Item463   pub fn remove(&mut self, index: usize) -> A::Item {
464     match self {
465       TinyVec::Inline(a) => a.remove(index),
466       TinyVec::Heap(v) => v.remove(index),
467     }
468   }
469 
470   /// Resize the vec to the new length.
471   ///
472   /// If it needs to be longer, it's filled with clones of the provided value.
473   /// If it needs to be shorter, it's truncated.
474   ///
475   /// ## Example
476   ///
477   /// ```rust
478   /// use tinyvec::*;
479   ///
480   /// let mut tv = tiny_vec!([&str; 10], "hello");
481   /// tv.resize(3, "world");
482   /// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]);
483   ///
484   /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3, 4);
485   /// tv.resize(2, 0);
486   /// assert_eq!(tv.as_slice(), &[1, 2][..]);
487   /// ```
488   #[inline]
resize(&mut self, new_len: usize, new_val: A::Item) where A::Item: Clone,489   pub fn resize(&mut self, new_len: usize, new_val: A::Item)
490   where
491     A::Item: Clone,
492   {
493     match self {
494       TinyVec::Inline(a) => {
495         if new_len > A::CAPACITY {
496           self.move_to_the_heap();
497           self.resize(new_len, new_val);
498         } else {
499           a.resize(new_len, new_val);
500         }
501       }
502       TinyVec::Heap(v) => v.resize(new_len, new_val),
503     }
504   }
505 
506   /// Resize the vec to the new length.
507   ///
508   /// If it needs to be longer, it's filled with repeated calls to the provided
509   /// function. If it needs to be shorter, it's truncated.
510   ///
511   /// ## Example
512   ///
513   /// ```rust
514   /// use tinyvec::*;
515   ///
516   /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3);
517   /// tv.resize_with(5, Default::default);
518   /// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]);
519   ///
520   /// let mut tv = tiny_vec!([i32; 10]);
521   /// let mut p = 1;
522   /// tv.resize_with(4, || {
523   ///   p *= 2;
524   ///   p
525   /// });
526   /// assert_eq!(tv.as_slice(), &[2, 4, 8, 16][..]);
527   /// ```
528   #[inline]
resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F)529   pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F) {
530     match self {
531       TinyVec::Inline(a) => a.resize_with(new_len, f),
532       TinyVec::Heap(v) => v.resize_with(new_len, f),
533     }
534   }
535 
536   /// Walk the vec and keep only the elements that pass the predicate given.
537   ///
538   /// ## Example
539   ///
540   /// ```rust
541   /// use tinyvec::*;
542   ///
543   /// let mut tv = tiny_vec!([i32; 10], 1, 2, 3, 4);
544   /// tv.retain(|&x| x % 2 == 0);
545   /// assert_eq!(tv.as_slice(), &[2, 4][..]);
546   /// ```
547   #[inline]
retain<F: FnMut(&A::Item) -> bool>(&mut self, acceptable: F)548   pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, acceptable: F) {
549     match self {
550       TinyVec::Inline(a) => a.retain(acceptable),
551       TinyVec::Heap(v) => v.retain(acceptable),
552     }
553   }
554 
555   /// Splits the collection at the point given.
556   ///
557   /// * `[0, at)` stays in this vec
558   /// * `[at, len)` ends up in the new vec.
559   ///
560   /// ## Panics
561   /// * if at > len
562   ///
563   /// ## Example
564   ///
565   /// ```rust
566   /// use tinyvec::*;
567   /// let mut tv = tiny_vec!([i32; 4], 1, 2, 3);
568   /// let tv2 = tv.split_off(1);
569   /// assert_eq!(tv.as_slice(), &[1][..]);
570   /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
571   /// ```
572   #[inline]
split_off(&mut self, at: usize) -> Self where A: Default,573   pub fn split_off(&mut self, at: usize) -> Self
574   where
575     A: Default,
576   {
577     match self {
578       TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)),
579       TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)),
580     }
581   }
582 
583   /// Remove an element, swapping the end of the vec into its place.
584   ///
585   /// ## Panics
586   /// * If the index is out of bounds.
587   ///
588   /// ## Example
589   /// ```rust
590   /// use tinyvec::*;
591   /// let mut tv = tiny_vec!([&str; 4], "foo", "bar", "quack", "zap");
592   ///
593   /// assert_eq!(tv.swap_remove(1), "bar");
594   /// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]);
595   ///
596   /// assert_eq!(tv.swap_remove(0), "foo");
597   /// assert_eq!(tv.as_slice(), &["quack", "zap"][..]);
598   /// ```
599   #[inline]
swap_remove(&mut self, index: usize) -> A::Item600   pub fn swap_remove(&mut self, index: usize) -> A::Item {
601     match self {
602       TinyVec::Inline(a) => a.swap_remove(index),
603       TinyVec::Heap(v) => v.swap_remove(index),
604     }
605   }
606 
607   /// Reduces the vec's length to the given value.
608   ///
609   /// If the vec is already shorter than the input, nothing happens.
610   #[inline]
truncate(&mut self, new_len: usize)611   pub fn truncate(&mut self, new_len: usize) {
612     match self {
613       TinyVec::Inline(a) => a.truncate(new_len),
614       TinyVec::Heap(v) => v.truncate(new_len),
615     }
616   }
617 
618   /// Wraps an array, using the given length as the starting length.
619   ///
620   /// If you want to use the whole length of the array, you can just use the
621   /// `From` impl.
622   ///
623   /// ## Failure
624   ///
625   /// If the given length is greater than the capacity of the array this will
626   /// error, and you'll get the array back in the `Err`.
627   #[inline]
try_from_array_len(data: A, len: usize) -> Result<Self, A>628   pub fn try_from_array_len(data: A, len: usize) -> Result<Self, A> {
629     let arr = ArrayVec::try_from_array_len(data, len)?;
630     Ok(TinyVec::Inline(arr))
631   }
632 }
633 
634 /// Draining iterator for `TinyVecDrain`
635 ///
636 /// See [`TinyVecDrain::drain`](TinyVecDrain::<A>::drain)
637 pub struct TinyVecDrain<'p, A: Array> {
638   parent: &'p mut TinyVec<A>,
639   target_index: usize,
640   target_count: usize,
641 }
642 impl<'p, A: Array> FusedIterator for TinyVecDrain<'p, A> { }
643 impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> {
644   type Item = A::Item;
645   #[inline]
next(&mut self) -> Option<Self::Item>646   fn next(&mut self) -> Option<Self::Item> {
647     if self.target_count > 0 {
648       let out = self.parent.remove(self.target_index);
649       self.target_count -= 1;
650       Some(out)
651     } else {
652       None
653     }
654   }
655 }
656 impl<'p, A: Array> Drop for TinyVecDrain<'p, A> {
657   #[inline]
drop(&mut self)658   fn drop(&mut self) {
659     for _ in self {}
660   }
661 }
662 
663 impl<A: Array> AsMut<[A::Item]> for TinyVec<A> {
664   #[inline(always)]
665   #[must_use]
as_mut(&mut self) -> &mut [A::Item]666   fn as_mut(&mut self) -> &mut [A::Item] {
667     &mut *self
668   }
669 }
670 
671 impl<A: Array> AsRef<[A::Item]> for TinyVec<A> {
672   #[inline(always)]
673   #[must_use]
as_ref(&self) -> &[A::Item]674   fn as_ref(&self) -> &[A::Item] {
675     &*self
676   }
677 }
678 
679 impl<A: Array> Borrow<[A::Item]> for TinyVec<A> {
680   #[inline(always)]
681   #[must_use]
borrow(&self) -> &[A::Item]682   fn borrow(&self) -> &[A::Item] {
683     &*self
684   }
685 }
686 
687 impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> {
688   #[inline(always)]
689   #[must_use]
borrow_mut(&mut self) -> &mut [A::Item]690   fn borrow_mut(&mut self) -> &mut [A::Item] {
691     &mut *self
692   }
693 }
694 
695 impl<A: Array> Extend<A::Item> for TinyVec<A> {
696   #[inline]
extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T)697   fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
698     for t in iter {
699       self.push(t)
700     }
701   }
702 }
703 
704 impl<A: Array> From<ArrayVec<A>> for TinyVec<A> {
705   #[inline(always)]
706   #[must_use]
from(arr: ArrayVec<A>) -> Self707   fn from(arr: ArrayVec<A>) -> Self {
708     TinyVec::Inline(arr)
709   }
710 }
711 
712 impl<A: Array> From<A> for TinyVec<A> {
from(array: A) -> Self713   fn from(array: A) -> Self {
714     TinyVec::Inline(ArrayVec::from(array))
715   }
716 }
717 
718 impl<T, A> From<&'_ [T]> for TinyVec<A>
719 where
720   T: Clone + Default,
721   A: Array<Item = T> + Default,
722 {
723   #[inline]
724   #[must_use]
from(slice: &[T]) -> Self725   fn from(slice: &[T]) -> Self {
726     if slice.len() > A::CAPACITY {
727       TinyVec::Heap(slice.into())
728     } else {
729       let mut arr = ArrayVec::new();
730       arr.extend_from_slice(slice);
731 
732       TinyVec::Inline(arr)
733     }
734   }
735 }
736 
737 impl<T, A> From<&'_ mut [T]> for TinyVec<A>
738 where
739   T: Clone + Default,
740   A: Array<Item = T> + Default,
741 {
742   #[inline]
743   #[must_use]
from(slice: &mut [T]) -> Self744   fn from(slice: &mut [T]) -> Self {
745     Self::from(&*slice)
746   }
747 }
748 
749 impl<A: Array + Default> FromIterator<A::Item> for TinyVec<A> {
750   #[inline]
751   #[must_use]
from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self752   fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
753     let mut av = Self::default();
754     for i in iter {
755       av.push(i)
756     }
757     av
758   }
759 }
760 
761 /// Iterator for consuming an `TinyVec` and returning owned elements.
762 pub enum TinyVecIterator<A: Array> {
763   #[allow(missing_docs)]
764   Inline(ArrayVecIterator<A>),
765   #[allow(missing_docs)]
766   Heap(alloc::vec::IntoIter<A::Item>),
767 }
768 
769 impl<A: Array> TinyVecIterator<A> {
770   /// Returns the remaining items of this iterator as a slice.
771   #[inline]
772   #[must_use]
as_slice(&self) -> &[A::Item]773   pub fn as_slice(&self) -> &[A::Item] {
774     match self {
775       TinyVecIterator::Inline(a) => a.as_slice(),
776       TinyVecIterator::Heap(v) => v.as_slice(),
777     }
778   }
779 }
780 impl<A: Array> FusedIterator for TinyVecIterator<A> { }
781 impl<A: Array> Iterator for TinyVecIterator<A> {
782   type Item = A::Item;
783   #[inline]
next(&mut self) -> Option<Self::Item>784   fn next(&mut self) -> Option<Self::Item> {
785     match self {
786       TinyVecIterator::Inline(a) => a.next(),
787       TinyVecIterator::Heap(v) => v.next(),
788     }
789   }
790   #[inline(always)]
791   #[must_use]
size_hint(&self) -> (usize, Option<usize>)792   fn size_hint(&self) -> (usize, Option<usize>) {
793     match self {
794       TinyVecIterator::Inline(a) => a.size_hint(),
795       TinyVecIterator::Heap(v) => v.size_hint(),
796     }
797   }
798   #[inline(always)]
count(self) -> usize799   fn count(self) -> usize {
800     match self {
801       TinyVecIterator::Inline(a) => a.count(),
802       TinyVecIterator::Heap(v) => v.count(),
803     }
804   }
805   #[inline]
last(self) -> Option<Self::Item>806   fn last(self) -> Option<Self::Item> {
807     match self {
808       TinyVecIterator::Inline(a) => a.last(),
809       TinyVecIterator::Heap(v) => v.last(),
810     }
811   }
812   #[inline]
nth(&mut self, n: usize) -> Option<A::Item>813   fn nth(&mut self, n: usize) -> Option<A::Item> {
814     match self {
815       TinyVecIterator::Inline(a) => a.nth(n),
816       TinyVecIterator::Heap(v) => v.nth(n),
817     }
818   }
819 }
820 
821 impl<A: Array> Debug for TinyVecIterator<A> where A::Item: Debug {
822   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result823   fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
824     f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish()
825   }
826 }
827 
828 impl<A: Array> IntoIterator for TinyVec<A> {
829   type Item = A::Item;
830   type IntoIter = TinyVecIterator<A>;
831   #[inline(always)]
832   #[must_use]
into_iter(self) -> Self::IntoIter833   fn into_iter(self) -> Self::IntoIter {
834     match self {
835       TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()),
836       TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()),
837     }
838   }
839 }
840 
841 impl<'a, A: Array> IntoIterator for &'a mut TinyVec<A> {
842   type Item = &'a mut A::Item;
843   type IntoIter = alloc::slice::IterMut<'a, A::Item>;
844   #[inline(always)]
845   #[must_use]
into_iter(self) -> Self::IntoIter846   fn into_iter(self) -> Self::IntoIter {
847     self.iter_mut()
848   }
849 }
850 
851 impl<'a, A: Array> IntoIterator for &'a TinyVec<A> {
852   type Item = &'a A::Item;
853   type IntoIter = alloc::slice::Iter<'a, A::Item>;
854   #[inline(always)]
855   #[must_use]
into_iter(self) -> Self::IntoIter856   fn into_iter(self) -> Self::IntoIter {
857     self.iter()
858   }
859 }
860 
861 impl<A: Array> PartialEq for TinyVec<A>
862 where
863   A::Item: PartialEq,
864 {
865   #[inline]
866   #[must_use]
eq(&self, other: &Self) -> bool867   fn eq(&self, other: &Self) -> bool {
868     self.as_slice().eq(other.as_slice())
869   }
870 }
871 impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {}
872 
873 impl<A: Array> PartialOrd for TinyVec<A>
874 where
875   A::Item: PartialOrd,
876 {
877   #[inline]
878   #[must_use]
partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering>879   fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
880     self.as_slice().partial_cmp(other.as_slice())
881   }
882 }
883 impl<A: Array> Ord for TinyVec<A>
884 where
885   A::Item: Ord,
886 {
887   #[inline]
888   #[must_use]
cmp(&self, other: &Self) -> core::cmp::Ordering889   fn cmp(&self, other: &Self) -> core::cmp::Ordering {
890     self.as_slice().cmp(other.as_slice())
891   }
892 }
893 
894 impl<A: Array> PartialEq<&A> for TinyVec<A>
895 where
896   A::Item: PartialEq,
897 {
898   #[inline]
899   #[must_use]
eq(&self, other: &&A) -> bool900   fn eq(&self, other: &&A) -> bool {
901     self.as_slice().eq(other.as_slice())
902   }
903 }
904 
905 impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A>
906 where
907   A::Item: PartialEq,
908 {
909   #[inline]
910   #[must_use]
eq(&self, other: &&[A::Item]) -> bool911   fn eq(&self, other: &&[A::Item]) -> bool {
912     self.as_slice().eq(*other)
913   }
914 }
915 
916 impl<A: Array> Hash for TinyVec<A>
917 where
918   A::Item: Hash,
919 {
920   #[inline]
hash<H: Hasher>(&self, state: &mut H)921   fn hash<H: Hasher>(&self, state: &mut H) {
922     self.as_slice().hash(state)
923   }
924 }
925 
926 // // // // // // // //
927 // Formatting impls
928 // // // // // // // //
929 
930 impl<A: Array> Binary for TinyVec<A>
931 where
932   A::Item: Binary,
933 {
934   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result935   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
936     write!(f, "[")?;
937     for (i, elem) in self.iter().enumerate() {
938       if i > 0 {
939         write!(f, ", ")?;
940       }
941       Binary::fmt(elem, f)?;
942     }
943     write!(f, "]")
944   }
945 }
946 
947 impl<A: Array> Debug for TinyVec<A>
948 where
949   A::Item: Debug,
950 {
951   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result952   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
953     write!(f, "[")?;
954     for (i, elem) in self.iter().enumerate() {
955       if i > 0 {
956         write!(f, ", ")?;
957       }
958       Debug::fmt(elem, f)?;
959     }
960     write!(f, "]")
961   }
962 }
963 
964 impl<A: Array> Display for TinyVec<A>
965 where
966   A::Item: Display,
967 {
968   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result969   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
970     write!(f, "[")?;
971     for (i, elem) in self.iter().enumerate() {
972       if i > 0 {
973         write!(f, ", ")?;
974       }
975       Display::fmt(elem, f)?;
976     }
977     write!(f, "]")
978   }
979 }
980 
981 impl<A: Array> LowerExp for TinyVec<A>
982 where
983   A::Item: LowerExp,
984 {
985   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result986   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
987     write!(f, "[")?;
988     for (i, elem) in self.iter().enumerate() {
989       if i > 0 {
990         write!(f, ", ")?;
991       }
992       LowerExp::fmt(elem, f)?;
993     }
994     write!(f, "]")
995   }
996 }
997 
998 impl<A: Array> LowerHex for TinyVec<A>
999 where
1000   A::Item: LowerHex,
1001 {
1002   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result1003   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1004     write!(f, "[")?;
1005     for (i, elem) in self.iter().enumerate() {
1006       if i > 0 {
1007         write!(f, ", ")?;
1008       }
1009       LowerHex::fmt(elem, f)?;
1010     }
1011     write!(f, "]")
1012   }
1013 }
1014 
1015 impl<A: Array> Octal for TinyVec<A>
1016 where
1017   A::Item: Octal,
1018 {
1019   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result1020   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1021     write!(f, "[")?;
1022     for (i, elem) in self.iter().enumerate() {
1023       if i > 0 {
1024         write!(f, ", ")?;
1025       }
1026       Octal::fmt(elem, f)?;
1027     }
1028     write!(f, "]")
1029   }
1030 }
1031 
1032 impl<A: Array> Pointer for TinyVec<A>
1033 where
1034   A::Item: Pointer,
1035 {
1036   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result1037   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1038     write!(f, "[")?;
1039     for (i, elem) in self.iter().enumerate() {
1040       if i > 0 {
1041         write!(f, ", ")?;
1042       }
1043       Pointer::fmt(elem, f)?;
1044     }
1045     write!(f, "]")
1046   }
1047 }
1048 
1049 impl<A: Array> UpperExp for TinyVec<A>
1050 where
1051   A::Item: UpperExp,
1052 {
1053   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result1054   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1055     write!(f, "[")?;
1056     for (i, elem) in self.iter().enumerate() {
1057       if i > 0 {
1058         write!(f, ", ")?;
1059       }
1060       UpperExp::fmt(elem, f)?;
1061     }
1062     write!(f, "]")
1063   }
1064 }
1065 
1066 impl<A: Array> UpperHex for TinyVec<A>
1067 where
1068   A::Item: UpperHex,
1069 {
1070   #[allow(clippy::missing_inline_in_public_items)]
fmt(&self, f: &mut Formatter) -> core::fmt::Result1071   fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1072     write!(f, "[")?;
1073     for (i, elem) in self.iter().enumerate() {
1074       if i > 0 {
1075         write!(f, ", ")?;
1076       }
1077       UpperHex::fmt(elem, f)?;
1078     }
1079     write!(f, "]")
1080   }
1081 }
1082