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#[derive(Clone)]
48pub enum SmallVec<T, const N: usize> {
49 Inline(heapless::Vec<T, N>),
51 Heap(Vec<T>),
53}
54
55impl<T, const N: usize> SmallVec<T, N> {
56 #[inline]
60 pub const fn new() -> Self {
61 SmallVec::Inline(heapless::Vec::new())
62 }
63
64 #[inline]
66 pub const fn inline_size() -> usize {
67 N
68 }
69
70 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
205 pub fn is_empty(&self) -> bool {
206 self.len() == 0
207 }
208
209 #[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 #[inline]
223 pub fn is_inline(&self) -> bool {
224 matches!(self, SmallVec::Inline(_))
225 }
226
227 #[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 #[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 #[inline]
251 pub fn as_ptr(&self) -> *const T {
252 self.as_slice().as_ptr()
253 }
254
255 #[inline]
261 pub fn as_mut_ptr(&mut self) -> *mut T {
262 self.as_mut_slice().as_mut_ptr()
263 }
264
265 #[inline]
268 pub fn push(&mut self, value: T) {
269 if let SmallVec::Inline(v) = self
270 && v.len() >= N
271 {
272 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[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 #[inline]
420 pub fn dedup(&mut self)
421 where
422 T: PartialEq,
423 {
424 self.dedup_by(|a, b| a == b);
425 }
426
427 #[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 #[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 #[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 #[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 #[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 #[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 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 #[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 #[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 #[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 #[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 #[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 #[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 #[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
645fn 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
664pub enum IntoIter<T, const N: usize> {
669 Inline(heapless::vec::IntoIter<T, N, usize>),
671 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
736pub enum Drain<'a, T, const N: usize> {
742 Inline(heapless::vec::Drain<'a, T, usize>),
744 Heap(alloc::vec::Drain<'a, T>),
746}
747
748impl<T, const N: usize> Drain<'_, T, N> {
749 #[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
909macro_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 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 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 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 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 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 #[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 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 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 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 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 let chunk = v.chunk_mut();
2077 assert!(chunk.len() > 0);
2078 assert!(!v.is_inline());
2079 assert_eq!(&*v, b"abcd");
2080 }
2081}