Skip to main content

small_collections/
small_vec.rs

1extern crate alloc;
2
3use alloc::{borrow::Cow, collections::VecDeque, vec::Vec};
4use core::{
5    borrow::{Borrow, BorrowMut},
6    cmp::Ordering,
7    fmt,
8    hash::{Hash, Hasher},
9    ops::{Deref, DerefMut, Index, IndexMut, Range, RangeBounds},
10    slice::{Iter, IterMut, SliceIndex},
11};
12
13/// A vector that stores its first `N` elements inline (on the stack) and
14/// spills onto the heap once it grows past that inline capacity.
15///
16/// `SmallVec` behaves like [`alloc::vec::Vec`] for the operations it exposes:
17/// it dereferences to `[T]`, so all slice methods are available. The only
18/// difference is *where* short sequences are stored: values fitting in `N`
19/// elements never touch the allocator.
20///
21/// # Examples
22///
23/// ```
24/// use small_collections::SmallVec;
25///
26/// let mut v: SmallVec<i32, 4> = SmallVec::new();
27/// v.push(1);
28/// v.push(2);
29/// assert!(v.is_inline());
30/// assert_eq!(&*v, &[1, 2]);
31///
32/// // Pushing past `N` automatically spills onto the heap.
33/// for i in 0..4 {
34///     v.push(i);
35/// }
36/// assert!(!v.is_inline());
37/// assert_eq!(v.len(), 6);
38/// ```
39///
40/// # Invariants
41///
42/// * The `Inline` variant never holds more than `N` elements.
43/// * A value only ever moves from `Inline` to `Heap` on growth; it moves back
44///   to `Inline` only through [`SmallVec::shrink_to_fit`] or
45///   [`SmallVec::shrink_to`]. [`SmallVec::clear`] and
46///   [`SmallVec::truncate`] keep the current storage.
47#[derive(Clone)]
48pub enum SmallVec<T, const N: usize> {
49    /// Data stored inline, on the stack, with a fixed capacity of `N`.
50    Inline(heapless::Vec<T, N>),
51    /// Data spilled onto the heap, growing as needed.
52    Heap(Vec<T>),
53}
54
55impl<T, const N: usize> SmallVec<T, N> {
56    /// Creates a new, empty `SmallVec` using its inline storage.
57    ///
58    /// This never allocates.
59    #[inline]
60    pub const fn new() -> Self {
61        SmallVec::Inline(heapless::Vec::new())
62    }
63
64    /// Returns the inline capacity, `N`.
65    #[inline]
66    pub const fn inline_size() -> usize {
67        N
68    }
69
70    /// Creates a new, empty `SmallVec` with at least the requested capacity.
71    ///
72    /// If `capacity <= N`, the result uses its inline storage (and therefore
73    /// reports a capacity of `N`). Otherwise a heap buffer with the requested
74    /// capacity is allocated.
75    #[inline]
76    pub fn with_capacity(capacity: usize) -> Self {
77        if capacity <= N {
78            Self::new()
79        } else {
80            SmallVec::Heap(Vec::with_capacity(capacity))
81        }
82    }
83
84    /// Builds a `SmallVec` from an array, storing it inline.
85    ///
86    /// The array length `S` must be less than or equal to `N`; this is checked
87    /// at compile time and a larger array fails to compile.
88    ///
89    /// # Examples
90    ///
91    /// ```
92    /// use small_collections::SmallVec;
93    ///
94    /// let v: SmallVec<i32, 4> = SmallVec::from_array([1, 2, 3]);
95    /// assert!(v.is_inline());
96    /// assert_eq!(&*v, &[1, 2, 3]);
97    /// ```
98    ///
99    /// An array larger than the inline capacity fails to compile:
100    ///
101    /// ```compile_fail
102    /// use small_collections::SmallVec;
103    ///
104    /// let v: SmallVec<i32, 2> = SmallVec::from_array([1, 2, 3]);
105    /// ```
106    #[inline]
107    pub const fn from_array<const S: usize>(elements: [T; S]) -> Self {
108        SmallVec::Inline(heapless::Vec::from_array(elements))
109    }
110
111    /// Builds an inline `SmallVec` containing the first `length` elements of a
112    /// full `[T; N]` buffer, dropping the remaining elements.
113    ///
114    /// # Panics
115    ///
116    /// Panics if `length > N`.
117    #[inline]
118    pub fn from_array_and_len(buf: [T; N], length: usize) -> Self {
119        assert!(length <= N, "`length` (is {length}) should be <= inline capacity (is {N})");
120        let mut v = heapless::Vec::<T, N>::from_array(buf);
121        v.truncate(length);
122        SmallVec::Inline(v)
123    }
124
125    /// Converts an [`alloc::vec::Vec`] into a `SmallVec`.
126    ///
127    /// An existing heap allocation is always preserved (like
128    /// [`SmallString::from_string`](crate::SmallString::from_string)), so even
129    /// a short vector stays on the heap. Use [`SmallVec::from_slice`] or the
130    /// `From<[T; M]>` impl if you want a short sequence to move inline. An
131    /// empty vector with no capacity returns an inline `SmallVec`.
132    #[inline]
133    pub fn from_vec(vec: Vec<T>) -> Self {
134        if vec.capacity() == 0 {
135            Self::new()
136        } else {
137            SmallVec::Heap(vec)
138        }
139    }
140
141    /// Clones a slice into a `SmallVec`, storing it inline when it fits.
142    ///
143    /// # Examples
144    ///
145    /// ```
146    /// use small_collections::SmallVec;
147    ///
148    /// let inline: SmallVec<u8, 4> = SmallVec::from_slice(&[1, 2, 3]);
149    /// assert!(inline.is_inline());
150    ///
151    /// let spilled: SmallVec<u8, 2> = SmallVec::from_slice(&[1, 2, 3]);
152    /// assert!(!spilled.is_inline());
153    /// ```
154    #[inline]
155    pub fn from_slice(slice: &[T]) -> Self
156    where
157        T: Clone,
158    {
159        if slice.len() <= N {
160            SmallVec::Inline(
161                heapless::Vec::from_slice(slice).unwrap_or_else(|_| unreachable!("slice length was checked against N")),
162            )
163        } else {
164            SmallVec::Heap(Vec::from(slice))
165        }
166    }
167
168    /// Moves the contents of a `SmallVec` with a different inline capacity into
169    /// this one.
170    ///
171    /// The elements are stored inline when they fit in `N`, otherwise they are
172    /// spilled onto the heap. Unlike [`SmallVec::from_vec`], this does not
173    /// preserve an existing heap allocation when it would fit inline.
174    #[inline]
175    pub fn from_small_vec<const M: usize>(input: SmallVec<T, M>) -> Self {
176        match input {
177            SmallVec::Heap(vec) => {
178                if vec.len() <= N {
179                    let mut this = Self::new();
180                    this.extend(vec);
181                    this
182                } else {
183                    SmallVec::Heap(vec)
184                }
185            }
186            SmallVec::Inline(vec) => {
187                let mut this = Self::new();
188                this.extend(vec);
189                this
190            }
191        }
192    }
193
194    /// Returns the number of elements in the vector.
195    #[inline]
196    pub fn len(&self) -> usize {
197        match self {
198            SmallVec::Inline(v) => v.len(),
199            SmallVec::Heap(v) => v.len(),
200        }
201    }
202
203    /// Returns `true` if the vector contains no elements.
204    #[inline]
205    pub fn is_empty(&self) -> bool {
206        self.len() == 0
207    }
208
209    /// Returns the total capacity, in elements, of the vector.
210    ///
211    /// For an inline vector this is always `N`; for a spilled vector it is the
212    /// current heap capacity.
213    #[inline]
214    pub fn capacity(&self) -> usize {
215        match self {
216            SmallVec::Inline(v) => v.capacity(),
217            SmallVec::Heap(v) => v.capacity(),
218        }
219    }
220
221    /// Returns `true` if the data is currently stored inline, on the stack.
222    #[inline]
223    pub fn is_inline(&self) -> bool {
224        matches!(self, SmallVec::Inline(_))
225    }
226
227    /// Extracts a slice containing the entire vector.
228    #[inline]
229    pub fn as_slice(&self) -> &[T] {
230        match self {
231            SmallVec::Inline(v) => v.as_slice(),
232            SmallVec::Heap(v) => v.as_slice(),
233        }
234    }
235
236    /// Extracts a mutable slice containing the entire vector.
237    #[inline]
238    pub fn as_mut_slice(&mut self) -> &mut [T] {
239        match self {
240            SmallVec::Inline(v) => v.as_mut_slice(),
241            SmallVec::Heap(v) => v.as_mut_slice(),
242        }
243    }
244
245    /// Returns a raw pointer to the first element, or a dangling-but-aligned
246    /// pointer when empty.
247    ///
248    /// The pointer only covers the initialized region (`len` elements), not
249    /// any spare capacity.
250    #[inline]
251    pub fn as_ptr(&self) -> *const T {
252        self.as_slice().as_ptr()
253    }
254
255    /// Returns a mutable raw pointer to the first element, or a
256    /// dangling-but-aligned pointer when empty.
257    ///
258    /// The pointer only covers the initialized region (`len` elements), not
259    /// any spare capacity.
260    #[inline]
261    pub fn as_mut_ptr(&mut self) -> *mut T {
262        self.as_mut_slice().as_mut_ptr()
263    }
264
265    /// Appends an element to the back of the vector, spilling onto the heap if
266    /// the inline capacity is exceeded.
267    #[inline]
268    pub fn push(&mut self, value: T) {
269        if let SmallVec::Inline(v) = self
270            && v.len() >= N
271        {
272            // Move everything to the heap, then push `value` below.
273            let cap = N.saturating_mul(2).max(1);
274            let mut heap: Vec<T> = Vec::with_capacity(cap);
275            heap.extend(core::mem::take(v));
276            *self = SmallVec::Heap(heap);
277        }
278
279        match self {
280            SmallVec::Inline(v) => {
281                if v.push(value).is_err() {
282                    unreachable!("inline capacity was checked before pushing");
283                }
284            }
285            SmallVec::Heap(v) => v.push(value),
286        }
287    }
288
289    /// Appends an element and returns a mutable reference to it.
290    #[inline]
291    pub fn push_mut(&mut self, value: T) -> &mut T {
292        self.push(value);
293        self.last_mut().expect("an element was just pushed")
294    }
295
296    /// Removes the last element and returns it, or `None` if empty.
297    #[inline]
298    pub fn pop(&mut self) -> Option<T> {
299        match self {
300            SmallVec::Inline(v) => v.pop(),
301            SmallVec::Heap(v) => v.pop(),
302        }
303    }
304
305    /// Removes and returns the last element if `predicate` returns `true` for
306    /// it, otherwise leaves the vector unchanged.
307    #[inline]
308    pub fn pop_if(&mut self, predicate: impl FnOnce(&mut T) -> bool) -> Option<T> {
309        let last = self.last_mut()?;
310        if predicate(last) { self.pop() } else { None }
311    }
312
313    /// Inserts an element at position `index`, shifting all elements after it
314    /// to the right.
315    ///
316    /// # Panics
317    ///
318    /// Panics if `index > len`.
319    #[inline]
320    pub fn insert(&mut self, index: usize, value: T) {
321        let len = self.len();
322        assert!(index <= len, "insertion index (is {index}) should be <= length (is {len})");
323        self.reserve(1);
324        match self {
325            SmallVec::Inline(v) => {
326                if v.insert(index, value).is_err() {
327                    unreachable!("inline capacity was reserved before inserting");
328                }
329            }
330            SmallVec::Heap(v) => v.insert(index, value),
331        }
332    }
333
334    /// Inserts an element at position `index` and returns a mutable reference
335    /// to it.
336    ///
337    /// # Panics
338    ///
339    /// Panics if `index > len`.
340    #[inline]
341    pub fn insert_mut(&mut self, index: usize, value: T) -> &mut T {
342        self.insert(index, value);
343        &mut self[index]
344    }
345
346    /// Removes and returns the element at `index`, shifting all elements after
347    /// it to the left.
348    ///
349    /// # Panics
350    ///
351    /// Panics if `index >= len`.
352    #[inline]
353    pub fn remove(&mut self, index: usize) -> T {
354        let len = self.len();
355        assert!(index < len, "removal index (is {index}) should be < length (is {len})");
356        match self {
357            SmallVec::Inline(v) => v.remove(index),
358            SmallVec::Heap(v) => v.remove(index),
359        }
360    }
361
362    /// Removes and returns the element at `index`, replacing it with the last
363    /// element. This does not preserve ordering, but is `O(1)`.
364    ///
365    /// # Panics
366    ///
367    /// Panics if `index >= len`.
368    #[inline]
369    pub fn swap_remove(&mut self, index: usize) -> T {
370        let len = self.len();
371        assert!(index < len, "swap_remove index (is {index}) should be < length (is {len})");
372        match self {
373            SmallVec::Inline(v) => v.swap_remove(index),
374            SmallVec::Heap(v) => v.swap_remove(index),
375        }
376    }
377
378    /// Removes all elements, keeping the current storage (inline stays inline,
379    /// heap stays heap) and its capacity.
380    #[inline]
381    pub fn clear(&mut self) {
382        match self {
383            SmallVec::Inline(v) => v.clear(),
384            SmallVec::Heap(v) => v.clear(),
385        }
386    }
387
388    /// Shortens the vector to `new_len`, dropping the excess elements.
389    ///
390    /// Does nothing if `new_len >= len`. Keeps the current storage.
391    #[inline]
392    pub fn truncate(&mut self, new_len: usize) {
393        match self {
394            SmallVec::Inline(v) => v.truncate(new_len),
395            SmallVec::Heap(v) => v.truncate(new_len),
396        }
397    }
398
399    /// Retains only the elements for which `f` returns `true`.
400    #[inline]
401    pub fn retain<F: FnMut(&T) -> bool>(&mut self, f: F) {
402        match self {
403            SmallVec::Inline(v) => v.retain(f),
404            SmallVec::Heap(v) => v.retain(f),
405        }
406    }
407
408    /// Retains only the elements for which `f` returns `true`, passing each
409    /// element by mutable reference.
410    #[inline]
411    pub fn retain_mut<F: FnMut(&mut T) -> bool>(&mut self, f: F) {
412        match self {
413            SmallVec::Inline(v) => v.retain_mut(f),
414            SmallVec::Heap(v) => v.retain_mut(f),
415        }
416    }
417
418    /// Removes consecutive duplicate elements using `PartialEq`.
419    #[inline]
420    pub fn dedup(&mut self)
421    where
422        T: PartialEq,
423    {
424        self.dedup_by(|a, b| a == b);
425    }
426
427    /// Removes consecutive elements that map to the same key.
428    #[inline]
429    pub fn dedup_by_key<F, K>(&mut self, mut key: F)
430    where
431        F: FnMut(&mut T) -> K,
432        K: PartialEq,
433    {
434        self.dedup_by(|a, b| key(a) == key(b));
435    }
436
437    /// Removes consecutive elements for which `same_bucket` returns `true`.
438    #[inline]
439    pub fn dedup_by<F>(&mut self, mut same_bucket: F)
440    where
441        F: FnMut(&mut T, &mut T) -> bool,
442    {
443        let len = self.len();
444        if len <= 1 {
445            return;
446        }
447
448        let slice = self.as_mut_slice();
449        let mut w = 1;
450        for r in 1..len {
451            let keep = {
452                let (left, right) = slice.split_at_mut(r);
453                let current = &mut right[0];
454                let previous = &mut left[w - 1];
455                !same_bucket(current, previous)
456            };
457            if keep {
458                if r != w {
459                    slice.swap(r, w);
460                }
461                w += 1;
462            }
463        }
464        self.truncate(w);
465    }
466
467    /// Resizes the vector to `new_len`, filling new slots by cloning `value`.
468    #[inline]
469    pub fn resize(&mut self, new_len: usize, value: T)
470    where
471        T: Clone,
472    {
473        let len = self.len();
474        if new_len > len {
475            self.extend(core::iter::repeat_n(value, new_len - len));
476        } else {
477            self.truncate(new_len);
478        }
479    }
480
481    /// Resizes the vector to `new_len`, filling new slots with `f()`.
482    #[inline]
483    pub fn resize_with<F: FnMut() -> T>(&mut self, new_len: usize, mut f: F) {
484        let len = self.len();
485        if new_len > len {
486            self.extend(core::iter::repeat_with(&mut f).take(new_len - len));
487        } else {
488            self.truncate(new_len);
489        }
490    }
491
492    /// Clones and appends every element of `other`.
493    #[inline]
494    pub fn extend_from_slice(&mut self, other: &[T])
495    where
496        T: Clone,
497    {
498        self.reserve(other.len());
499        match self {
500            SmallVec::Inline(v) => {
501                if v.extend_from_slice(other).is_err() {
502                    unreachable!("capacity was reserved before extending");
503                }
504            }
505            SmallVec::Heap(v) => v.extend_from_slice(other),
506        }
507    }
508
509    /// Clones the elements in `source` and appends them to the end of the
510    /// vector.
511    ///
512    /// # Panics
513    ///
514    /// Panics if the range is out of bounds.
515    #[inline]
516    pub fn extend_from_within<R: RangeBounds<usize>>(&mut self, source: R)
517    where
518        T: Clone,
519    {
520        let range = bounded_range(source, self.len());
521        let count = range.end - range.start;
522        if count == 0 {
523            return;
524        }
525        self.reserve(count);
526        match self {
527            // `Vec::extend_from_within` clones the range in bulk.
528            SmallVec::Heap(v) => v.extend_from_within(range),
529            SmallVec::Inline(v) => {
530                for i in 0..count {
531                    let value = v[range.start + i].clone();
532                    if v.push(value).is_err() {
533                        unreachable!("capacity was reserved before extending");
534                    }
535                }
536            }
537        }
538    }
539
540    /// Reserves room for at least `additional` more elements, growing the
541    /// heap buffer (or spilling to it) if needed.
542    #[inline]
543    pub fn reserve(&mut self, additional: usize) {
544        match self {
545            SmallVec::Heap(v) => v.reserve(additional),
546            SmallVec::Inline(v) => {
547                if additional > N - v.len() {
548                    let cap = N.saturating_mul(2).max(v.len().saturating_add(additional));
549                    let mut heap: Vec<T> = Vec::with_capacity(cap);
550                    heap.extend(core::mem::take(v));
551                    *self = SmallVec::Heap(heap);
552                }
553            }
554        }
555    }
556
557    /// Reserves room for exactly `additional` more elements, growing the heap
558    /// buffer (or spilling to it) if needed.
559    #[inline]
560    pub fn reserve_exact(&mut self, additional: usize) {
561        match self {
562            SmallVec::Heap(v) => v.reserve_exact(additional),
563            SmallVec::Inline(v) => {
564                if additional > N - v.len() {
565                    let cap = v.len().saturating_add(additional).max(N.saturating_add(1));
566                    let mut heap: Vec<T> = Vec::with_capacity(cap);
567                    heap.extend(core::mem::take(v));
568                    *self = SmallVec::Heap(heap);
569                }
570            }
571        }
572    }
573
574    /// Shrinks the vector as much as possible: an inline vector is unchanged,
575    /// while a spilled vector whose length fits in `N` moves back inline.
576    #[inline]
577    pub fn shrink_to_fit(&mut self) {
578        if let SmallVec::Heap(v) = self {
579            if v.len() <= N {
580                let inline = heapless::Vec::<T, N>::from_iter(v.drain(..));
581                *self = SmallVec::Inline(inline);
582            } else {
583                v.shrink_to_fit();
584            }
585        }
586    }
587
588    /// Shrinks the vector's capacity to at least `min_capacity`, moving it back
589    /// inline when the result fits in `N`.
590    #[inline]
591    pub fn shrink_to(&mut self, min_capacity: usize) {
592        if let SmallVec::Heap(v) = self
593            && v.capacity() > min_capacity
594        {
595            let target = v.len().max(min_capacity);
596            if target <= N {
597                let inline = heapless::Vec::<T, N>::from_iter(v.drain(..));
598                *self = SmallVec::Inline(inline);
599            } else {
600                v.shrink_to(target);
601            }
602        }
603    }
604
605    /// Moves every element out of `other` and appends them here, leaving
606    /// `other` empty.
607    #[inline]
608    pub fn append<const M: usize>(&mut self, other: &mut SmallVec<T, M>) {
609        self.reserve(other.len());
610        self.extend(other.drain(..));
611    }
612
613    /// Splits the vector into two at `at`: `self` keeps `[0, at)`, and the
614    /// returned vector holds `[at, len)`.
615    ///
616    /// # Panics
617    ///
618    /// Panics if `at > len`.
619    #[inline]
620    pub fn split_off(&mut self, at: usize) -> Self {
621        let len = self.len();
622        assert!(at <= len, "split index (is {at}) should be <= length (is {len})");
623        self.drain(at..).collect()
624    }
625
626    /// Removes the given range from the vector and returns an iterator over the
627    /// removed elements.
628    ///
629    /// The returned iterator keeps a mutable borrow on the vector. If it is
630    /// dropped without being fully consumed, the remaining removed elements are
631    /// dropped and the tail is moved into place.
632    ///
633    /// # Panics
634    ///
635    /// Panics if the range is out of bounds.
636    #[inline]
637    pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> Drain<'_, T, N> {
638        match self {
639            SmallVec::Inline(v) => Drain::Inline(v.drain(range)),
640            SmallVec::Heap(v) => Drain::Heap(v.drain(range)),
641        }
642    }
643}
644
645/// Converts a `RangeBounds` into a concrete, validated `Range`, panicking when
646/// it is out of bounds for a vector of `len` elements.
647fn bounded_range<R: RangeBounds<usize>>(range: R, len: usize) -> Range<usize> {
648    use core::ops::Bound;
649
650    let start = match range.start_bound() {
651        Bound::Included(&n) => n,
652        Bound::Excluded(&n) => n.checked_add(1).expect("range start overflow"),
653        Bound::Unbounded => 0,
654    };
655    let end = match range.end_bound() {
656        Bound::Included(&n) => n.checked_add(1).expect("range end overflow"),
657        Bound::Excluded(&n) => n,
658        Bound::Unbounded => len,
659    };
660    assert!(start <= end && end <= len, "range out of bounds");
661    start..end
662}
663
664/// An iterator that moves elements out of a [`SmallVec`].
665///
666/// Created by [`SmallVec::into_iter`]. It yields owned values, taking them
667/// either from the inline storage or from the heap buffer.
668pub enum IntoIter<T, const N: usize> {
669    /// Iterating over the inline storage.
670    Inline(heapless::vec::IntoIter<T, N, usize>),
671    /// Iterating over the heap buffer.
672    Heap(alloc::vec::IntoIter<T>),
673}
674
675impl<T, const N: usize> Iterator for IntoIter<T, N> {
676    type Item = T;
677
678    #[inline]
679    fn next(&mut self) -> Option<Self::Item> {
680        match self {
681            IntoIter::Inline(v) => v.next(),
682            IntoIter::Heap(v) => v.next(),
683        }
684    }
685
686    #[inline]
687    fn size_hint(&self) -> (usize, Option<usize>) {
688        match self {
689            IntoIter::Inline(v) => v.size_hint(),
690            IntoIter::Heap(v) => v.size_hint(),
691        }
692    }
693}
694
695impl<T, const N: usize> DoubleEndedIterator for IntoIter<T, N> {
696    #[inline]
697    fn next_back(&mut self) -> Option<Self::Item> {
698        match self {
699            IntoIter::Inline(v) => v.next_back(),
700            IntoIter::Heap(v) => v.next_back(),
701        }
702    }
703}
704
705impl<T, const N: usize> ExactSizeIterator for IntoIter<T, N> {
706    #[inline]
707    fn len(&self) -> usize {
708        match self {
709            IntoIter::Inline(v) => v.len(),
710            IntoIter::Heap(v) => v.len(),
711        }
712    }
713}
714
715impl<T, const N: usize> core::iter::FusedIterator for IntoIter<T, N> {}
716
717impl<T: Clone, const N: usize> Clone for IntoIter<T, N> {
718    #[inline]
719    fn clone(&self) -> Self {
720        match self {
721            IntoIter::Inline(v) => IntoIter::Inline(v.clone()),
722            IntoIter::Heap(v) => IntoIter::Heap(v.clone()),
723        }
724    }
725}
726
727impl<T: fmt::Debug, const N: usize> fmt::Debug for IntoIter<T, N> {
728    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
729        match self {
730            IntoIter::Inline(v) => fmt::Debug::fmt(v, f),
731            IntoIter::Heap(v) => fmt::Debug::fmt(v, f),
732        }
733    }
734}
735
736/// A draining iterator for a [`SmallVec`].
737///
738/// Created by [`SmallVec::drain`]. If the iterator is dropped before being
739/// fully consumed, the remaining removed elements are dropped and the
740/// unconsumed tail is moved back into place.
741pub enum Drain<'a, T, const N: usize> {
742    /// Draining the inline storage.
743    Inline(heapless::vec::Drain<'a, T, usize>),
744    /// Draining the heap buffer.
745    Heap(alloc::vec::Drain<'a, T>),
746}
747
748impl<T, const N: usize> Drain<'_, T, N> {
749    /// Returns the remaining elements to be yielded as a slice.
750    #[inline]
751    pub fn as_slice(&self) -> &[T] {
752        match self {
753            Drain::Inline(v) => v.as_slice(),
754            Drain::Heap(v) => v.as_slice(),
755        }
756    }
757}
758
759impl<T, const N: usize> Iterator for Drain<'_, T, N> {
760    type Item = T;
761
762    #[inline]
763    fn next(&mut self) -> Option<Self::Item> {
764        match self {
765            Drain::Inline(v) => v.next(),
766            Drain::Heap(v) => v.next(),
767        }
768    }
769
770    #[inline]
771    fn size_hint(&self) -> (usize, Option<usize>) {
772        match self {
773            Drain::Inline(v) => v.size_hint(),
774            Drain::Heap(v) => v.size_hint(),
775        }
776    }
777}
778
779impl<T, const N: usize> DoubleEndedIterator for Drain<'_, T, N> {
780    #[inline]
781    fn next_back(&mut self) -> Option<Self::Item> {
782        match self {
783            Drain::Inline(v) => v.next_back(),
784            Drain::Heap(v) => v.next_back(),
785        }
786    }
787}
788
789impl<T, const N: usize> ExactSizeIterator for Drain<'_, T, N> {
790    #[inline]
791    fn len(&self) -> usize {
792        match self {
793            Drain::Inline(v) => v.len(),
794            Drain::Heap(v) => v.len(),
795        }
796    }
797}
798
799impl<T, const N: usize> core::iter::FusedIterator for Drain<'_, T, N> {}
800
801impl<T: fmt::Debug, const N: usize> fmt::Debug for Drain<'_, T, N> {
802    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
803        match self {
804            Drain::Inline(v) => fmt::Debug::fmt(v, f),
805            Drain::Heap(v) => fmt::Debug::fmt(v, f),
806        }
807    }
808}
809
810impl<T, const N: usize> Default for SmallVec<T, N> {
811    #[inline]
812    fn default() -> Self {
813        Self::new()
814    }
815}
816
817impl<T, const N: usize> Deref for SmallVec<T, N> {
818    type Target = [T];
819
820    #[inline]
821    fn deref(&self) -> &Self::Target {
822        self.as_slice()
823    }
824}
825
826impl<T, const N: usize> DerefMut for SmallVec<T, N> {
827    #[inline]
828    fn deref_mut(&mut self) -> &mut Self::Target {
829        self.as_mut_slice()
830    }
831}
832
833impl<T, const N: usize> AsRef<[T]> for SmallVec<T, N> {
834    #[inline]
835    fn as_ref(&self) -> &[T] {
836        self.as_slice()
837    }
838}
839
840impl<T, const N: usize> AsMut<[T]> for SmallVec<T, N> {
841    #[inline]
842    fn as_mut(&mut self) -> &mut [T] {
843        self.as_mut_slice()
844    }
845}
846
847impl<T, const N: usize> Borrow<[T]> for SmallVec<T, N> {
848    #[inline]
849    fn borrow(&self) -> &[T] {
850        self.as_slice()
851    }
852}
853
854impl<T, const N: usize> BorrowMut<[T]> for SmallVec<T, N> {
855    #[inline]
856    fn borrow_mut(&mut self) -> &mut [T] {
857        self.as_mut_slice()
858    }
859}
860
861impl<T, const N: usize, I: SliceIndex<[T]>> Index<I> for SmallVec<T, N> {
862    type Output = <I as SliceIndex<[T]>>::Output;
863
864    #[inline]
865    fn index(&self, index: I) -> &Self::Output {
866        &self.as_slice()[index]
867    }
868}
869
870impl<T, const N: usize, I: SliceIndex<[T]>> IndexMut<I> for SmallVec<T, N> {
871    #[inline]
872    fn index_mut(&mut self, index: I) -> &mut Self::Output {
873        &mut self.as_mut_slice()[index]
874    }
875}
876
877impl<T: fmt::Debug, const N: usize> fmt::Debug for SmallVec<T, N> {
878    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
879        f.debug_list().entries(self.iter()).finish()
880    }
881}
882
883impl<T: Hash, const N: usize> Hash for SmallVec<T, N> {
884    #[inline]
885    fn hash<H: Hasher>(&self, state: &mut H) {
886        self.as_slice().hash(state);
887    }
888}
889
890impl<T: Eq, const N: usize> Eq for SmallVec<T, N> {}
891
892impl<T, U, const N: usize, const M: usize> PartialOrd<SmallVec<U, M>> for SmallVec<T, N>
893where
894    T: PartialOrd<U>,
895{
896    #[inline]
897    fn partial_cmp(&self, other: &SmallVec<U, M>) -> Option<Ordering> {
898        self.as_slice().iter().partial_cmp(other.as_slice().iter())
899    }
900}
901
902impl<T: Ord, const N: usize> Ord for SmallVec<T, N> {
903    #[inline]
904    fn cmp(&self, other: &Self) -> Ordering {
905        self.as_slice().cmp(other.as_slice())
906    }
907}
908
909/// Implements `PartialEq` between two slice-like types by comparing their
910/// dereferenced slices.
911macro_rules! impl_slice_eq {
912    ([$($vars:tt)*] $lhs:ty, $rhs:ty) => {
913        impl<T, U, const N: usize, $($vars)*> PartialEq<$rhs> for $lhs
914        where
915            T: PartialEq<U>,
916        {
917            #[inline]
918            fn eq(&self, other: &$rhs) -> bool {
919                self[..] == other[..]
920            }
921        }
922    };
923}
924
925impl_slice_eq! { [const M: usize] SmallVec<T, M>, SmallVec<U, N> }
926impl_slice_eq! { [const M: usize] SmallVec<T, M>, [U; N] }
927impl_slice_eq! { [const M: usize] SmallVec<T, M>, &[U; N] }
928impl_slice_eq! { [] SmallVec<T, N>, [U] }
929impl_slice_eq! { [] SmallVec<T, N>, &[U] }
930impl_slice_eq! { [] SmallVec<T, N>, &mut [U] }
931impl_slice_eq! { [] [T], SmallVec<U, N> }
932impl_slice_eq! { [] &[T], SmallVec<U, N> }
933impl_slice_eq! { [] &mut [T], SmallVec<U, N> }
934impl_slice_eq! { [] Vec<T>, SmallVec<U, N> }
935impl_slice_eq! { [] SmallVec<T, N>, Vec<U> }
936
937impl<T, U, const N: usize> PartialEq<SmallVec<U, N>> for Cow<'_, [T]>
938where
939    T: Clone + PartialEq<U>,
940{
941    #[inline]
942    fn eq(&self, other: &SmallVec<U, N>) -> bool {
943        self[..] == other[..]
944    }
945}
946
947impl<T, U, const N: usize> PartialEq<Cow<'_, [U]>> for SmallVec<T, N>
948where
949    U: Clone,
950    T: PartialEq<U>,
951{
952    #[inline]
953    fn eq(&self, other: &Cow<'_, [U]>) -> bool {
954        self[..] == other[..]
955    }
956}
957
958impl<T, U, const N: usize> PartialEq<SmallVec<U, N>> for VecDeque<T>
959where
960    T: PartialEq<U>,
961{
962    #[inline]
963    fn eq(&self, other: &SmallVec<U, N>) -> bool {
964        let other = other.as_slice();
965        if self.len() != other.len() {
966            return false;
967        }
968        let (sa, sb) = self.as_slices();
969        let (oa, ob) = other.split_at(sa.len());
970        sa == oa && sb == ob
971    }
972}
973
974impl<T, const N: usize> IntoIterator for SmallVec<T, N> {
975    type Item = T;
976    type IntoIter = IntoIter<T, N>;
977
978    #[inline]
979    fn into_iter(self) -> Self::IntoIter {
980        match self {
981            SmallVec::Inline(v) => IntoIter::Inline(v.into_iter()),
982            SmallVec::Heap(v) => IntoIter::Heap(v.into_iter()),
983        }
984    }
985}
986
987impl<'a, T, const N: usize> IntoIterator for &'a SmallVec<T, N> {
988    type Item = &'a T;
989    type IntoIter = Iter<'a, T>;
990
991    #[inline]
992    fn into_iter(self) -> Self::IntoIter {
993        self.iter()
994    }
995}
996
997impl<'a, T, const N: usize> IntoIterator for &'a mut SmallVec<T, N> {
998    type Item = &'a mut T;
999    type IntoIter = IterMut<'a, T>;
1000
1001    #[inline]
1002    fn into_iter(self) -> Self::IntoIter {
1003        self.iter_mut()
1004    }
1005}
1006
1007impl<T, const N: usize> Extend<T> for SmallVec<T, N> {
1008    #[inline]
1009    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1010        let iter = iter.into_iter();
1011        let (lower, _) = iter.size_hint();
1012        self.reserve(lower);
1013        for item in iter {
1014            self.push(item);
1015        }
1016    }
1017}
1018
1019impl<'a, T: Clone + 'a, const N: usize> Extend<&'a T> for SmallVec<T, N> {
1020    #[inline]
1021    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
1022        self.extend(iter.into_iter().cloned());
1023    }
1024}
1025
1026impl<T, const N: usize> FromIterator<T> for SmallVec<T, N> {
1027    #[inline]
1028    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1029        let iter = iter.into_iter();
1030        let (lower, _) = iter.size_hint();
1031        let mut this = Self::with_capacity(lower);
1032        this.extend(iter);
1033        this
1034    }
1035}
1036
1037impl<T, const N: usize> From<&[T]> for SmallVec<T, N>
1038where
1039    T: Clone,
1040{
1041    #[inline]
1042    fn from(slice: &[T]) -> Self {
1043        Self::from_slice(slice)
1044    }
1045}
1046
1047impl<T, const N: usize> From<&mut [T]> for SmallVec<T, N>
1048where
1049    T: Clone,
1050{
1051    #[inline]
1052    fn from(slice: &mut [T]) -> Self {
1053        Self::from_slice(slice)
1054    }
1055}
1056
1057impl<T, const M: usize, const N: usize> From<&[T; M]> for SmallVec<T, N>
1058where
1059    T: Clone,
1060{
1061    #[inline]
1062    fn from(slice: &[T; M]) -> Self {
1063        Self::from_slice(slice)
1064    }
1065}
1066
1067impl<T, const M: usize, const N: usize> From<&mut [T; M]> for SmallVec<T, N>
1068where
1069    T: Clone,
1070{
1071    #[inline]
1072    fn from(slice: &mut [T; M]) -> Self {
1073        Self::from_slice(slice)
1074    }
1075}
1076
1077impl<T, const M: usize, const N: usize> From<[T; M]> for SmallVec<T, N> {
1078    #[inline]
1079    fn from(array: [T; M]) -> Self {
1080        if M <= N {
1081            SmallVec::Inline(heapless::Vec::from_iter(array))
1082        } else {
1083            Self::from_vec(Vec::from(array))
1084        }
1085    }
1086}
1087
1088impl<T, const N: usize> From<Vec<T>> for SmallVec<T, N> {
1089    #[inline]
1090    fn from(vec: Vec<T>) -> Self {
1091        Self::from_vec(vec)
1092    }
1093}
1094
1095impl<T, const N: usize> From<SmallVec<T, N>> for Vec<T> {
1096    #[inline]
1097    fn from(this: SmallVec<T, N>) -> Self {
1098        match this {
1099            SmallVec::Inline(v) => v.into_iter().collect(),
1100            SmallVec::Heap(v) => v,
1101        }
1102    }
1103}
1104
1105impl<T, const N: usize> From<SmallVec<T, N>> for alloc::boxed::Box<[T]> {
1106    #[inline]
1107    fn from(this: SmallVec<T, N>) -> Self {
1108        Vec::from(this).into_boxed_slice()
1109    }
1110}
1111
1112impl<T, const M: usize, const N: usize> TryFrom<SmallVec<T, N>> for [T; M] {
1113    type Error = SmallVec<T, N>;
1114
1115    #[inline]
1116    fn try_from(this: SmallVec<T, N>) -> Result<[T; M], Self::Error> {
1117        if this.len() != M {
1118            return Err(this);
1119        }
1120
1121        match this {
1122            SmallVec::Inline(v) => match v.into_array::<M>() {
1123                Ok(array) => Ok(array),
1124                Err(v) => Err(SmallVec::Inline(v)),
1125            },
1126            SmallVec::Heap(v) => match <[T; M]>::try_from(v) {
1127                Ok(array) => Ok(array),
1128                Err(v) => Err(SmallVec::Heap(v)),
1129            },
1130        }
1131    }
1132}
1133
1134#[cfg(feature = "serde")]
1135impl<T, const N: usize> serde::Serialize for SmallVec<T, N>
1136where
1137    T: serde::Serialize,
1138{
1139    fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1140        use serde::ser::SerializeSeq;
1141
1142        let mut seq = serializer.serialize_seq(Some(self.len()))?;
1143        for item in self.iter() {
1144            seq.serialize_element(item)?;
1145        }
1146        seq.end()
1147    }
1148}
1149
1150#[cfg(feature = "serde")]
1151impl<'de, T, const N: usize> serde::Deserialize<'de> for SmallVec<T, N>
1152where
1153    T: serde::Deserialize<'de>,
1154{
1155    fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
1156        use core::marker::PhantomData;
1157
1158        use serde::de::{SeqAccess, Visitor};
1159
1160        struct SmallVecVisitor<T, const N: usize> {
1161            marker: PhantomData<T>,
1162        }
1163
1164        impl<'de, T, const N: usize> Visitor<'de> for SmallVecVisitor<T, N>
1165        where
1166            T: serde::Deserialize<'de>,
1167        {
1168            type Value = SmallVec<T, N>;
1169
1170            fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1171                formatter.write_str("a sequence")
1172            }
1173
1174            fn visit_seq<A: SeqAccess<'de>>(self, mut seq: A) -> Result<Self::Value, A::Error> {
1175                let mut this = SmallVec::new();
1176                if let Some(size) = seq.size_hint() {
1177                    this.reserve(size);
1178                }
1179                while let Some(value) = seq.next_element()? {
1180                    this.push(value);
1181                }
1182                Ok(this)
1183            }
1184        }
1185
1186        deserializer.deserialize_seq(SmallVecVisitor {
1187            marker: PhantomData,
1188        })
1189    }
1190}
1191
1192#[cfg(feature = "std")]
1193impl<const N: usize> std::io::Write for SmallVec<u8, N> {
1194    #[inline]
1195    fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
1196        self.extend_from_slice(buf);
1197        Ok(buf.len())
1198    }
1199
1200    #[inline]
1201    fn write_all(&mut self, buf: &[u8]) -> std::io::Result<()> {
1202        self.extend_from_slice(buf);
1203        Ok(())
1204    }
1205
1206    #[inline]
1207    fn flush(&mut self) -> std::io::Result<()> {
1208        Ok(())
1209    }
1210}
1211
1212#[cfg(feature = "bytes")]
1213unsafe impl<const N: usize> bytes::BufMut for SmallVec<u8, N> {
1214    #[inline]
1215    fn remaining_mut(&self) -> usize {
1216        // A vector can never have more than `isize::MAX` bytes.
1217        isize::MAX as usize - self.len()
1218    }
1219
1220    #[inline]
1221    unsafe fn advance_mut(&mut self, cnt: usize) {
1222        let len = self.len();
1223        let remaining = self.capacity() - len;
1224        assert!(
1225            cnt <= remaining,
1226            "advance out of bounds: the capacity is {remaining} but advancing by {cnt}"
1227        );
1228
1229        let new_len = len + cnt;
1230        match self {
1231            SmallVec::Inline(v) => unsafe { v.set_len(new_len) },
1232            SmallVec::Heap(v) => unsafe { v.set_len(new_len) },
1233        }
1234    }
1235
1236    #[inline]
1237    fn chunk_mut(&mut self) -> &mut bytes::buf::UninitSlice {
1238        if self.capacity() == self.len() {
1239            // Grow the vector so there is always somewhere to write.
1240            self.reserve(64);
1241        }
1242
1243        match self {
1244            SmallVec::Inline(v) => {
1245                let spare = v.spare_capacity_mut();
1246                let ptr = spare.as_mut_ptr().cast::<u8>();
1247                let len = spare.len();
1248                // SAFETY: `ptr` points to `len` contiguous, writable bytes of
1249                // uninitialized storage owned by `self`.
1250                unsafe { bytes::buf::UninitSlice::from_raw_parts_mut(ptr, len) }
1251            }
1252            SmallVec::Heap(v) => v.chunk_mut(),
1253        }
1254    }
1255
1256    #[inline]
1257    fn put<T: bytes::Buf>(&mut self, mut source: T)
1258    where
1259        Self: Sized,
1260    {
1261        self.reserve(source.remaining());
1262        while source.has_remaining() {
1263            let chunk = source.chunk();
1264            let len = chunk.len();
1265            self.extend_from_slice(chunk);
1266            source.advance(len);
1267        }
1268    }
1269
1270    #[inline]
1271    fn put_slice(&mut self, source: &[u8]) {
1272        self.extend_from_slice(source);
1273    }
1274
1275    #[inline]
1276    fn put_bytes(&mut self, val: u8, cnt: usize) {
1277        let new_len = self.len().saturating_add(cnt);
1278        self.resize(new_len, val);
1279    }
1280}
1281
1282#[cfg(test)]
1283mod tests {
1284    use alloc::{boxed::Box, vec, vec::Vec};
1285    use core::cmp::Ordering;
1286
1287    use super::SmallVec;
1288
1289    #[test]
1290    fn new_is_inline_and_empty() {
1291        let v: SmallVec<i32, 4> = SmallVec::new();
1292        assert!(v.is_inline());
1293        assert!(v.is_inline());
1294        assert!(v.is_empty());
1295        assert_eq!(v.len(), 0);
1296        assert_eq!(v.capacity(), 4);
1297        assert_eq!(<SmallVec<i32, 4>>::inline_size(), 4);
1298    }
1299
1300    #[test]
1301    fn push_stays_inline_until_full() {
1302        let mut v: SmallVec<i32, 3> = SmallVec::new();
1303        v.push(1);
1304        v.push(2);
1305        v.push(3);
1306        assert!(v.is_inline());
1307        assert_eq!(&*v, &[1, 2, 3]);
1308
1309        v.push(4);
1310        assert!(!v.is_inline());
1311        assert_eq!(&*v, &[1, 2, 3, 4]);
1312        assert!(v.capacity() >= 4);
1313    }
1314
1315    #[test]
1316    fn zero_inline_capacity_spills_immediately() {
1317        let mut v: SmallVec<i32, 0> = SmallVec::new();
1318        assert!(v.is_inline());
1319        assert_eq!(v.capacity(), 0);
1320        v.push(1);
1321        assert!(!v.is_inline());
1322        assert_eq!(&*v, &[1]);
1323    }
1324
1325    #[test]
1326    fn pop_and_pop_if() {
1327        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1328        assert_eq!(v.pop(), Some(3));
1329        assert_eq!(v.pop(), Some(2));
1330        assert_eq!(v.pop_if(|x| *x == 1), Some(1));
1331        assert_eq!(v.pop(), None);
1332        assert_eq!(v.pop_if(|_| true), None);
1333    }
1334
1335    #[test]
1336    fn insert_and_remove() {
1337        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1338        v.insert(1, 9);
1339        assert_eq!(&*v, &[1, 9, 2, 3]);
1340        assert!(v.is_inline());
1341
1342        // Inserting past the inline capacity spills.
1343        v.insert(4, 8);
1344        assert!(!v.is_inline());
1345        assert_eq!(&*v, &[1, 9, 2, 3, 8]);
1346
1347        assert_eq!(v.remove(0), 1);
1348        assert_eq!(&*v, &[9, 2, 3, 8]);
1349    }
1350
1351    #[test]
1352    #[should_panic(expected = "insertion index")]
1353    fn insert_out_of_bounds_panics() {
1354        let mut v: SmallVec<i32, 4> = SmallVec::from([1]);
1355        v.insert(3, 2);
1356    }
1357
1358    #[test]
1359    #[should_panic(expected = "removal index")]
1360    fn remove_out_of_bounds_panics() {
1361        let mut v: SmallVec<i32, 4> = SmallVec::from([1]);
1362        v.remove(1);
1363    }
1364
1365    #[test]
1366    fn swap_remove() {
1367        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3, 4]);
1368        assert_eq!(v.swap_remove(1), 2);
1369        assert_eq!(&*v, &[1, 4, 3]);
1370        assert_eq!(v.swap_remove(2), 3);
1371        assert_eq!(&*v, &[1, 4]);
1372    }
1373
1374    #[test]
1375    fn push_mut_and_insert_mut() {
1376        let mut v: SmallVec<i32, 2> = SmallVec::new();
1377        *v.push_mut(1) += 10;
1378        *v.insert_mut(0, 5) *= 2;
1379        assert_eq!(&*v, &[10, 11]);
1380    }
1381
1382    #[test]
1383    fn clear_keeps_storage() {
1384        let mut inline: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1385        inline.clear();
1386        assert!(inline.is_inline());
1387        assert!(inline.is_empty());
1388
1389        let mut spilled: SmallVec<i32, 2> = SmallVec::from([1, 2, 3]);
1390        spilled.clear();
1391        assert!(!spilled.is_inline());
1392        assert!(spilled.is_empty());
1393    }
1394
1395    #[test]
1396    fn truncate_keeps_storage() {
1397        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1398        v.truncate(1);
1399        assert!(v.is_inline());
1400        assert_eq!(&*v, &[1]);
1401        v.truncate(10);
1402        assert_eq!(&*v, &[1]);
1403    }
1404
1405    #[test]
1406    fn retain_and_retain_mut() {
1407        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2, 3, 4, 5]);
1408        v.retain(|x| x % 2 == 1);
1409        assert_eq!(&*v, &[1, 3, 5]);
1410
1411        v.retain_mut(|x| {
1412            *x *= 2;
1413            *x < 6
1414        });
1415        assert_eq!(&*v, &[2]);
1416    }
1417
1418    #[test]
1419    fn dedup() {
1420        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 1, 2, 2, 2, 3, 1]);
1421        v.dedup();
1422        assert_eq!(&*v, &[1, 2, 3, 1]);
1423
1424        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 3, 2, 4, 5]);
1425        v.dedup_by_key(|x| *x % 2);
1426        assert_eq!(&*v, &[1, 2, 5]);
1427    }
1428
1429    #[test]
1430    fn resize_and_resize_with() {
1431        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1432        v.resize(6, 0);
1433        assert!(!v.is_inline());
1434        assert_eq!(&*v, &[1, 2, 0, 0, 0, 0]);
1435        v.resize(2, 0);
1436        assert_eq!(&*v, &[1, 2]);
1437
1438        let mut counter = 0;
1439        let mut w: SmallVec<i32, 2> = SmallVec::new();
1440        w.resize_with(4, || {
1441            counter += 1;
1442            counter
1443        });
1444        assert_eq!(&*w, &[1, 2, 3, 4]);
1445    }
1446
1447    #[test]
1448    fn extend_from_slice_and_within() {
1449        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1450        v.extend_from_slice(&[3, 4]);
1451        assert!(v.is_inline());
1452        assert_eq!(&*v, &[1, 2, 3, 4]);
1453
1454        v.extend_from_within(0..2);
1455        assert!(!v.is_inline());
1456        assert_eq!(&*v, &[1, 2, 3, 4, 1, 2]);
1457    }
1458
1459    #[test]
1460    fn reserve_and_reserve_exact() {
1461        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1462        v.reserve(1);
1463        assert!(v.is_inline());
1464        v.reserve(10);
1465        assert!(!v.is_inline());
1466        assert!(v.capacity() >= 12);
1467        let before = v.capacity();
1468        v.reserve_exact(2);
1469        assert!(v.capacity() >= before);
1470        assert_eq!(&*v, &[1, 2]);
1471    }
1472
1473    #[test]
1474    fn shrink_to_fit_moves_back_inline() {
1475        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3, 4]);
1476        v.push(5);
1477        assert!(!v.is_inline());
1478        v.pop();
1479        v.shrink_to_fit();
1480        assert!(v.is_inline());
1481        assert_eq!(&*v, &[1, 2, 3, 4]);
1482    }
1483
1484    #[test]
1485    fn shrink_to_moves_back_inline() {
1486        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3, 4]);
1487        v.push(5);
1488        assert!(!v.is_inline());
1489        v.pop();
1490        v.shrink_to(2);
1491        assert!(v.is_inline());
1492        assert_eq!(&*v, &[1, 2, 3, 4]);
1493    }
1494
1495    #[test]
1496    fn append_moves_between_capacities() {
1497        let mut a: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1498        let mut b: SmallVec<i32, 8> = SmallVec::from([3, 4, 5]);
1499        a.append(&mut b);
1500        assert_eq!(&*a, &[1, 2, 3, 4, 5]);
1501        assert!(b.is_empty());
1502    }
1503
1504    #[test]
1505    fn split_off() {
1506        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2, 3, 4, 5]);
1507        let tail: SmallVec<i32, 8> = v.split_off(2);
1508        assert_eq!(&*v, &[1, 2]);
1509        assert_eq!(&*tail, &[3, 4, 5]);
1510        assert!(tail.is_inline());
1511    }
1512
1513    #[test]
1514    fn drain_inline_and_heap() {
1515        let mut inline: SmallVec<i32, 8> = SmallVec::from([1, 2, 3, 4]);
1516        let drained: Vec<i32> = inline.drain(1..3).collect();
1517        assert_eq!(drained, vec![2, 3]);
1518        assert_eq!(&*inline, &[1, 4]);
1519
1520        let mut heap: SmallVec<i32, 2> = SmallVec::from([1, 2, 3, 4]);
1521        assert!(!heap.is_inline());
1522        heap.drain(..);
1523        assert!(heap.is_empty());
1524    }
1525
1526    #[test]
1527    fn drain_dropped_early_restores_tail() {
1528        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2, 3, 4, 5]);
1529        {
1530            let mut d = v.drain(1..4);
1531            assert_eq!(d.next(), Some(2));
1532        }
1533        assert_eq!(&*v, &[1, 5]);
1534    }
1535
1536    #[test]
1537    fn into_iter_inline_and_heap() {
1538        let inline: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1539        let collected: Vec<i32> = inline.into_iter().collect();
1540        assert_eq!(collected, vec![1, 2, 3]);
1541
1542        let heap: SmallVec<i32, 2> = SmallVec::from([1, 2, 3, 4]);
1543        assert!(!heap.is_inline());
1544        let collected: Vec<i32> = heap.into_iter().collect();
1545        assert_eq!(collected, vec![1, 2, 3, 4]);
1546    }
1547
1548    #[test]
1549    fn into_iter_double_ended() {
1550        let v: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1551        let collected: Vec<i32> = v.into_iter().rev().collect();
1552        assert_eq!(collected, vec![3, 2, 1]);
1553    }
1554
1555    #[test]
1556    fn from_vec_preserves_heap() {
1557        let heap: Vec<i32> = vec![1, 2];
1558        let v: SmallVec<i32, 16> = SmallVec::from_vec(heap);
1559        assert!(!v.is_inline());
1560        assert_eq!(&*v, &[1, 2]);
1561    }
1562
1563    #[test]
1564    fn from_vec_empty_is_inline() {
1565        let v: SmallVec<i32, 4> = SmallVec::from_vec(Vec::new());
1566        assert!(v.is_inline());
1567    }
1568
1569    #[test]
1570    fn from_array_inline_and_heap() {
1571        let inline: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1572        assert!(inline.is_inline());
1573
1574        let heap: SmallVec<i32, 2> = SmallVec::from([1, 2, 3]);
1575        assert!(!heap.is_inline());
1576        assert_eq!(&*heap, &[1, 2, 3]);
1577    }
1578
1579    #[test]
1580    fn from_array_and_len() {
1581        let v: SmallVec<i32, 4> = SmallVec::from_array_and_len([1, 2, 3, 4], 2);
1582        assert!(v.is_inline());
1583        assert_eq!(&*v, &[1, 2]);
1584    }
1585
1586    #[test]
1587    fn from_slice_inline_and_heap() {
1588        let inline: SmallVec<i32, 4> = SmallVec::from_slice(&[1, 2]);
1589        assert!(inline.is_inline());
1590
1591        let heap: SmallVec<i32, 1> = SmallVec::from_slice(&[1, 2]);
1592        assert!(!heap.is_inline());
1593    }
1594
1595    #[test]
1596    fn from_small_vec_cross_capacity() {
1597        let source: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1598        let fits: SmallVec<i32, 8> = SmallVec::from_small_vec(source);
1599        assert!(fits.is_inline());
1600        assert_eq!(&*fits, &[1, 2, 3]);
1601
1602        let spilled: SmallVec<i32, 2> = SmallVec::from([1, 2, 3]);
1603        let target: SmallVec<i32, 8> = SmallVec::from_small_vec(spilled);
1604        assert!(target.is_inline());
1605        assert_eq!(&*target, &[1, 2, 3]);
1606
1607        let big: SmallVec<i32, 8> = SmallVec::from([1, 2, 3, 4, 5]);
1608        let target: SmallVec<i32, 2> = SmallVec::from_small_vec(big);
1609        assert!(!target.is_inline());
1610        assert_eq!(&*target, &[1, 2, 3, 4, 5]);
1611    }
1612
1613    #[test]
1614    fn with_capacity() {
1615        let inline: SmallVec<i32, 8> = SmallVec::with_capacity(3);
1616        assert!(inline.is_inline());
1617
1618        let heap: SmallVec<i32, 2> = SmallVec::with_capacity(10);
1619        assert!(!heap.is_inline());
1620        assert!(heap.capacity() >= 10);
1621    }
1622
1623    #[test]
1624    fn conversions_to_and_from_vec() {
1625        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1626        let heap: Vec<i32> = Vec::from(v);
1627        assert_eq!(heap, vec![1, 2, 3]);
1628
1629        let v: SmallVec<i32, 2> = SmallVec::from([1, 2, 3]);
1630        let heap: Vec<i32> = Vec::from(v);
1631        assert_eq!(heap, vec![1, 2, 3]);
1632
1633        let boxed: Box<[i32]> = Box::from(SmallVec::<i32, 4>::from([1, 2]));
1634        assert_eq!(&*boxed, &[1, 2]);
1635    }
1636
1637    #[test]
1638    fn try_into_array() {
1639        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1640        let array: [i32; 3] = v.try_into().unwrap();
1641        assert_eq!(array, [1, 2, 3]);
1642
1643        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1644        assert!(<[i32; 2]>::try_from(v).is_err());
1645
1646        let v: SmallVec<i32, 2> = SmallVec::from([1, 2, 3]);
1647        let array: [i32; 3] = v.try_into().unwrap();
1648        assert_eq!(array, [1, 2, 3]);
1649    }
1650
1651    #[test]
1652    fn from_iterator_collects_and_spills() {
1653        let inline: SmallVec<i32, 8> = (1..=3).collect();
1654        assert!(inline.is_inline());
1655
1656        let heap: SmallVec<i32, 2> = (1..=5).collect();
1657        assert!(!heap.is_inline());
1658        assert_eq!(&*heap, &[1, 2, 3, 4, 5]);
1659    }
1660
1661    #[test]
1662    fn extend_trait() {
1663        let mut v: SmallVec<i32, 4> = SmallVec::from([1]);
1664        v.extend([2, 3, 4, 5]);
1665        assert_eq!(&*v, &[1, 2, 3, 4, 5]);
1666        v.extend([6, 7].iter());
1667        assert_eq!(&*v, &[1, 2, 3, 4, 5, 6, 7]);
1668    }
1669
1670    #[test]
1671    fn comparisons_across_capacities_and_types() {
1672        let a: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1673        let b: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1674        assert_eq!(a, b);
1675        assert_eq!(a, [1, 2, 3]);
1676        assert_eq!(a, &[1, 2, 3][..]);
1677        assert_eq!(a, vec![1, 2, 3]);
1678        assert_eq!(vec![1, 2, 3], a);
1679        assert_eq!(a, *alloc::borrow::Cow::Borrowed(&[1, 2, 3][..]));
1680
1681        let c: SmallVec<i32, 4> = SmallVec::from([4]);
1682        assert_ne!(a, c);
1683        assert!(a < c);
1684    }
1685
1686    #[test]
1687    fn deref_and_slice_methods() {
1688        let v: SmallVec<i32, 8> = SmallVec::from([3, 1, 2]);
1689        assert_eq!(v.iter().copied().max(), Some(3));
1690        assert_eq!(v.first(), Some(&3));
1691        assert_eq!(&v[1..], &[1, 2]);
1692    }
1693
1694    #[test]
1695    fn debug_and_default() {
1696        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1697        assert_eq!(alloc::format!("{v:?}"), "[1, 2, 3]");
1698
1699        let d: SmallVec<i32, 4> = Default::default();
1700        assert!(d.is_empty());
1701    }
1702
1703    #[test]
1704    fn hash_matches_slice() {
1705        use core::hash::{Hash, Hasher};
1706        use std::collections::hash_map::DefaultHasher;
1707
1708        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1709        let mut h1 = DefaultHasher::new();
1710        v.hash(&mut h1);
1711
1712        let mut h2 = DefaultHasher::new();
1713        [1, 2, 3].hash(&mut h2);
1714
1715        assert_eq!(h1.finish(), h2.finish());
1716    }
1717
1718    #[test]
1719    #[cfg(feature = "serde")]
1720    fn serde_is_flat_sequence() {
1721        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1722        let json = serde_json::to_string(&v).unwrap();
1723        assert_eq!(json, "[1,2,3]");
1724
1725        let back: SmallVec<i32, 4> = serde_json::from_str(&json).unwrap();
1726        assert!(back.is_inline());
1727        assert_eq!(back, v);
1728
1729        let long = "[1,2,3,4,5,6]";
1730        let back: SmallVec<i32, 2> = serde_json::from_str(long).unwrap();
1731        assert!(!back.is_inline());
1732        assert_eq!(&*back, &[1, 2, 3, 4, 5, 6]);
1733    }
1734
1735    #[test]
1736    #[cfg(feature = "std")]
1737    fn io_write() {
1738        use std::io::Write;
1739
1740        let mut v: SmallVec<u8, 4> = SmallVec::new();
1741        v.write_all(b"hello ").unwrap();
1742        write!(v, "world").unwrap();
1743        assert_eq!(&*v, b"hello world");
1744        assert!(!v.is_inline());
1745    }
1746
1747    #[test]
1748    #[cfg(feature = "bytes")]
1749    fn buf_mut() {
1750        use bytes::{BufMut, BytesMut};
1751
1752        let mut v: SmallVec<u8, 4> = SmallVec::new();
1753        v.put_slice(b"ab");
1754        assert!(v.is_inline());
1755        v.put_u8(b'c');
1756        // `put` exercises `chunk_mut`/`advance_mut`.
1757        v.put(BytesMut::from(&b"de"[..]));
1758        assert_eq!(&*v, b"abcde");
1759
1760        let mut v: SmallVec<u8, 8> = SmallVec::new();
1761        v.put_u32(0x0102_0304);
1762        assert_eq!(&*v, &[1, 2, 3, 4]);
1763    }
1764
1765    // -----------------------------------------------------------------------
1766    // Additional coverage
1767    // -----------------------------------------------------------------------
1768
1769    #[test]
1770    fn inline_size_is_n() {
1771        assert_eq!(<SmallVec<i32, 4>>::inline_size(), 4);
1772        assert_eq!(<SmallVec<i32, 0>>::inline_size(), 0);
1773    }
1774
1775    #[test]
1776    fn capacity_invariants_across_operations() {
1777        let mut v: SmallVec<i32, 4> = SmallVec::new();
1778        v.reserve(2);
1779        assert!(v.capacity() >= v.len() + 2);
1780        v.extend([1, 2]);
1781        v.reserve(10);
1782        assert!(v.capacity() >= v.len() + 10);
1783
1784        let mut e: SmallVec<i32, 2> = SmallVec::new();
1785        e.reserve_exact(8);
1786        assert!(e.capacity() >= 8);
1787    }
1788
1789    #[test]
1790    fn push_growth_loop_preserves_all_elements() {
1791        let mut v: SmallVec<usize, 4> = SmallVec::new();
1792        for i in 0..1000 {
1793            v.push(i);
1794        }
1795        assert!(!v.is_inline());
1796        assert_eq!(v.len(), 1000);
1797        for (i, x) in v.iter().enumerate() {
1798            assert_eq!(*x, i);
1799        }
1800    }
1801
1802    #[test]
1803    fn insert_at_end_and_into_empty() {
1804        let mut v: SmallVec<i32, 4> = SmallVec::new();
1805        v.insert(0, 1);
1806        assert_eq!(&*v, &[1]);
1807        v.insert(1, 2);
1808        assert_eq!(&*v, &[1, 2]);
1809    }
1810
1811    #[test]
1812    #[should_panic(expected = "range out of bounds")]
1813    fn extend_from_within_out_of_bounds_panics() {
1814        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2]);
1815        v.extend_from_within(0..3);
1816    }
1817
1818    #[test]
1819    fn extend_from_within_empty_range_is_noop() {
1820        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1821        v.extend_from_within(1..1);
1822        assert!(v.is_inline());
1823        assert_eq!(&*v, &[1, 2]);
1824    }
1825
1826    #[test]
1827    #[should_panic]
1828    fn split_off_out_of_bounds_panics() {
1829        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2]);
1830        let _ = v.split_off(3);
1831    }
1832
1833    #[test]
1834    fn split_off_boundaries() {
1835        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1836        let empty = v.split_off(3);
1837        assert!(empty.is_empty());
1838        assert_eq!(&*v, &[1, 2, 3]);
1839
1840        let mut w: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1841        let all = w.split_off(0);
1842        assert!(w.is_empty());
1843        assert_eq!(&*all, &[1, 2, 3]);
1844    }
1845
1846    #[test]
1847    #[should_panic]
1848    fn drain_out_of_bounds_panics() {
1849        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2]);
1850        let _ = v.drain(0..3);
1851    }
1852
1853    #[test]
1854    fn drain_as_slice_and_double_ended() {
1855        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2, 3, 4]);
1856        {
1857            let mut d = v.drain(1..4);
1858            assert_eq!(d.as_slice(), &[2, 3, 4]);
1859            assert_eq!(d.next(), Some(2));
1860            assert_eq!(d.next_back(), Some(4));
1861            assert_eq!(d.as_slice(), &[3]);
1862            assert_eq!(d.next(), Some(3));
1863            assert_eq!(d.next(), None);
1864        }
1865        assert_eq!(&*v, &[1]);
1866    }
1867
1868    #[test]
1869    fn clear_then_shrink_to_fit_moves_inline() {
1870        let mut v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3, 4, 5]);
1871        assert!(!v.is_inline());
1872        v.clear();
1873        assert!(!v.is_inline());
1874        v.shrink_to_fit();
1875        assert!(v.is_inline());
1876    }
1877
1878    #[test]
1879    fn shrink_to_keeps_min_capacity_on_heap() {
1880        let mut v: SmallVec<i32, 2> = SmallVec::from([1, 2, 3, 4]);
1881        assert!(!v.is_inline());
1882        v.shrink_to(3);
1883        assert!(!v.is_inline());
1884        assert!(v.capacity() >= 3);
1885        assert_eq!(&*v, &[1, 2, 3, 4]);
1886    }
1887
1888    #[test]
1889    fn zero_capacity_vector_operations() {
1890        let mut v: SmallVec<i32, 0> = SmallVec::new();
1891        assert!(v.is_inline());
1892        assert_eq!(v.capacity(), 0);
1893        v.reserve(0);
1894        assert!(v.is_inline());
1895        v.push(1);
1896        assert!(!v.is_inline());
1897        v.insert(0, 0);
1898        assert_eq!(&*v, &[0, 1]);
1899        v.shrink_to_fit();
1900        v.truncate(1);
1901        assert_eq!(&*v, &[0]);
1902    }
1903
1904    #[test]
1905    fn dedup_by_preserves_order_and_argument_order() {
1906        // `same_bucket` is called with (current, previous), like std.
1907        let mut v: SmallVec<i32, 8> = SmallVec::from([1, 2, 2, 3, 3, 3, 4]);
1908        let mut calls = Vec::new();
1909        v.dedup_by(|a, b| {
1910            calls.push((*a, *b));
1911            a == b
1912        });
1913        assert_eq!(&*v, &[1, 2, 3, 4]);
1914        assert_eq!(calls[0], (2, 1));
1915        assert_eq!(calls[1], (2, 2));
1916        assert_eq!(calls[2], (3, 2));
1917    }
1918
1919    #[test]
1920    fn dedup_on_empty_and_single() {
1921        let mut empty: SmallVec<i32, 4> = SmallVec::new();
1922        empty.dedup();
1923        assert!(empty.is_empty());
1924
1925        let mut one: SmallVec<i32, 4> = SmallVec::from([1]);
1926        one.dedup();
1927        assert_eq!(&*one, &[1]);
1928    }
1929
1930    #[test]
1931    fn retain_removes_nothing_and_everything() {
1932        let mut keep: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1933        keep.retain(|_| true);
1934        assert_eq!(&*keep, &[1, 2, 3]);
1935
1936        let mut drop: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1937        drop.retain(|_| false);
1938        assert!(drop.is_empty());
1939    }
1940
1941    #[test]
1942    fn try_from_error_preserves_contents() {
1943        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
1944        let err = <[i32; 2]>::try_from(v).unwrap_err();
1945        assert_eq!(&*err, &[1, 2, 3]);
1946
1947        let v: SmallVec<i32, 2> = SmallVec::from([1, 2, 3]);
1948        assert!(!v.is_inline());
1949        let err = <[i32; 2]>::try_from(v).unwrap_err();
1950        assert_eq!(&*err, &[1, 2, 3]);
1951    }
1952
1953    #[test]
1954    fn into_vec_preserves_heap_allocation() {
1955        let mut v: SmallVec<i32, 2> = SmallVec::new();
1956        v.extend([1, 2, 3, 4]);
1957        assert!(!v.is_inline());
1958        let ptr = v.as_ptr();
1959        let vec: Vec<i32> = Vec::from(v);
1960        assert_eq!(vec.as_ptr(), ptr);
1961        assert_eq!(vec, vec![1, 2, 3, 4]);
1962    }
1963
1964    #[test]
1965    fn hash_inline_and_heap_agree() {
1966        use core::hash::{Hash, Hasher};
1967        use std::collections::hash_map::DefaultHasher;
1968
1969        let inline: SmallVec<i32, 8> = SmallVec::from([1, 2, 3]);
1970        let heap: SmallVec<i32, 1> = SmallVec::from([1, 2, 3]);
1971        assert!(inline.is_inline());
1972        assert!(!heap.is_inline());
1973
1974        let mut h1 = DefaultHasher::new();
1975        inline.hash(&mut h1);
1976        let mut h2 = DefaultHasher::new();
1977        heap.hash(&mut h2);
1978        assert_eq!(h1.finish(), h2.finish());
1979    }
1980
1981    #[test]
1982    fn vecdeque_equality() {
1983        use alloc::collections::VecDeque;
1984
1985        let v: SmallVec<i32, 2> = SmallVec::from([1, 2, 3, 4]);
1986        assert!(!v.is_inline());
1987        let mut dq: VecDeque<i32> = VecDeque::new();
1988        dq.extend([1, 2, 3, 4]);
1989        assert_eq!(dq, v);
1990
1991        // A deque whose contents wrap around still compares equal.
1992        let mut wrapped: VecDeque<i32> = VecDeque::new();
1993        wrapped.extend([9, 1, 2, 3, 4]);
1994        wrapped.pop_front();
1995        assert_eq!(wrapped, v);
1996
1997        let mut shorter: VecDeque<i32> = VecDeque::new();
1998        shorter.extend([1, 2, 3]);
1999        assert_ne!(shorter, v);
2000    }
2001
2002    #[test]
2003    fn cow_equality() {
2004        use alloc::borrow::Cow;
2005
2006        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
2007        let borrowed: Cow<'_, [i32]> = Cow::Borrowed(&[1, 2, 3]);
2008        assert_eq!(borrowed, v);
2009        assert_eq!(v, borrowed);
2010
2011        let mismatched: Cow<'_, [i32]> = Cow::Borrowed(&[1, 2]);
2012        assert_ne!(mismatched, v);
2013    }
2014
2015    #[test]
2016    fn cross_capacity_ordering() {
2017        let a: SmallVec<i32, 2> = SmallVec::from([1, 2]);
2018        let b: SmallVec<i32, 8> = SmallVec::from([1, 3]);
2019        assert!(a < b);
2020        assert!(b > a);
2021        let c: SmallVec<i32, 8> = SmallVec::from([1, 2]);
2022        assert_eq!(a.partial_cmp(&c), Some(Ordering::Equal));
2023    }
2024
2025    #[test]
2026    fn into_iter_exact_size_and_clone() {
2027        let v: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
2028        let mut it = v.into_iter();
2029        assert_eq!(it.len(), 3);
2030        assert_eq!(it.size_hint(), (3, Some(3)));
2031        let mut cloned = it.clone();
2032        assert_eq!(cloned.next(), Some(1));
2033        // The original is unaffected by the clone.
2034        assert_eq!(it.next(), Some(1));
2035        assert_eq!(it.next(), Some(2));
2036        assert_eq!(it.next(), Some(3));
2037        assert_eq!(it.next(), None);
2038    }
2039
2040    #[test]
2041    fn default_is_inline_empty() {
2042        let v: SmallVec<i32, 4> = Default::default();
2043        assert!(v.is_inline());
2044        assert!(v.is_empty());
2045    }
2046
2047    #[test]
2048    fn debug_inline_and_heap() {
2049        let inline: SmallVec<i32, 4> = SmallVec::from([1, 2, 3]);
2050        assert_eq!(alloc::format!("{inline:?}"), "[1, 2, 3]");
2051        let heap: SmallVec<i32, 1> = SmallVec::from([1, 2, 3]);
2052        assert_eq!(alloc::format!("{heap:?}"), "[1, 2, 3]");
2053    }
2054
2055    #[test]
2056    #[cfg(feature = "bytes")]
2057    #[should_panic(expected = "advance out of bounds")]
2058    fn buf_mut_advance_out_of_bounds_panics() {
2059        use bytes::BufMut;
2060
2061        let mut v: SmallVec<u8, 4> = SmallVec::new();
2062        // SAFETY: this deliberately violates the `BufMut` contract to check
2063        // the bounds assertion inside `advance_mut`.
2064        unsafe { v.advance_mut(10) };
2065    }
2066
2067    #[test]
2068    #[cfg(feature = "bytes")]
2069    fn buf_mut_chunk_mut_grows_when_full() {
2070        use bytes::BufMut;
2071
2072        let mut v: SmallVec<u8, 4> = SmallVec::new();
2073        v.put_slice(b"abcd");
2074        assert!(v.is_inline());
2075        // `chunk_mut` must grow (spill) so there is always somewhere to write.
2076        let chunk = v.chunk_mut();
2077        assert!(chunk.len() > 0);
2078        assert!(!v.is_inline());
2079        assert_eq!(&*v, b"abcd");
2080    }
2081}