tinyvec/
tinyvec.rs

1use super::*;
2
3use alloc::vec::{self, Vec};
4use core::convert::TryFrom;
5use tinyvec_macros::impl_mirrored;
6
7#[cfg(feature = "rustc_1_57")]
8use alloc::collections::TryReserveError;
9
10#[cfg(feature = "serde")]
11use core::marker::PhantomData;
12#[cfg(feature = "serde")]
13use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
14#[cfg(feature = "serde")]
15use serde::ser::{Serialize, SerializeSeq, Serializer};
16
17/// Helper to make a `TinyVec`.
18///
19/// You specify the backing array type, and optionally give all the elements you
20/// want to initially place into the array.
21///
22/// ```rust
23/// use tinyvec::*;
24///
25/// // The backing array type can be specified in the macro call
26/// let empty_tv = tiny_vec!([u8; 16]);
27/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3);
28/// let many_ints = tiny_vec!([i32; 4] => 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
29///
30/// // Or left to inference
31/// let empty_tv: TinyVec<[u8; 16]> = tiny_vec!();
32/// let some_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3);
33/// let many_ints: TinyVec<[i32; 4]> = tiny_vec!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
34/// ```
35#[macro_export]
36#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
37macro_rules! tiny_vec {
38  ($array_type:ty => $($elem:expr),* $(,)?) => {
39    {
40      // https://github.com/rust-lang/lang-team/issues/28
41      const INVOKED_ELEM_COUNT: usize = 0 $( + { let _ = stringify!($elem); 1 })*;
42      // If we have more `$elem` than the `CAPACITY` we will simply go directly
43      // to constructing on the heap.
44      match $crate::TinyVec::constructor_for_capacity(INVOKED_ELEM_COUNT) {
45        $crate::TinyVecConstructor::Inline(f) => {
46          f($crate::array_vec!($array_type => $($elem),*))
47        }
48        $crate::TinyVecConstructor::Heap(f) => {
49          f(vec!($($elem),*))
50        }
51      }
52    }
53  };
54  ($array_type:ty) => {
55    $crate::TinyVec::<$array_type>::default()
56  };
57  ($($elem:expr),*) => {
58    $crate::tiny_vec!(_ => $($elem),*)
59  };
60  ($elem:expr; $n:expr) => {
61    $crate::TinyVec::from([$elem; $n])
62  };
63  () => {
64    $crate::tiny_vec!(_)
65  };
66}
67
68#[doc(hidden)] // Internal implementation details of `tiny_vec!`
69pub enum TinyVecConstructor<A: Array> {
70  Inline(fn(ArrayVec<A>) -> TinyVec<A>),
71  Heap(fn(Vec<A::Item>) -> TinyVec<A>),
72}
73
74/// A vector that starts inline, but can automatically move to the heap.
75///
76/// * Requires the `alloc` feature
77///
78/// A `TinyVec` is either an Inline([`ArrayVec`](crate::ArrayVec::<A>)) or
79/// Heap([`Vec`](https://doc.rust-lang.org/alloc/vec/struct.Vec.html)). The
80/// interface for the type as a whole is a bunch of methods that just match on
81/// the enum variant and then call the same method on the inner vec.
82///
83/// ## Construction
84///
85/// Because it's an enum, you can construct a `TinyVec` simply by making an
86/// `ArrayVec` or `Vec` and then putting it into the enum.
87///
88/// There is also a macro
89///
90/// ```rust
91/// # use tinyvec::*;
92/// let empty_tv = tiny_vec!([u8; 16]);
93/// let some_ints = tiny_vec!([i32; 4] => 1, 2, 3);
94/// ```
95#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
96pub enum TinyVec<A: Array> {
97  #[allow(missing_docs)]
98  Inline(ArrayVec<A>),
99  #[allow(missing_docs)]
100  Heap(Vec<A::Item>),
101}
102
103impl<A> Clone for TinyVec<A>
104where
105  A: Array + Clone,
106  A::Item: Clone,
107{
108  #[inline]
109  fn clone(&self) -> Self {
110    match self {
111      TinyVec::Heap(v) => TinyVec::Heap(v.clone()),
112      TinyVec::Inline(v) => TinyVec::Inline(v.clone()),
113    }
114  }
115
116  #[inline]
117  fn clone_from(&mut self, o: &Self) {
118    if o.len() > self.len() {
119      self.reserve(o.len() - self.len());
120    } else {
121      self.truncate(o.len());
122    }
123    let (start, end) = o.split_at(self.len());
124    for (dst, src) in self.iter_mut().zip(start) {
125      dst.clone_from(src);
126    }
127    self.extend_from_slice(end);
128  }
129}
130
131impl<A: Array> Default for TinyVec<A> {
132  #[inline]
133  #[must_use]
134  fn default() -> Self {
135    TinyVec::Inline(ArrayVec::default())
136  }
137}
138
139impl<A: Array> Deref for TinyVec<A> {
140  type Target = [A::Item];
141
142  impl_mirrored! {
143    type Mirror = TinyVec;
144    #[inline(always)]
145    #[must_use]
146    fn deref(self: &Self) -> &Self::Target;
147  }
148}
149
150impl<A: Array> DerefMut for TinyVec<A> {
151  impl_mirrored! {
152    type Mirror = TinyVec;
153    #[inline(always)]
154    #[must_use]
155    fn deref_mut(self: &mut Self) -> &mut Self::Target;
156  }
157}
158
159impl<A: Array, I: SliceIndex<[A::Item]>> Index<I> for TinyVec<A> {
160  type Output = <I as SliceIndex<[A::Item]>>::Output;
161  #[inline(always)]
162  #[must_use]
163  fn index(&self, index: I) -> &Self::Output {
164    &self.deref()[index]
165  }
166}
167
168impl<A: Array, I: SliceIndex<[A::Item]>> IndexMut<I> for TinyVec<A> {
169  #[inline(always)]
170  #[must_use]
171  fn index_mut(&mut self, index: I) -> &mut Self::Output {
172    &mut self.deref_mut()[index]
173  }
174}
175
176#[cfg(feature = "std")]
177#[cfg_attr(docs_rs, doc(cfg(feature = "std")))]
178impl<A: Array<Item = u8>> std::io::Write for TinyVec<A> {
179  #[inline(always)]
180  fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
181    self.extend_from_slice(buf);
182    Ok(buf.len())
183  }
184
185  #[inline(always)]
186  fn flush(&mut self) -> std::io::Result<()> {
187    Ok(())
188  }
189}
190
191#[cfg(feature = "serde")]
192#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))]
193impl<A: Array> Serialize for TinyVec<A>
194where
195  A::Item: Serialize,
196{
197  #[must_use]
198  fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
199  where
200    S: Serializer,
201  {
202    let mut seq = serializer.serialize_seq(Some(self.len()))?;
203    for element in self.iter() {
204      seq.serialize_element(element)?;
205    }
206    seq.end()
207  }
208}
209
210#[cfg(feature = "serde")]
211#[cfg_attr(docs_rs, doc(cfg(feature = "serde")))]
212impl<'de, A: Array> Deserialize<'de> for TinyVec<A>
213where
214  A::Item: Deserialize<'de>,
215{
216  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
217  where
218    D: Deserializer<'de>,
219  {
220    deserializer.deserialize_seq(TinyVecVisitor(PhantomData))
221  }
222}
223
224#[cfg(feature = "arbitrary")]
225#[cfg_attr(docs_rs, doc(cfg(feature = "arbitrary")))]
226impl<'a, A> arbitrary::Arbitrary<'a> for TinyVec<A>
227where
228  A: Array,
229  A::Item: arbitrary::Arbitrary<'a>,
230{
231  fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
232    let v = Vec::arbitrary(u)?;
233    let mut tv = TinyVec::Heap(v);
234    tv.shrink_to_fit();
235    Ok(tv)
236  }
237}
238
239impl<A: Array> TinyVec<A> {
240  /// Returns whether elements are on heap
241  #[inline(always)]
242  #[must_use]
243  pub fn is_heap(&self) -> bool {
244    match self {
245      TinyVec::Heap(_) => true,
246      TinyVec::Inline(_) => false,
247    }
248  }
249  /// Returns whether elements are on stack
250  #[inline(always)]
251  #[must_use]
252  pub fn is_inline(&self) -> bool {
253    !self.is_heap()
254  }
255
256  /// Shrinks the capacity of the vector as much as possible.\
257  /// It is inlined if length is less than `A::CAPACITY`.
258  /// ```rust
259  /// use tinyvec::*;
260  /// let mut tv = tiny_vec!([i32; 2] => 1, 2, 3);
261  /// assert!(tv.is_heap());
262  /// let _ = tv.pop();
263  /// assert!(tv.is_heap());
264  /// tv.shrink_to_fit();
265  /// assert!(tv.is_inline());
266  /// ```
267  #[inline]
268  pub fn shrink_to_fit(&mut self) {
269    let vec = match self {
270      TinyVec::Inline(_) => return,
271      TinyVec::Heap(h) => h,
272    };
273
274    if vec.len() > A::CAPACITY {
275      return vec.shrink_to_fit();
276    }
277
278    let moved_vec = core::mem::take(vec);
279
280    let mut av = ArrayVec::default();
281    let mut rest = av.fill(moved_vec);
282    debug_assert!(rest.next().is_none());
283    *self = TinyVec::Inline(av);
284  }
285
286  /// Moves the content of the TinyVec to the heap, if it's inline.
287  /// ```rust
288  /// use tinyvec::*;
289  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
290  /// assert!(tv.is_inline());
291  /// tv.move_to_the_heap();
292  /// assert!(tv.is_heap());
293  /// ```
294  #[allow(clippy::missing_inline_in_public_items)]
295  pub fn move_to_the_heap(&mut self) {
296    let arr = match self {
297      TinyVec::Heap(_) => return,
298      TinyVec::Inline(a) => a,
299    };
300
301    let v = arr.drain_to_vec();
302    *self = TinyVec::Heap(v);
303  }
304
305  /// Tries to move the content of the TinyVec to the heap, if it's inline.
306  ///
307  /// # Errors
308  ///
309  /// If the allocator reports a failure, then an error is returned and the
310  /// content is kept on the stack.
311  ///
312  /// ```rust
313  /// use tinyvec::*;
314  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
315  /// assert!(tv.is_inline());
316  /// assert_eq!(Ok(()), tv.try_move_to_the_heap());
317  /// assert!(tv.is_heap());
318  /// ```
319  #[cfg(feature = "rustc_1_57")]
320  pub fn try_move_to_the_heap(&mut self) -> Result<(), TryReserveError> {
321    let arr = match self {
322      TinyVec::Heap(_) => return Ok(()),
323      TinyVec::Inline(a) => a,
324    };
325
326    let v = arr.try_drain_to_vec()?;
327    *self = TinyVec::Heap(v);
328    return Ok(());
329  }
330
331  /// If TinyVec is inline, moves the content of it to the heap.
332  /// Also reserves additional space.
333  /// ```rust
334  /// use tinyvec::*;
335  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
336  /// assert!(tv.is_inline());
337  /// tv.move_to_the_heap_and_reserve(32);
338  /// assert!(tv.is_heap());
339  /// assert!(tv.capacity() >= 35);
340  /// ```
341  #[inline]
342  pub fn move_to_the_heap_and_reserve(&mut self, n: usize) {
343    let arr = match self {
344      TinyVec::Heap(h) => return h.reserve(n),
345      TinyVec::Inline(a) => a,
346    };
347
348    let v = arr.drain_to_vec_and_reserve(n);
349    *self = TinyVec::Heap(v);
350  }
351
352  /// If TinyVec is inline, try to move the content of it to the heap.
353  /// Also reserves additional space.
354  ///
355  /// # Errors
356  ///
357  /// If the allocator reports a failure, then an error is returned.
358  ///
359  /// ```rust
360  /// use tinyvec::*;
361  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
362  /// assert!(tv.is_inline());
363  /// assert_eq!(Ok(()), tv.try_move_to_the_heap_and_reserve(32));
364  /// assert!(tv.is_heap());
365  /// assert!(tv.capacity() >= 35);
366  /// ```
367  #[cfg(feature = "rustc_1_57")]
368  pub fn try_move_to_the_heap_and_reserve(
369    &mut self, n: usize,
370  ) -> Result<(), TryReserveError> {
371    let arr = match self {
372      TinyVec::Heap(h) => return h.try_reserve(n),
373      TinyVec::Inline(a) => a,
374    };
375
376    let v = arr.try_drain_to_vec_and_reserve(n)?;
377    *self = TinyVec::Heap(v);
378    return Ok(());
379  }
380
381  /// Reserves additional space.
382  /// Moves to the heap if array can't hold `n` more items
383  /// ```rust
384  /// use tinyvec::*;
385  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4);
386  /// assert!(tv.is_inline());
387  /// tv.reserve(1);
388  /// assert!(tv.is_heap());
389  /// assert!(tv.capacity() >= 5);
390  /// ```
391  #[inline]
392  pub fn reserve(&mut self, n: usize) {
393    let arr = match self {
394      TinyVec::Heap(h) => return h.reserve(n),
395      TinyVec::Inline(a) => a,
396    };
397
398    if n > arr.capacity() - arr.len() {
399      let v = arr.drain_to_vec_and_reserve(n);
400      *self = TinyVec::Heap(v);
401    }
402
403    /* In this place array has enough place, so no work is needed more */
404    return;
405  }
406
407  /// Tries to reserve additional space.
408  /// Moves to the heap if array can't hold `n` more items.
409  ///
410  /// # Errors
411  ///
412  /// If the allocator reports a failure, then an error is returned.
413  ///
414  /// ```rust
415  /// use tinyvec::*;
416  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4);
417  /// assert!(tv.is_inline());
418  /// assert_eq!(Ok(()), tv.try_reserve(1));
419  /// assert!(tv.is_heap());
420  /// assert!(tv.capacity() >= 5);
421  /// ```
422  #[cfg(feature = "rustc_1_57")]
423  pub fn try_reserve(&mut self, n: usize) -> Result<(), TryReserveError> {
424    let arr = match self {
425      TinyVec::Heap(h) => return h.try_reserve(n),
426      TinyVec::Inline(a) => a,
427    };
428
429    if n > arr.capacity() - arr.len() {
430      let v = arr.try_drain_to_vec_and_reserve(n)?;
431      *self = TinyVec::Heap(v);
432    }
433
434    /* In this place array has enough place, so no work is needed more */
435    return Ok(());
436  }
437
438  /// Reserves additional space.
439  /// Moves to the heap if array can't hold `n` more items
440  ///
441  /// From [Vec::reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.reserve_exact)
442  /// ```text
443  /// Note that the allocator may give the collection more space than it requests.
444  /// Therefore, capacity can not be relied upon to be precisely minimal.
445  /// Prefer `reserve` if future insertions are expected.
446  /// ```
447  /// ```rust
448  /// use tinyvec::*;
449  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4);
450  /// assert!(tv.is_inline());
451  /// tv.reserve_exact(1);
452  /// assert!(tv.is_heap());
453  /// assert!(tv.capacity() >= 5);
454  /// ```
455  #[inline]
456  pub fn reserve_exact(&mut self, n: usize) {
457    let arr = match self {
458      TinyVec::Heap(h) => return h.reserve_exact(n),
459      TinyVec::Inline(a) => a,
460    };
461
462    if n > arr.capacity() - arr.len() {
463      let v = arr.drain_to_vec_and_reserve(n);
464      *self = TinyVec::Heap(v);
465    }
466
467    /* In this place array has enough place, so no work is needed more */
468    return;
469  }
470
471  /// Tries to reserve additional space.
472  /// Moves to the heap if array can't hold `n` more items
473  ///
474  /// # Errors
475  ///
476  /// If the allocator reports a failure, then an error is returned.
477  ///
478  /// From [Vec::try_reserve_exact](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.try_reserve_exact)
479  /// ```text
480  /// Note that the allocator may give the collection more space than it requests.
481  /// Therefore, capacity can not be relied upon to be precisely minimal.
482  /// Prefer `reserve` if future insertions are expected.
483  /// ```
484  /// ```rust
485  /// use tinyvec::*;
486  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3, 4);
487  /// assert!(tv.is_inline());
488  /// assert_eq!(Ok(()), tv.try_reserve_exact(1));
489  /// assert!(tv.is_heap());
490  /// assert!(tv.capacity() >= 5);
491  /// ```
492  #[cfg(feature = "rustc_1_57")]
493  pub fn try_reserve_exact(&mut self, n: usize) -> Result<(), TryReserveError> {
494    let arr = match self {
495      TinyVec::Heap(h) => return h.try_reserve_exact(n),
496      TinyVec::Inline(a) => a,
497    };
498
499    if n > arr.capacity() - arr.len() {
500      let v = arr.try_drain_to_vec_and_reserve(n)?;
501      *self = TinyVec::Heap(v);
502    }
503
504    /* In this place array has enough place, so no work is needed more */
505    return Ok(());
506  }
507
508  /// Makes a new TinyVec with _at least_ the given capacity.
509  ///
510  /// If the requested capacity is less than or equal to the array capacity you
511  /// get an inline vec. If it's greater than you get a heap vec.
512  /// ```
513  /// # use tinyvec::*;
514  /// let t = TinyVec::<[u8; 10]>::with_capacity(5);
515  /// assert!(t.is_inline());
516  /// assert!(t.capacity() >= 5);
517  ///
518  /// let t = TinyVec::<[u8; 10]>::with_capacity(20);
519  /// assert!(t.is_heap());
520  /// assert!(t.capacity() >= 20);
521  /// ```
522  #[inline]
523  #[must_use]
524  pub fn with_capacity(cap: usize) -> Self {
525    if cap <= A::CAPACITY {
526      TinyVec::Inline(ArrayVec::default())
527    } else {
528      TinyVec::Heap(Vec::with_capacity(cap))
529    }
530  }
531}
532
533impl<A: Array> TinyVec<A> {
534  /// Move all values from `other` into this vec.
535  #[inline]
536  pub fn append(&mut self, other: &mut Self) {
537    self.reserve(other.len());
538
539    /* Doing append should be faster, because it is effectively a memcpy */
540    match (self, other) {
541      (TinyVec::Heap(sh), TinyVec::Heap(oh)) => sh.append(oh),
542      (TinyVec::Inline(a), TinyVec::Heap(h)) => a.extend(h.drain(..)),
543      (ref mut this, TinyVec::Inline(arr)) => this.extend(arr.drain(..)),
544    }
545  }
546
547  impl_mirrored! {
548    type Mirror = TinyVec;
549
550    /// Remove an element, swapping the end of the vec into its place.
551    ///
552    /// ## Panics
553    /// * If the index is out of bounds.
554    ///
555    /// ## Example
556    /// ```rust
557    /// use tinyvec::*;
558    /// let mut tv = tiny_vec!([&str; 4] => "foo", "bar", "quack", "zap");
559    ///
560    /// assert_eq!(tv.swap_remove(1), "bar");
561    /// assert_eq!(tv.as_slice(), &["foo", "zap", "quack"][..]);
562    ///
563    /// assert_eq!(tv.swap_remove(0), "foo");
564    /// assert_eq!(tv.as_slice(), &["quack", "zap"][..]);
565    /// ```
566    #[inline]
567    pub fn swap_remove(self: &mut Self, index: usize) -> A::Item;
568
569    /// Remove and return the last element of the vec, if there is one.
570    ///
571    /// ## Failure
572    /// * If the vec is empty you get `None`.
573    #[inline]
574    pub fn pop(self: &mut Self) -> Option<A::Item>;
575
576    /// Removes the item at `index`, shifting all others down by one index.
577    ///
578    /// Returns the removed element.
579    ///
580    /// ## Panics
581    ///
582    /// If the index is out of bounds.
583    ///
584    /// ## Example
585    ///
586    /// ```rust
587    /// use tinyvec::*;
588    /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
589    /// assert_eq!(tv.remove(1), 2);
590    /// assert_eq!(tv.as_slice(), &[1, 3][..]);
591    /// ```
592    #[inline]
593    pub fn remove(self: &mut Self, index: usize) -> A::Item;
594
595    /// The length of the vec (in elements).
596    #[inline(always)]
597    #[must_use]
598    pub fn len(self: &Self) -> usize;
599
600    /// The capacity of the `TinyVec`.
601    ///
602    /// When not heap allocated this is fixed based on the array type.
603    /// Otherwise its the result of the underlying Vec::capacity.
604    #[inline(always)]
605    #[must_use]
606    pub fn capacity(self: &Self) -> usize;
607
608    /// Reduces the vec's length to the given value.
609    ///
610    /// If the vec is already shorter than the input, nothing happens.
611    #[inline]
612    pub fn truncate(self: &mut Self, new_len: usize);
613
614    /// A mutable pointer to the backing array.
615    ///
616    /// ## Safety
617    ///
618    /// This pointer has provenance over the _entire_ backing array/buffer.
619    #[inline(always)]
620    #[must_use]
621    pub fn as_mut_ptr(self: &mut Self) -> *mut A::Item;
622
623    /// A const pointer to the backing array.
624    ///
625    /// ## Safety
626    ///
627    /// This pointer has provenance over the _entire_ backing array/buffer.
628    #[inline(always)]
629    #[must_use]
630    pub fn as_ptr(self: &Self) -> *const A::Item;
631  }
632
633  /// Walk the vec and keep only the elements that pass the predicate given.
634  ///
635  /// ## Example
636  ///
637  /// ```rust
638  /// use tinyvec::*;
639  ///
640  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
641  /// tv.retain(|&x| x % 2 == 0);
642  /// assert_eq!(tv.as_slice(), &[2, 4][..]);
643  /// ```
644  #[inline]
645  pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, acceptable: F) {
646    match self {
647      TinyVec::Inline(i) => i.retain(acceptable),
648      TinyVec::Heap(h) => h.retain(acceptable),
649    }
650  }
651
652  /// Walk the vec and keep only the elements that pass the predicate given,
653  /// having the opportunity to modify the elements at the same time.
654  ///
655  /// ## Example
656  ///
657  /// ```rust
658  /// use tinyvec::*;
659  ///
660  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
661  /// tv.retain_mut(|x| if *x % 2 == 0 { *x *= 2; true } else { false });
662  /// assert_eq!(tv.as_slice(), &[4, 8][..]);
663  /// ```
664  #[inline]
665  #[cfg(feature = "rustc_1_61")]
666  pub fn retain_mut<F: FnMut(&mut A::Item) -> bool>(&mut self, acceptable: F) {
667    match self {
668      TinyVec::Inline(i) => i.retain_mut(acceptable),
669      TinyVec::Heap(h) => h.retain_mut(acceptable),
670    }
671  }
672
673  /// Helper for getting the mut slice.
674  #[inline(always)]
675  #[must_use]
676  pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
677    self.deref_mut()
678  }
679
680  /// Helper for getting the shared slice.
681  #[inline(always)]
682  #[must_use]
683  pub fn as_slice(&self) -> &[A::Item] {
684    self.deref()
685  }
686
687  /// Removes all elements from the vec.
688  #[inline(always)]
689  pub fn clear(&mut self) {
690    self.truncate(0)
691  }
692
693  /// De-duplicates the vec.
694  #[cfg(feature = "nightly_slice_partition_dedup")]
695  #[inline(always)]
696  pub fn dedup(&mut self)
697  where
698    A::Item: PartialEq,
699  {
700    self.dedup_by(|a, b| a == b)
701  }
702
703  /// De-duplicates the vec according to the predicate given.
704  #[cfg(feature = "nightly_slice_partition_dedup")]
705  #[inline(always)]
706  pub fn dedup_by<F>(&mut self, same_bucket: F)
707  where
708    F: FnMut(&mut A::Item, &mut A::Item) -> bool,
709  {
710    let len = {
711      let (dedup, _) = self.as_mut_slice().partition_dedup_by(same_bucket);
712      dedup.len()
713    };
714    self.truncate(len);
715  }
716
717  /// De-duplicates the vec according to the key selector given.
718  #[cfg(feature = "nightly_slice_partition_dedup")]
719  #[inline(always)]
720  pub fn dedup_by_key<F, K>(&mut self, mut key: F)
721  where
722    F: FnMut(&mut A::Item) -> K,
723    K: PartialEq,
724  {
725    self.dedup_by(|a, b| key(a) == key(b))
726  }
727
728  /// Creates a draining iterator that removes the specified range in the vector
729  /// and yields the removed items.
730  ///
731  /// **Note: This method has significant performance issues compared to
732  /// matching on the TinyVec and then calling drain on the Inline or Heap value
733  /// inside. The draining iterator has to branch on every single access. It is
734  /// provided for simplicity and compatibility only.**
735  ///
736  /// ## Panics
737  /// * If the start is greater than the end
738  /// * If the end is past the edge of the vec.
739  ///
740  /// ## Example
741  /// ```rust
742  /// use tinyvec::*;
743  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
744  /// let tv2: TinyVec<[i32; 4]> = tv.drain(1..).collect();
745  /// assert_eq!(tv.as_slice(), &[1][..]);
746  /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
747  ///
748  /// tv.drain(..);
749  /// assert_eq!(tv.as_slice(), &[]);
750  /// ```
751  #[inline]
752  pub fn drain<R: RangeBounds<usize>>(
753    &mut self, range: R,
754  ) -> TinyVecDrain<'_, A> {
755    match self {
756      TinyVec::Inline(i) => TinyVecDrain::Inline(i.drain(range)),
757      TinyVec::Heap(h) => TinyVecDrain::Heap(h.drain(range)),
758    }
759  }
760
761  /// Clone each element of the slice into this vec.
762  /// ```rust
763  /// use tinyvec::*;
764  /// let mut tv = tiny_vec!([i32; 4] => 1, 2);
765  /// tv.extend_from_slice(&[3, 4]);
766  /// assert_eq!(tv.as_slice(), [1, 2, 3, 4]);
767  /// ```
768  #[inline]
769  pub fn extend_from_slice(&mut self, sli: &[A::Item])
770  where
771    A::Item: Clone,
772  {
773    self.reserve(sli.len());
774    match self {
775      TinyVec::Inline(a) => a.extend_from_slice(sli),
776      TinyVec::Heap(h) => h.extend_from_slice(sli),
777    }
778  }
779
780  /// Wraps up an array and uses the given length as the initial length.
781  ///
782  /// Note that the `From` impl for arrays assumes the full length is used.
783  ///
784  /// ## Panics
785  ///
786  /// The length must be less than or equal to the capacity of the array.
787  #[inline]
788  #[must_use]
789  #[allow(clippy::match_wild_err_arm)]
790  pub fn from_array_len(data: A, len: usize) -> Self {
791    match Self::try_from_array_len(data, len) {
792      Ok(out) => out,
793      Err(_) => {
794        panic!("TinyVec: length {} exceeds capacity {}!", len, A::CAPACITY)
795      }
796    }
797  }
798
799  /// This is an internal implementation detail of the `tiny_vec!` macro, and
800  /// using it other than from that macro is not supported by this crate's
801  /// SemVer guarantee.
802  #[inline(always)]
803  #[doc(hidden)]
804  pub fn constructor_for_capacity(cap: usize) -> TinyVecConstructor<A> {
805    if cap <= A::CAPACITY {
806      TinyVecConstructor::Inline(TinyVec::Inline)
807    } else {
808      TinyVecConstructor::Heap(TinyVec::Heap)
809    }
810  }
811
812  /// Inserts an item at the position given, moving all following elements +1
813  /// index.
814  ///
815  /// ## Panics
816  /// * If `index` > `len`
817  ///
818  /// ## Example
819  /// ```rust
820  /// use tinyvec::*;
821  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3);
822  /// tv.insert(1, 4);
823  /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3]);
824  /// tv.insert(4, 5);
825  /// assert_eq!(tv.as_slice(), &[1, 4, 2, 3, 5]);
826  /// ```
827  #[inline]
828  pub fn insert(&mut self, index: usize, item: A::Item) {
829    assert!(
830      index <= self.len(),
831      "insertion index (is {}) should be <= len (is {})",
832      index,
833      self.len()
834    );
835
836    let arr = match self {
837      TinyVec::Heap(v) => return v.insert(index, item),
838      TinyVec::Inline(a) => a,
839    };
840
841    if let Some(x) = arr.try_insert(index, item) {
842      let mut v = Vec::with_capacity(arr.len() * 2);
843      let mut it = arr.iter_mut().map(core::mem::take);
844      v.extend(it.by_ref().take(index));
845      v.push(x);
846      v.extend(it);
847      *self = TinyVec::Heap(v);
848    }
849  }
850
851  /// If the vec is empty.
852  #[inline(always)]
853  #[must_use]
854  pub fn is_empty(&self) -> bool {
855    self.len() == 0
856  }
857
858  /// Makes a new, empty vec.
859  #[inline(always)]
860  #[must_use]
861  pub fn new() -> Self {
862    Self::default()
863  }
864
865  /// Place an element onto the end of the vec.
866  #[inline]
867  pub fn push(&mut self, val: A::Item) {
868    // The code path for moving the inline contents to the heap produces a lot
869    // of instructions, but we have a strong guarantee that this is a cold
870    // path. LLVM doesn't know this, inlines it, and this tends to cause a
871    // cascade of other bad inlining decisions because the body of push looks
872    // huge even though nearly every call executes the same few instructions.
873    //
874    // Moving the logic out of line with #[cold] causes the hot code to  be
875    // inlined together, and we take the extra cost of a function call only
876    // in rare cases.
877    #[cold]
878    fn drain_to_heap_and_push<A: Array>(
879      arr: &mut ArrayVec<A>, val: A::Item,
880    ) -> TinyVec<A> {
881      /* Make the Vec twice the size to amortize the cost of draining */
882      let mut v = arr.drain_to_vec_and_reserve(arr.len());
883      v.push(val);
884      TinyVec::Heap(v)
885    }
886
887    match self {
888      TinyVec::Heap(v) => v.push(val),
889      TinyVec::Inline(arr) => {
890        if let Some(x) = arr.try_push(val) {
891          *self = drain_to_heap_and_push(arr, x);
892        }
893      }
894    }
895  }
896
897  /// Resize the vec to the new length.
898  ///
899  /// If it needs to be longer, it's filled with clones of the provided value.
900  /// If it needs to be shorter, it's truncated.
901  ///
902  /// ## Example
903  ///
904  /// ```rust
905  /// use tinyvec::*;
906  ///
907  /// let mut tv = tiny_vec!([&str; 10] => "hello");
908  /// tv.resize(3, "world");
909  /// assert_eq!(tv.as_slice(), &["hello", "world", "world"][..]);
910  ///
911  /// let mut tv = tiny_vec!([i32; 10] => 1, 2, 3, 4);
912  /// tv.resize(2, 0);
913  /// assert_eq!(tv.as_slice(), &[1, 2][..]);
914  /// ```
915  #[inline]
916  pub fn resize(&mut self, new_len: usize, new_val: A::Item)
917  where
918    A::Item: Clone,
919  {
920    self.resize_with(new_len, || new_val.clone());
921  }
922
923  /// Resize the vec to the new length.
924  ///
925  /// If it needs to be longer, it's filled with repeated calls to the provided
926  /// function. If it needs to be shorter, it's truncated.
927  ///
928  /// ## Example
929  ///
930  /// ```rust
931  /// use tinyvec::*;
932  ///
933  /// let mut tv = tiny_vec!([i32; 3] => 1, 2, 3);
934  /// tv.resize_with(5, Default::default);
935  /// assert_eq!(tv.as_slice(), &[1, 2, 3, 0, 0][..]);
936  ///
937  /// let mut tv = tiny_vec!([i32; 2]);
938  /// let mut p = 1;
939  /// tv.resize_with(4, || {
940  ///   p *= 2;
941  ///   p
942  /// });
943  /// assert_eq!(tv.as_slice(), &[2, 4, 8, 16][..]);
944  /// ```
945  #[inline]
946  pub fn resize_with<F: FnMut() -> A::Item>(&mut self, new_len: usize, f: F) {
947    match new_len.checked_sub(self.len()) {
948      None => return self.truncate(new_len),
949      Some(n) => self.reserve(n),
950    }
951
952    match self {
953      TinyVec::Inline(a) => a.resize_with(new_len, f),
954      TinyVec::Heap(v) => v.resize_with(new_len, f),
955    }
956  }
957
958  /// Splits the collection at the point given.
959  ///
960  /// * `[0, at)` stays in this vec
961  /// * `[at, len)` ends up in the new vec.
962  ///
963  /// ## Panics
964  /// * if at > len
965  ///
966  /// ## Example
967  ///
968  /// ```rust
969  /// use tinyvec::*;
970  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
971  /// let tv2 = tv.split_off(1);
972  /// assert_eq!(tv.as_slice(), &[1][..]);
973  /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
974  /// ```
975  #[inline]
976  pub fn split_off(&mut self, at: usize) -> Self {
977    match self {
978      TinyVec::Inline(a) => TinyVec::Inline(a.split_off(at)),
979      TinyVec::Heap(v) => TinyVec::Heap(v.split_off(at)),
980    }
981  }
982
983  /// Creates a splicing iterator that removes the specified range in the
984  /// vector, yields the removed items, and replaces them with elements from
985  /// the provided iterator.
986  ///
987  /// `splice` fuses the provided iterator, so elements after the first `None`
988  /// are ignored.
989  ///
990  /// ## Panics
991  /// * If the start is greater than the end.
992  /// * If the end is past the edge of the vec.
993  /// * If the provided iterator panics.
994  ///
995  /// ## Example
996  /// ```rust
997  /// use tinyvec::*;
998  /// let mut tv = tiny_vec!([i32; 4] => 1, 2, 3);
999  /// let tv2: TinyVec<[i32; 4]> = tv.splice(1.., 4..=6).collect();
1000  /// assert_eq!(tv.as_slice(), &[1, 4, 5, 6][..]);
1001  /// assert_eq!(tv2.as_slice(), &[2, 3][..]);
1002  ///
1003  /// tv.splice(.., None);
1004  /// assert_eq!(tv.as_slice(), &[]);
1005  /// ```
1006  #[inline]
1007  pub fn splice<R, I>(
1008    &mut self, range: R, replacement: I,
1009  ) -> TinyVecSplice<'_, A, core::iter::Fuse<I::IntoIter>>
1010  where
1011    R: RangeBounds<usize>,
1012    I: IntoIterator<Item = A::Item>,
1013  {
1014    use core::ops::Bound;
1015    let start = match range.start_bound() {
1016      Bound::Included(x) => *x,
1017      Bound::Excluded(x) => x.saturating_add(1),
1018      Bound::Unbounded => 0,
1019    };
1020    let end = match range.end_bound() {
1021      Bound::Included(x) => x.saturating_add(1),
1022      Bound::Excluded(x) => *x,
1023      Bound::Unbounded => self.len(),
1024    };
1025    assert!(
1026      start <= end,
1027      "TinyVec::splice> Illegal range, {} to {}",
1028      start,
1029      end
1030    );
1031    assert!(
1032      end <= self.len(),
1033      "TinyVec::splice> Range ends at {} but length is only {}!",
1034      end,
1035      self.len()
1036    );
1037
1038    TinyVecSplice {
1039      removal_start: start,
1040      removal_end: end,
1041      parent: self,
1042      replacement: replacement.into_iter().fuse(),
1043    }
1044  }
1045
1046  /// Wraps an array, using the given length as the starting length.
1047  ///
1048  /// If you want to use the whole length of the array, you can just use the
1049  /// `From` impl.
1050  ///
1051  /// ## Failure
1052  ///
1053  /// If the given length is greater than the capacity of the array this will
1054  /// error, and you'll get the array back in the `Err`.
1055  #[inline]
1056  pub fn try_from_array_len(data: A, len: usize) -> Result<Self, A> {
1057    let arr = ArrayVec::try_from_array_len(data, len)?;
1058    Ok(TinyVec::Inline(arr))
1059  }
1060}
1061
1062/// Draining iterator for `TinyVecDrain`
1063///
1064/// See [`TinyVecDrain::drain`](TinyVecDrain::<A>::drain)
1065#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1066pub enum TinyVecDrain<'p, A: Array> {
1067  #[allow(missing_docs)]
1068  Inline(ArrayVecDrain<'p, A::Item>),
1069  #[allow(missing_docs)]
1070  Heap(vec::Drain<'p, A::Item>),
1071}
1072
1073impl<'p, A: Array> Iterator for TinyVecDrain<'p, A> {
1074  type Item = A::Item;
1075
1076  impl_mirrored! {
1077    type Mirror = TinyVecDrain;
1078
1079    #[inline]
1080    fn next(self: &mut Self) -> Option<Self::Item>;
1081    #[inline]
1082    fn nth(self: &mut Self, n: usize) -> Option<Self::Item>;
1083    #[inline]
1084    fn size_hint(self: &Self) -> (usize, Option<usize>);
1085    #[inline]
1086    fn last(self: Self) -> Option<Self::Item>;
1087    #[inline]
1088    fn count(self: Self) -> usize;
1089  }
1090
1091  #[inline]
1092  fn for_each<F: FnMut(Self::Item)>(self, f: F) {
1093    match self {
1094      TinyVecDrain::Inline(i) => i.for_each(f),
1095      TinyVecDrain::Heap(h) => h.for_each(f),
1096    }
1097  }
1098}
1099
1100impl<'p, A: Array> DoubleEndedIterator for TinyVecDrain<'p, A> {
1101  impl_mirrored! {
1102    type Mirror = TinyVecDrain;
1103
1104    #[inline]
1105    fn next_back(self: &mut Self) -> Option<Self::Item>;
1106
1107    #[inline]
1108    fn nth_back(self: &mut Self, n: usize) -> Option<Self::Item>;
1109  }
1110}
1111
1112/// Splicing iterator for `TinyVec`
1113/// See [`TinyVec::splice`](TinyVec::<A>::splice)
1114#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1115pub struct TinyVecSplice<'p, A: Array, I: Iterator<Item = A::Item>> {
1116  parent: &'p mut TinyVec<A>,
1117  removal_start: usize,
1118  removal_end: usize,
1119  replacement: I,
1120}
1121
1122impl<'p, A, I> Iterator for TinyVecSplice<'p, A, I>
1123where
1124  A: Array,
1125  I: Iterator<Item = A::Item>,
1126{
1127  type Item = A::Item;
1128
1129  #[inline]
1130  fn next(&mut self) -> Option<A::Item> {
1131    if self.removal_start < self.removal_end {
1132      match self.replacement.next() {
1133        Some(replacement) => {
1134          let removed = core::mem::replace(
1135            &mut self.parent[self.removal_start],
1136            replacement,
1137          );
1138          self.removal_start += 1;
1139          Some(removed)
1140        }
1141        None => {
1142          let removed = self.parent.remove(self.removal_start);
1143          self.removal_end -= 1;
1144          Some(removed)
1145        }
1146      }
1147    } else {
1148      None
1149    }
1150  }
1151
1152  #[inline]
1153  fn size_hint(&self) -> (usize, Option<usize>) {
1154    let len = self.len();
1155    (len, Some(len))
1156  }
1157}
1158
1159impl<'p, A, I> ExactSizeIterator for TinyVecSplice<'p, A, I>
1160where
1161  A: Array,
1162  I: Iterator<Item = A::Item>,
1163{
1164  #[inline]
1165  fn len(&self) -> usize {
1166    self.removal_end - self.removal_start
1167  }
1168}
1169
1170impl<'p, A, I> FusedIterator for TinyVecSplice<'p, A, I>
1171where
1172  A: Array,
1173  I: Iterator<Item = A::Item>,
1174{
1175}
1176
1177impl<'p, A, I> DoubleEndedIterator for TinyVecSplice<'p, A, I>
1178where
1179  A: Array,
1180  I: Iterator<Item = A::Item> + DoubleEndedIterator,
1181{
1182  #[inline]
1183  fn next_back(&mut self) -> Option<A::Item> {
1184    if self.removal_start < self.removal_end {
1185      match self.replacement.next_back() {
1186        Some(replacement) => {
1187          let removed = core::mem::replace(
1188            &mut self.parent[self.removal_end - 1],
1189            replacement,
1190          );
1191          self.removal_end -= 1;
1192          Some(removed)
1193        }
1194        None => {
1195          let removed = self.parent.remove(self.removal_end - 1);
1196          self.removal_end -= 1;
1197          Some(removed)
1198        }
1199      }
1200    } else {
1201      None
1202    }
1203  }
1204}
1205
1206impl<'p, A: Array, I: Iterator<Item = A::Item>> Drop
1207  for TinyVecSplice<'p, A, I>
1208{
1209  #[inline]
1210  fn drop(&mut self) {
1211    for _ in self.by_ref() {}
1212
1213    let (lower_bound, _) = self.replacement.size_hint();
1214    self.parent.reserve(lower_bound);
1215
1216    for replacement in self.replacement.by_ref() {
1217      self.parent.insert(self.removal_end, replacement);
1218      self.removal_end += 1;
1219    }
1220  }
1221}
1222
1223impl<A: Array> AsMut<[A::Item]> for TinyVec<A> {
1224  #[inline(always)]
1225  #[must_use]
1226  fn as_mut(&mut self) -> &mut [A::Item] {
1227    &mut *self
1228  }
1229}
1230
1231impl<A: Array> AsRef<[A::Item]> for TinyVec<A> {
1232  #[inline(always)]
1233  #[must_use]
1234  fn as_ref(&self) -> &[A::Item] {
1235    &*self
1236  }
1237}
1238
1239impl<A: Array> Borrow<[A::Item]> for TinyVec<A> {
1240  #[inline(always)]
1241  #[must_use]
1242  fn borrow(&self) -> &[A::Item] {
1243    &*self
1244  }
1245}
1246
1247impl<A: Array> BorrowMut<[A::Item]> for TinyVec<A> {
1248  #[inline(always)]
1249  #[must_use]
1250  fn borrow_mut(&mut self) -> &mut [A::Item] {
1251    &mut *self
1252  }
1253}
1254
1255impl<A: Array> Extend<A::Item> for TinyVec<A> {
1256  #[inline]
1257  fn extend<T: IntoIterator<Item = A::Item>>(&mut self, iter: T) {
1258    let iter = iter.into_iter();
1259    let (lower_bound, _) = iter.size_hint();
1260    self.reserve(lower_bound);
1261
1262    let a = match self {
1263      TinyVec::Heap(h) => return h.extend(iter),
1264      TinyVec::Inline(a) => a,
1265    };
1266
1267    let mut iter = a.fill(iter);
1268    let maybe = iter.next();
1269
1270    let surely = match maybe {
1271      Some(x) => x,
1272      None => return,
1273    };
1274
1275    let mut v = a.drain_to_vec_and_reserve(a.len());
1276    v.push(surely);
1277    v.extend(iter);
1278    *self = TinyVec::Heap(v);
1279  }
1280}
1281
1282impl<A: Array> From<ArrayVec<A>> for TinyVec<A> {
1283  #[inline(always)]
1284  #[must_use]
1285  fn from(arr: ArrayVec<A>) -> Self {
1286    TinyVec::Inline(arr)
1287  }
1288}
1289
1290impl<A: Array> From<A> for TinyVec<A> {
1291  #[inline]
1292  fn from(array: A) -> Self {
1293    TinyVec::Inline(ArrayVec::from(array))
1294  }
1295}
1296
1297impl<T, A> From<&'_ [T]> for TinyVec<A>
1298where
1299  T: Clone + Default,
1300  A: Array<Item = T>,
1301{
1302  #[inline]
1303  #[must_use]
1304  fn from(slice: &[T]) -> Self {
1305    if let Ok(arr) = ArrayVec::try_from(slice) {
1306      TinyVec::Inline(arr)
1307    } else {
1308      TinyVec::Heap(slice.into())
1309    }
1310  }
1311}
1312
1313impl<T, A> From<&'_ mut [T]> for TinyVec<A>
1314where
1315  T: Clone + Default,
1316  A: Array<Item = T>,
1317{
1318  #[inline]
1319  #[must_use]
1320  fn from(slice: &mut [T]) -> Self {
1321    Self::from(&*slice)
1322  }
1323}
1324
1325impl<A: Array> FromIterator<A::Item> for TinyVec<A> {
1326  #[inline]
1327  #[must_use]
1328  fn from_iter<T: IntoIterator<Item = A::Item>>(iter: T) -> Self {
1329    let mut av = Self::default();
1330    av.extend(iter);
1331    av
1332  }
1333}
1334
1335/// Iterator for consuming an `TinyVec` and returning owned elements.
1336#[cfg_attr(docsrs, doc(cfg(feature = "alloc")))]
1337pub enum TinyVecIterator<A: Array> {
1338  #[allow(missing_docs)]
1339  Inline(ArrayVecIterator<A>),
1340  #[allow(missing_docs)]
1341  Heap(alloc::vec::IntoIter<A::Item>),
1342}
1343
1344impl<A: Array> TinyVecIterator<A> {
1345  impl_mirrored! {
1346    type Mirror = TinyVecIterator;
1347    /// Returns the remaining items of this iterator as a slice.
1348    #[inline]
1349    #[must_use]
1350    pub fn as_slice(self: &Self) -> &[A::Item];
1351  }
1352}
1353
1354impl<A: Array> FusedIterator for TinyVecIterator<A> {}
1355
1356impl<A: Array> Iterator for TinyVecIterator<A> {
1357  type Item = A::Item;
1358
1359  impl_mirrored! {
1360    type Mirror = TinyVecIterator;
1361
1362    #[inline]
1363    fn next(self: &mut Self) -> Option<Self::Item>;
1364
1365    #[inline(always)]
1366    #[must_use]
1367    fn size_hint(self: &Self) -> (usize, Option<usize>);
1368
1369    #[inline(always)]
1370    fn count(self: Self) -> usize;
1371
1372    #[inline]
1373    fn last(self: Self) -> Option<Self::Item>;
1374
1375    #[inline]
1376    fn nth(self: &mut Self, n: usize) -> Option<A::Item>;
1377  }
1378}
1379
1380impl<A: Array> DoubleEndedIterator for TinyVecIterator<A> {
1381  impl_mirrored! {
1382    type Mirror = TinyVecIterator;
1383
1384    #[inline]
1385    fn next_back(self: &mut Self) -> Option<Self::Item>;
1386
1387    #[inline]
1388    fn nth_back(self: &mut Self, n: usize) -> Option<Self::Item>;
1389  }
1390}
1391
1392impl<A: Array> ExactSizeIterator for TinyVecIterator<A> {
1393  impl_mirrored! {
1394    type Mirror = TinyVecIterator;
1395    #[inline]
1396    fn len(self: &Self) -> usize;
1397  }
1398}
1399
1400impl<A: Array> Debug for TinyVecIterator<A>
1401where
1402  A::Item: Debug,
1403{
1404  #[allow(clippy::missing_inline_in_public_items)]
1405  fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
1406    f.debug_tuple("TinyVecIterator").field(&self.as_slice()).finish()
1407  }
1408}
1409
1410impl<A: Array> IntoIterator for TinyVec<A> {
1411  type Item = A::Item;
1412  type IntoIter = TinyVecIterator<A>;
1413  #[inline(always)]
1414  #[must_use]
1415  fn into_iter(self) -> Self::IntoIter {
1416    match self {
1417      TinyVec::Inline(a) => TinyVecIterator::Inline(a.into_iter()),
1418      TinyVec::Heap(v) => TinyVecIterator::Heap(v.into_iter()),
1419    }
1420  }
1421}
1422
1423impl<'a, A: Array> IntoIterator for &'a mut TinyVec<A> {
1424  type Item = &'a mut A::Item;
1425  type IntoIter = core::slice::IterMut<'a, A::Item>;
1426  #[inline(always)]
1427  #[must_use]
1428  fn into_iter(self) -> Self::IntoIter {
1429    self.iter_mut()
1430  }
1431}
1432
1433impl<'a, A: Array> IntoIterator for &'a TinyVec<A> {
1434  type Item = &'a A::Item;
1435  type IntoIter = core::slice::Iter<'a, A::Item>;
1436  #[inline(always)]
1437  #[must_use]
1438  fn into_iter(self) -> Self::IntoIter {
1439    self.iter()
1440  }
1441}
1442
1443impl<A: Array> PartialEq for TinyVec<A>
1444where
1445  A::Item: PartialEq,
1446{
1447  #[inline]
1448  #[must_use]
1449  fn eq(&self, other: &Self) -> bool {
1450    self.as_slice().eq(other.as_slice())
1451  }
1452}
1453impl<A: Array> Eq for TinyVec<A> where A::Item: Eq {}
1454
1455impl<A: Array> PartialOrd for TinyVec<A>
1456where
1457  A::Item: PartialOrd,
1458{
1459  #[inline]
1460  #[must_use]
1461  fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
1462    self.as_slice().partial_cmp(other.as_slice())
1463  }
1464}
1465impl<A: Array> Ord for TinyVec<A>
1466where
1467  A::Item: Ord,
1468{
1469  #[inline]
1470  #[must_use]
1471  fn cmp(&self, other: &Self) -> core::cmp::Ordering {
1472    self.as_slice().cmp(other.as_slice())
1473  }
1474}
1475
1476impl<A: Array> PartialEq<&A> for TinyVec<A>
1477where
1478  A::Item: PartialEq,
1479{
1480  #[inline]
1481  #[must_use]
1482  fn eq(&self, other: &&A) -> bool {
1483    self.as_slice().eq(other.as_slice())
1484  }
1485}
1486
1487impl<A: Array> PartialEq<&[A::Item]> for TinyVec<A>
1488where
1489  A::Item: PartialEq,
1490{
1491  #[inline]
1492  #[must_use]
1493  fn eq(&self, other: &&[A::Item]) -> bool {
1494    self.as_slice().eq(*other)
1495  }
1496}
1497
1498impl<A: Array> Hash for TinyVec<A>
1499where
1500  A::Item: Hash,
1501{
1502  #[inline]
1503  fn hash<H: Hasher>(&self, state: &mut H) {
1504    self.as_slice().hash(state)
1505  }
1506}
1507
1508// // // // // // // //
1509// Formatting impls
1510// // // // // // // //
1511
1512impl<A: Array> Binary for TinyVec<A>
1513where
1514  A::Item: Binary,
1515{
1516  #[allow(clippy::missing_inline_in_public_items)]
1517  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1518    write!(f, "[")?;
1519    if f.alternate() {
1520      write!(f, "\n    ")?;
1521    }
1522    for (i, elem) in self.iter().enumerate() {
1523      if i > 0 {
1524        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1525      }
1526      Binary::fmt(elem, f)?;
1527    }
1528    if f.alternate() {
1529      write!(f, ",\n")?;
1530    }
1531    write!(f, "]")
1532  }
1533}
1534
1535impl<A: Array> Debug for TinyVec<A>
1536where
1537  A::Item: Debug,
1538{
1539  #[allow(clippy::missing_inline_in_public_items)]
1540  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1541    write!(f, "[")?;
1542    if f.alternate() && !self.is_empty() {
1543      write!(f, "\n    ")?;
1544    }
1545    for (i, elem) in self.iter().enumerate() {
1546      if i > 0 {
1547        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1548      }
1549      Debug::fmt(elem, f)?;
1550    }
1551    if f.alternate() && !self.is_empty() {
1552      write!(f, ",\n")?;
1553    }
1554    write!(f, "]")
1555  }
1556}
1557
1558impl<A: Array> Display for TinyVec<A>
1559where
1560  A::Item: Display,
1561{
1562  #[allow(clippy::missing_inline_in_public_items)]
1563  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1564    write!(f, "[")?;
1565    if f.alternate() {
1566      write!(f, "\n    ")?;
1567    }
1568    for (i, elem) in self.iter().enumerate() {
1569      if i > 0 {
1570        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1571      }
1572      Display::fmt(elem, f)?;
1573    }
1574    if f.alternate() {
1575      write!(f, ",\n")?;
1576    }
1577    write!(f, "]")
1578  }
1579}
1580
1581impl<A: Array> LowerExp for TinyVec<A>
1582where
1583  A::Item: LowerExp,
1584{
1585  #[allow(clippy::missing_inline_in_public_items)]
1586  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1587    write!(f, "[")?;
1588    if f.alternate() {
1589      write!(f, "\n    ")?;
1590    }
1591    for (i, elem) in self.iter().enumerate() {
1592      if i > 0 {
1593        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1594      }
1595      LowerExp::fmt(elem, f)?;
1596    }
1597    if f.alternate() {
1598      write!(f, ",\n")?;
1599    }
1600    write!(f, "]")
1601  }
1602}
1603
1604impl<A: Array> LowerHex for TinyVec<A>
1605where
1606  A::Item: LowerHex,
1607{
1608  #[allow(clippy::missing_inline_in_public_items)]
1609  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1610    write!(f, "[")?;
1611    if f.alternate() {
1612      write!(f, "\n    ")?;
1613    }
1614    for (i, elem) in self.iter().enumerate() {
1615      if i > 0 {
1616        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1617      }
1618      LowerHex::fmt(elem, f)?;
1619    }
1620    if f.alternate() {
1621      write!(f, ",\n")?;
1622    }
1623    write!(f, "]")
1624  }
1625}
1626
1627impl<A: Array> Octal for TinyVec<A>
1628where
1629  A::Item: Octal,
1630{
1631  #[allow(clippy::missing_inline_in_public_items)]
1632  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1633    write!(f, "[")?;
1634    if f.alternate() {
1635      write!(f, "\n    ")?;
1636    }
1637    for (i, elem) in self.iter().enumerate() {
1638      if i > 0 {
1639        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1640      }
1641      Octal::fmt(elem, f)?;
1642    }
1643    if f.alternate() {
1644      write!(f, ",\n")?;
1645    }
1646    write!(f, "]")
1647  }
1648}
1649
1650impl<A: Array> Pointer for TinyVec<A>
1651where
1652  A::Item: Pointer,
1653{
1654  #[allow(clippy::missing_inline_in_public_items)]
1655  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1656    write!(f, "[")?;
1657    if f.alternate() {
1658      write!(f, "\n    ")?;
1659    }
1660    for (i, elem) in self.iter().enumerate() {
1661      if i > 0 {
1662        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1663      }
1664      Pointer::fmt(elem, f)?;
1665    }
1666    if f.alternate() {
1667      write!(f, ",\n")?;
1668    }
1669    write!(f, "]")
1670  }
1671}
1672
1673impl<A: Array> UpperExp for TinyVec<A>
1674where
1675  A::Item: UpperExp,
1676{
1677  #[allow(clippy::missing_inline_in_public_items)]
1678  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1679    write!(f, "[")?;
1680    if f.alternate() {
1681      write!(f, "\n    ")?;
1682    }
1683    for (i, elem) in self.iter().enumerate() {
1684      if i > 0 {
1685        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1686      }
1687      UpperExp::fmt(elem, f)?;
1688    }
1689    if f.alternate() {
1690      write!(f, ",\n")?;
1691    }
1692    write!(f, "]")
1693  }
1694}
1695
1696impl<A: Array> UpperHex for TinyVec<A>
1697where
1698  A::Item: UpperHex,
1699{
1700  #[allow(clippy::missing_inline_in_public_items)]
1701  fn fmt(&self, f: &mut Formatter) -> core::fmt::Result {
1702    write!(f, "[")?;
1703    if f.alternate() {
1704      write!(f, "\n    ")?;
1705    }
1706    for (i, elem) in self.iter().enumerate() {
1707      if i > 0 {
1708        write!(f, ",{}", if f.alternate() { "\n    " } else { " " })?;
1709      }
1710      UpperHex::fmt(elem, f)?;
1711    }
1712    if f.alternate() {
1713      write!(f, ",\n")?;
1714    }
1715    write!(f, "]")
1716  }
1717}
1718
1719#[cfg(feature = "serde")]
1720#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
1721struct TinyVecVisitor<A: Array>(PhantomData<A>);
1722
1723#[cfg(feature = "serde")]
1724impl<'de, A: Array> Visitor<'de> for TinyVecVisitor<A>
1725where
1726  A::Item: Deserialize<'de>,
1727{
1728  type Value = TinyVec<A>;
1729
1730  fn expecting(
1731    &self, formatter: &mut core::fmt::Formatter,
1732  ) -> core::fmt::Result {
1733    formatter.write_str("a sequence")
1734  }
1735
1736  fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
1737  where
1738    S: SeqAccess<'de>,
1739  {
1740    let mut new_tinyvec = match seq.size_hint() {
1741      Some(expected_size) => TinyVec::with_capacity(expected_size),
1742      None => Default::default(),
1743    };
1744
1745    while let Some(value) = seq.next_element()? {
1746      new_tinyvec.push(value);
1747    }
1748
1749    Ok(new_tinyvec)
1750  }
1751}