1use alloc::vec::Vec;
29use core::mem::MaybeUninit;
30
31enum Repr<T, const N: usize> {
33 Inline {
34 data: [MaybeUninit<T>; N],
35 len: usize,
36 },
37 Heap(Vec<T>),
38}
39
40pub struct SmallVec<T, const N: usize> {
48 repr: Repr<T, N>,
49}
50
51impl<T, const N: usize> SmallVec<T, N> {
52 #[must_use]
54 pub const fn new() -> Self {
55 Self {
56 repr: Repr::Inline {
57 data: [const { MaybeUninit::uninit() }; N],
58 len: 0,
59 },
60 }
61 }
62
63 #[must_use]
67 pub fn with_capacity(cap: usize) -> Self {
68 if cap <= N {
69 Self::new()
70 } else {
71 Self {
72 repr: Repr::Heap(Vec::with_capacity(cap)),
73 }
74 }
75 }
76
77 #[must_use]
79 pub fn len(&self) -> usize {
80 match &self.repr {
81 Repr::Inline { len, .. } => *len,
82 Repr::Heap(v) => v.len(),
83 }
84 }
85
86 #[must_use]
88 pub fn is_empty(&self) -> bool {
89 self.len() == 0
90 }
91
92 #[must_use]
94 pub fn capacity(&self) -> usize {
95 match &self.repr {
96 Repr::Inline { .. } => N,
97 Repr::Heap(v) => v.capacity(),
98 }
99 }
100
101 #[must_use]
103 pub fn is_inline(&self) -> bool {
104 matches!(self.repr, Repr::Inline { .. })
105 }
106
107 #[must_use]
109 pub fn as_slice(&self) -> &[T] {
110 match &self.repr {
111 Repr::Inline { data, len } => {
112 unsafe { core::slice::from_raw_parts(data.as_ptr().cast::<T>(), *len) }
114 }
115 Repr::Heap(v) => v.as_slice(),
116 }
117 }
118
119 #[must_use]
121 pub fn as_mut_slice(&mut self) -> &mut [T] {
122 match &mut self.repr {
123 Repr::Inline { data, len } => {
124 unsafe { core::slice::from_raw_parts_mut(data.as_mut_ptr().cast::<T>(), *len) }
126 }
127 Repr::Heap(v) => v.as_mut_slice(),
128 }
129 }
130
131 #[must_use]
133 pub fn as_ptr(&self) -> *const T {
134 match &self.repr {
135 Repr::Inline { data, .. } => data.as_ptr().cast::<T>(),
136 Repr::Heap(v) => v.as_ptr(),
137 }
138 }
139
140 #[must_use]
142 pub fn as_mut_ptr(&mut self) -> *mut T {
143 match &mut self.repr {
144 Repr::Inline { data, .. } => data.as_mut_ptr().cast::<T>(),
145 Repr::Heap(v) => v.as_mut_ptr(),
146 }
147 }
148
149 pub fn push(&mut self, value: T) {
153 match &mut self.repr {
154 Repr::Inline { data, len } if *len < N => {
155 data[*len].write(value);
156 *len += 1;
157 }
158 _ => {
159 self.spill_and_push(value);
160 }
161 }
162 }
163
164 fn spill_and_push(&mut self, value: T) {
166 match &mut self.repr {
167 Repr::Heap(v) => {
168 v.push(value);
169 }
170 Repr::Inline { .. } => {
171 self.spill();
172 if let Repr::Heap(v) = &mut self.repr {
173 v.push(value);
174 }
175 }
176 }
177 }
178
179 #[must_use]
181 pub fn pop(&mut self) -> Option<T> {
182 match &mut self.repr {
183 Repr::Inline { data, len } => {
184 if *len == 0 {
185 return None;
186 }
187 *len -= 1;
188 Some(unsafe { data[*len].assume_init_read() })
190 }
191 Repr::Heap(v) => v.pop(),
192 }
193 }
194
195 pub fn insert(&mut self, index: usize, value: T) {
201 let len = self.len();
202 assert!(index <= len, "index out of bounds");
203
204 if let Repr::Inline { .. } = &self.repr {
205 if len >= N {
206 self.spill();
207 }
208 }
209
210 match &mut self.repr {
211 Repr::Inline { data, len } => {
212 unsafe {
214 let ptr = data.as_mut_ptr().add(index);
215 core::ptr::copy(ptr, ptr.add(1), *len - index);
216 ptr.cast::<T>().write(value);
217 }
218 *len += 1;
219 }
220 Repr::Heap(v) => v.insert(index, value),
221 }
222 }
223
224 pub fn remove(&mut self, index: usize) -> T {
230 let len = self.len();
231 assert!(index < len, "index out of bounds");
232
233 match &mut self.repr {
234 Repr::Inline { data, len } => {
235 unsafe {
238 let ptr = data.as_mut_ptr().add(index);
239 let value = ptr.cast::<T>().read();
240 core::ptr::copy(ptr.add(1), ptr, *len - index - 1);
241 *len -= 1;
242 value
243 }
244 }
245 Repr::Heap(v) => v.remove(index),
246 }
247 }
248
249 pub fn swap_remove(&mut self, index: usize) -> T {
256 let len = self.len();
257 assert!(index < len, "index out of bounds");
258
259 match &mut self.repr {
260 Repr::Inline { data, len } => {
261 *len -= 1;
262 data.swap(index, *len);
263 unsafe { data[*len].assume_init_read() }
265 }
266 Repr::Heap(v) => v.swap_remove(index),
267 }
268 }
269
270 pub fn clear(&mut self) {
272 match &mut self.repr {
273 Repr::Inline { data, len } => {
274 for item in data.iter_mut().take(*len) {
275 unsafe {
277 item.assume_init_drop();
278 }
279 }
280 *len = 0;
281 }
282 Repr::Heap(v) => v.clear(),
283 }
284 }
285
286 pub fn truncate(&mut self, new_len: usize) {
290 let len = self.len();
291 if new_len >= len {
292 return;
293 }
294
295 match &mut self.repr {
296 Repr::Inline { data, len } => {
297 for item in data.iter_mut().take(*len).skip(new_len) {
298 unsafe {
300 item.assume_init_drop();
301 }
302 }
303 *len = new_len;
304 }
305 Repr::Heap(v) => v.truncate(new_len),
306 }
307 }
308
309 #[must_use]
311 pub fn last(&self) -> Option<&T> {
312 let len = self.len();
313 if len == 0 {
314 None
315 } else {
316 Some(&self.as_slice()[len - 1])
317 }
318 }
319
320 #[must_use]
322 pub fn last_mut(&mut self) -> Option<&mut T> {
323 let len = self.len();
324 if len == 0 {
325 None
326 } else {
327 Some(&mut self.as_mut_slice()[len - 1])
328 }
329 }
330
331 pub fn reserve(&mut self, additional: usize) {
335 let needed = self.len() + additional;
336 if needed <= self.capacity() {
337 return;
338 }
339
340 match &self.repr {
341 Repr::Inline { .. } => {
342 self.spill_with_capacity(needed);
343 }
344 Repr::Heap(_) => {
345 let old = core::mem::replace(&mut self.repr, Repr::Inline {
347 data: [const { MaybeUninit::uninit() }; N],
348 len: 0,
349 });
350 if let Repr::Heap(mut v) = old {
351 v.reserve(additional);
352 self.repr = Repr::Heap(v);
353 }
354 }
355 }
356 }
357
358 pub fn spill(&mut self) {
362 if let Repr::Inline { len, .. } = &self.repr {
363 let cap = core::cmp::max(2 * N, *len);
364 self.spill_with_capacity(cap);
365 }
366 }
367
368 fn spill_with_capacity(&mut self, cap: usize) {
370 let old = core::mem::replace(
371 &mut self.repr,
372 Repr::Inline {
373 data: [const { MaybeUninit::uninit() }; N],
374 len: 0,
375 },
376 );
377
378 if let Repr::Inline { data, len } = old {
379 let mut v = Vec::with_capacity(cap);
380 unsafe {
384 core::ptr::copy_nonoverlapping(data.as_ptr().cast::<T>(), v.as_mut_ptr(), len);
385 v.set_len(len);
386 }
387 self.repr = Repr::Heap(v);
388 }
389 }
390
391 pub fn shrink_to_fit(&mut self) {
395 if let Repr::Heap(_) = &self.repr {
396 let len = self.len();
397 if len <= N {
398 let old = core::mem::replace(
399 &mut self.repr,
400 Repr::Inline {
401 data: [const { MaybeUninit::uninit() }; N],
402 len: 0,
403 },
404 );
405 if let Repr::Heap(v) = old {
406 let mut data = [const { MaybeUninit::uninit() }; N];
407 unsafe {
409 core::ptr::copy_nonoverlapping(
410 v.as_ptr(),
411 data.as_mut_ptr().cast::<T>(),
412 len,
413 );
414 }
415 let mut v = v;
418 unsafe {
420 v.set_len(0);
421 }
422 drop(v);
423 self.repr = Repr::Inline { data, len };
424 }
425 } else {
426 let old = core::mem::replace(
428 &mut self.repr,
429 Repr::Inline {
430 data: [const { MaybeUninit::uninit() }; N],
431 len: 0,
432 },
433 );
434 if let Repr::Heap(mut v) = old {
435 v.shrink_to_fit();
436 self.repr = Repr::Heap(v);
437 }
438 }
439 }
440 }
441
442 pub fn iter(&self) -> core::slice::Iter<'_, T> {
444 self.as_slice().iter()
445 }
446
447 pub fn iter_mut(&mut self) -> core::slice::IterMut<'_, T> {
449 self.as_mut_slice().iter_mut()
450 }
451
452 #[must_use]
454 pub fn into_vec(mut self) -> Vec<T> {
455 self.spill();
456 let old = core::mem::replace(
457 &mut self.repr,
458 Repr::Inline {
459 data: [const { MaybeUninit::uninit() }; N],
460 len: 0,
461 },
462 );
463 match old {
464 Repr::Heap(v) => v,
465 Repr::Inline { .. } => unreachable!(),
466 }
467 }
468}
469
470impl<T: Clone, const N: usize> Clone for SmallVec<T, N> {
471 fn clone(&self) -> Self {
472 match &self.repr {
473 Repr::Inline { data, len } => {
474 let mut new_data = [const { MaybeUninit::uninit() }; N];
475 for i in 0..*len {
476 new_data[i].write(unsafe { data[i].assume_init_ref() }.clone());
478 }
479 Self {
480 repr: Repr::Inline {
481 data: new_data,
482 len: *len,
483 },
484 }
485 }
486 Repr::Heap(v) => Self {
487 repr: Repr::Heap(v.clone()),
488 },
489 }
490 }
491}
492
493impl<T: core::fmt::Debug, const N: usize> core::fmt::Debug for SmallVec<T, N> {
494 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
495 f.debug_list().entries(self.as_slice()).finish()
496 }
497}
498
499impl<T, const N: usize> Default for SmallVec<T, N> {
500 fn default() -> Self {
501 Self::new()
502 }
503}
504
505impl<T, const N: usize> Drop for SmallVec<T, N> {
506 fn drop(&mut self) {
507 if let Repr::Inline { data, len } = &mut self.repr {
508 for item in data.iter_mut().take(*len) {
509 unsafe {
511 item.assume_init_drop();
512 }
513 }
514 *len = 0;
515 }
516 }
518}
519
520impl<T: PartialEq, const N: usize> PartialEq for SmallVec<T, N> {
521 fn eq(&self, other: &Self) -> bool {
522 self.as_slice() == other.as_slice()
523 }
524}
525
526impl<T: Eq, const N: usize> Eq for SmallVec<T, N> {}
527
528impl<T: core::hash::Hash, const N: usize> core::hash::Hash for SmallVec<T, N> {
529 fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
530 self.as_slice().hash(state);
531 }
532}
533
534impl<T: PartialOrd, const N: usize> PartialOrd for SmallVec<T, N> {
535 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
536 self.as_slice().partial_cmp(other.as_slice())
537 }
538}
539
540impl<T: Ord, const N: usize> Ord for SmallVec<T, N> {
541 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
542 self.as_slice().cmp(other.as_slice())
543 }
544}
545
546impl<T, const N: usize> core::ops::Deref for SmallVec<T, N> {
547 type Target = [T];
548
549 fn deref(&self) -> &[T] {
550 self.as_slice()
551 }
552}
553
554impl<T, const N: usize> core::ops::DerefMut for SmallVec<T, N> {
555 fn deref_mut(&mut self) -> &mut [T] {
556 self.as_mut_slice()
557 }
558}
559
560impl<T, const N: usize> core::ops::Index<usize> for SmallVec<T, N> {
561 type Output = T;
562
563 fn index(&self, index: usize) -> &T {
564 &self.as_slice()[index]
565 }
566}
567
568impl<T, const N: usize> core::ops::IndexMut<usize> for SmallVec<T, N> {
569 fn index_mut(&mut self, index: usize) -> &mut T {
570 &mut self.as_mut_slice()[index]
571 }
572}
573
574impl<T, const N: usize> From<Vec<T>> for SmallVec<T, N> {
575 fn from(v: Vec<T>) -> Self {
576 Self {
577 repr: Repr::Heap(v),
578 }
579 }
580}
581
582impl<T: Clone, const N: usize> From<&[T]> for SmallVec<T, N> {
583 fn from(slice: &[T]) -> Self {
584 let mut sv = Self::with_capacity(slice.len());
585 for item in slice {
586 sv.push(item.clone());
587 }
588 sv
589 }
590}
591
592impl<T, const N: usize> From<[T; N]> for SmallVec<T, N> {
593 fn from(array: [T; N]) -> Self {
594 let mut data: [MaybeUninit<T>; N] = [const { MaybeUninit::uninit() }; N];
595 unsafe {
599 let src: *const T = (&raw const array).cast::<T>();
600 for (i, slot) in data.iter_mut().enumerate().take(N) {
601 slot.write(src.add(i).read());
602 }
603 core::mem::forget(array);
604 }
605 Self {
606 repr: Repr::Inline { data, len: N },
607 }
608 }
609}
610
611impl<T, const N: usize> AsRef<[T]> for SmallVec<T, N> {
612 fn as_ref(&self) -> &[T] {
613 self.as_slice()
614 }
615}
616
617impl<T, const N: usize> AsMut<[T]> for SmallVec<T, N> {
618 fn as_mut(&mut self) -> &mut [T] {
619 self.as_mut_slice()
620 }
621}
622
623impl<T, const N: usize> core::borrow::Borrow<[T]> for SmallVec<T, N> {
624 fn borrow(&self) -> &[T] {
625 self.as_slice()
626 }
627}
628
629impl<T, const N: usize> core::borrow::BorrowMut<[T]> for SmallVec<T, N> {
630 fn borrow_mut(&mut self) -> &mut [T] {
631 self.as_mut_slice()
632 }
633}
634
635impl<T, const N: usize> Extend<T> for SmallVec<T, N> {
636 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
637 for item in iter {
638 self.push(item);
639 }
640 }
641}
642
643impl<T, const N: usize> FromIterator<T> for SmallVec<T, N> {
644 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
645 let mut sv = Self::new();
646 sv.extend(iter);
647 sv
648 }
649}
650
651pub struct SmallVecIntoIter<T, const N: usize> {
655 inner: IntoIterRepr<T, N>,
656}
657
658enum IntoIterRepr<T, const N: usize> {
659 Inline {
660 data: [MaybeUninit<T>; N],
661 start: usize,
662 end: usize,
663 },
664 Heap(alloc::vec::IntoIter<T>),
665}
666
667impl<T, const N: usize> Iterator for SmallVecIntoIter<T, N> {
668 type Item = T;
669
670 fn next(&mut self) -> Option<T> {
671 match &mut self.inner {
672 IntoIterRepr::Inline { data, start, end } => {
673 if *start >= *end {
674 return None;
675 }
676 let idx = *start;
677 *start += 1;
678 Some(unsafe { data[idx].assume_init_read() })
680 }
681 IntoIterRepr::Heap(iter) => iter.next(),
682 }
683 }
684
685 fn size_hint(&self) -> (usize, Option<usize>) {
686 let remaining = self.len();
687 (remaining, Some(remaining))
688 }
689}
690
691impl<T, const N: usize> DoubleEndedIterator for SmallVecIntoIter<T, N> {
692 fn next_back(&mut self) -> Option<T> {
693 match &mut self.inner {
694 IntoIterRepr::Inline { data, start, end } => {
695 if *start >= *end {
696 return None;
697 }
698 *end -= 1;
699 Some(unsafe { data[*end].assume_init_read() })
701 }
702 IntoIterRepr::Heap(iter) => iter.next_back(),
703 }
704 }
705}
706
707impl<T, const N: usize> ExactSizeIterator for SmallVecIntoIter<T, N> {
708 fn len(&self) -> usize {
709 match &self.inner {
710 IntoIterRepr::Inline { start, end, .. } => *end - *start,
711 IntoIterRepr::Heap(iter) => iter.len(),
712 }
713 }
714}
715
716impl<T, const N: usize> Drop for SmallVecIntoIter<T, N> {
717 fn drop(&mut self) {
718 if let IntoIterRepr::Inline { data, start, end } = &mut self.inner {
720 for item in data.iter_mut().take(*end).skip(*start) {
721 unsafe {
723 item.assume_init_drop();
724 }
725 }
726 *start = *end;
727 }
728 }
730}
731
732impl<T, const N: usize> IntoIterator for SmallVec<T, N> {
733 type Item = T;
734 type IntoIter = SmallVecIntoIter<T, N>;
735
736 fn into_iter(mut self) -> SmallVecIntoIter<T, N> {
737 let inner = match &mut self.repr {
738 Repr::Inline { len, .. } => {
739 let end = *len;
740 *len = 0;
743 let old = core::mem::replace(
744 &mut self.repr,
745 Repr::Inline {
746 data: [const { MaybeUninit::uninit() }; N],
747 len: 0,
748 },
749 );
750 match old {
751 Repr::Inline { data, .. } => IntoIterRepr::Inline {
752 data,
753 start: 0,
754 end,
755 },
756 Repr::Heap(_) => unreachable!(),
757 }
758 }
759 Repr::Heap(_) => {
760 let old = core::mem::replace(
761 &mut self.repr,
762 Repr::Inline {
763 data: [const { MaybeUninit::uninit() }; N],
764 len: 0,
765 },
766 );
767 match old {
768 Repr::Heap(v) => IntoIterRepr::Heap(v.into_iter()),
769 Repr::Inline { .. } => unreachable!(),
770 }
771 }
772 };
773 SmallVecIntoIter { inner }
775 }
776}
777
778impl<'a, T, const N: usize> IntoIterator for &'a SmallVec<T, N> {
779 type Item = &'a T;
780 type IntoIter = core::slice::Iter<'a, T>;
781
782 fn into_iter(self) -> Self::IntoIter {
783 self.iter()
784 }
785}
786
787impl<'a, T, const N: usize> IntoIterator for &'a mut SmallVec<T, N> {
788 type Item = &'a mut T;
789 type IntoIter = core::slice::IterMut<'a, T>;
790
791 fn into_iter(self) -> Self::IntoIter {
792 self.iter_mut()
793 }
794}
795
796#[cfg(test)]
797mod tests {
798 extern crate alloc;
799 use alloc::string::String;
800 use alloc::vec;
801
802 use super::*;
803
804 #[test]
805 fn new_is_empty() {
806 let sv = SmallVec::<i32, 4>::new();
807 assert!(sv.is_empty());
808 assert_eq!(sv.len(), 0);
809 assert!(sv.is_inline());
810 }
811
812 #[test]
813 fn push_within_capacity() {
814 let mut sv = SmallVec::<i32, 4>::new();
815 sv.push(1);
816 sv.push(2);
817 sv.push(3);
818 assert_eq!(sv.len(), 3);
819 assert!(sv.is_inline());
820 assert_eq!(sv.as_slice(), &[1, 2, 3]);
821 }
822
823 #[test]
824 fn push_spills_to_heap() {
825 let mut sv = SmallVec::<i32, 2>::new();
826 sv.push(1);
827 sv.push(2);
828 assert!(sv.is_inline());
829 sv.push(3);
830 assert!(!sv.is_inline());
831 assert_eq!(sv.as_slice(), &[1, 2, 3]);
832 }
833
834 #[test]
835 fn pop_inline() {
836 let mut sv = SmallVec::<i32, 4>::new();
837 sv.push(10);
838 sv.push(20);
839 assert_eq!(sv.pop(), Some(20));
840 assert_eq!(sv.pop(), Some(10));
841 assert_eq!(sv.pop(), None);
842 }
843
844 #[test]
845 fn pop_heap() {
846 let mut sv = SmallVec::<i32, 1>::new();
847 sv.push(1);
848 sv.push(2);
849 sv.push(3);
850 assert_eq!(sv.pop(), Some(3));
851 assert_eq!(sv.pop(), Some(2));
852 assert_eq!(sv.pop(), Some(1));
853 assert_eq!(sv.pop(), None);
854 }
855
856 #[test]
857 fn insert_inline() {
858 let mut sv = SmallVec::<i32, 4>::new();
859 sv.push(1);
860 sv.push(3);
861 sv.insert(1, 2);
862 assert_eq!(sv.as_slice(), &[1, 2, 3]);
863 assert!(sv.is_inline());
864 }
865
866 #[test]
867 fn insert_causes_spill() {
868 let mut sv = SmallVec::<i32, 2>::new();
869 sv.push(1);
870 sv.push(3);
871 sv.insert(1, 2);
872 assert_eq!(sv.as_slice(), &[1, 2, 3]);
873 assert!(!sv.is_inline());
874 }
875
876 #[test]
877 fn remove_inline() {
878 let mut sv = SmallVec::<i32, 4>::new();
879 sv.push(1);
880 sv.push(2);
881 sv.push(3);
882 let removed = sv.remove(1);
883 assert_eq!(removed, 2);
884 assert_eq!(sv.as_slice(), &[1, 3]);
885 }
886
887 #[test]
888 fn swap_remove_inline() {
889 let mut sv = SmallVec::<i32, 4>::new();
890 sv.push(10);
891 sv.push(20);
892 sv.push(30);
893 let removed = sv.swap_remove(0);
894 assert_eq!(removed, 10);
895 assert_eq!(sv.as_slice(), &[30, 20]);
896 }
897
898 #[test]
899 fn clear_inline() {
900 let mut sv = SmallVec::<i32, 4>::new();
901 sv.push(1);
902 sv.push(2);
903 sv.clear();
904 assert!(sv.is_empty());
905 }
906
907 #[test]
908 fn clear_heap() {
909 let mut sv = SmallVec::<i32, 1>::new();
910 sv.push(1);
911 sv.push(2);
912 sv.push(3);
913 sv.clear();
914 assert!(sv.is_empty());
915 }
916
917 #[test]
918 fn truncate_inline() {
919 let mut sv = SmallVec::<i32, 4>::new();
920 sv.push(1);
921 sv.push(2);
922 sv.push(3);
923 sv.truncate(1);
924 assert_eq!(sv.as_slice(), &[1]);
925 }
926
927 #[test]
928 fn truncate_noop() {
929 let mut sv = SmallVec::<i32, 4>::new();
930 sv.push(1);
931 sv.truncate(5);
932 assert_eq!(sv.len(), 1);
933 }
934
935 #[test]
936 fn last_and_last_mut() {
937 let mut sv = SmallVec::<i32, 4>::new();
938 assert_eq!(sv.last(), None);
939 sv.push(1);
940 sv.push(2);
941 assert_eq!(sv.last(), Some(&2));
942 *sv.last_mut().unwrap() = 99;
943 assert_eq!(sv.last(), Some(&99));
944 }
945
946 #[test]
947 fn capacity_inline() {
948 let sv = SmallVec::<i32, 4>::new();
949 assert_eq!(sv.capacity(), 4);
950 }
951
952 #[test]
953 fn with_capacity_inline() {
954 let sv = SmallVec::<i32, 4>::with_capacity(3);
955 assert!(sv.is_inline());
956 assert_eq!(sv.capacity(), 4);
957 }
958
959 #[test]
960 fn with_capacity_heap() {
961 let sv = SmallVec::<i32, 4>::with_capacity(10);
962 assert!(!sv.is_inline());
963 assert!(sv.capacity() >= 10);
964 }
965
966 #[test]
967 fn reserve_spills() {
968 let mut sv = SmallVec::<i32, 2>::new();
969 sv.push(1);
970 sv.reserve(5);
971 assert!(!sv.is_inline());
972 assert!(sv.capacity() >= 6);
973 assert_eq!(sv.as_slice(), &[1]);
974 }
975
976 #[test]
977 fn spill_and_shrink_back() {
978 let mut sv = SmallVec::<i32, 4>::new();
979 sv.push(1);
980 sv.push(2);
981 sv.spill();
982 assert!(!sv.is_inline());
983 assert_eq!(sv.as_slice(), &[1, 2]);
984 sv.shrink_to_fit();
985 assert!(sv.is_inline());
986 assert_eq!(sv.as_slice(), &[1, 2]);
987 }
988
989 #[test]
990 fn clone_inline() {
991 let mut sv = SmallVec::<i32, 4>::new();
992 sv.push(1);
993 sv.push(2);
994 let sv2 = sv.clone();
995 assert_eq!(sv2.as_slice(), &[1, 2]);
996 assert!(sv2.is_inline());
997 }
998
999 #[test]
1000 fn clone_heap() {
1001 let mut sv = SmallVec::<i32, 1>::new();
1002 sv.push(1);
1003 sv.push(2);
1004 let sv2 = sv.clone();
1005 assert_eq!(sv2.as_slice(), &[1, 2]);
1006 }
1007
1008 #[test]
1009 fn debug_format() {
1010 let mut sv = SmallVec::<i32, 4>::new();
1011 sv.push(1);
1012 sv.push(2);
1013 let s = alloc::format!("{sv:?}");
1014 assert_eq!(s, "[1, 2]");
1015 }
1016
1017 #[test]
1018 fn eq_and_ord() {
1019 let mut a = SmallVec::<i32, 4>::new();
1020 a.push(1);
1021 a.push(2);
1022 let mut b = SmallVec::<i32, 4>::new();
1023 b.push(1);
1024 b.push(2);
1025 assert_eq!(a, b);
1026
1027 let mut c = SmallVec::<i32, 4>::new();
1028 c.push(1);
1029 c.push(3);
1030 assert!(a < c);
1031 }
1032
1033 #[test]
1034 fn index_and_index_mut() {
1035 let mut sv = SmallVec::<i32, 4>::new();
1036 sv.push(10);
1037 sv.push(20);
1038 assert_eq!(sv[0], 10);
1039 sv[0] = 99;
1040 assert_eq!(sv[0], 99);
1041 }
1042
1043 #[test]
1044 fn from_vec() {
1045 let sv: SmallVec<i32, 4> = SmallVec::from(vec![1, 2, 3]);
1046 assert!(!sv.is_inline());
1047 assert_eq!(sv.as_slice(), &[1, 2, 3]);
1048 }
1049
1050 #[test]
1051 fn from_slice() {
1052 let sv: SmallVec<i32, 4> = SmallVec::from([1, 2, 3].as_slice());
1053 assert!(sv.is_inline());
1054 assert_eq!(sv.as_slice(), &[1, 2, 3]);
1055 }
1056
1057 #[test]
1058 fn from_array() {
1059 let sv: SmallVec<i32, 3> = SmallVec::from([1, 2, 3]);
1060 assert!(sv.is_inline());
1061 assert_eq!(sv.as_slice(), &[1, 2, 3]);
1062 }
1063
1064 #[test]
1065 fn extend_and_from_iter() {
1066 let sv: SmallVec<i32, 2> = (0..5).collect();
1067 assert_eq!(sv.as_slice(), &[0, 1, 2, 3, 4]);
1068 }
1069
1070 #[test]
1071 fn into_iter_inline() {
1072 let mut sv = SmallVec::<i32, 4>::new();
1073 sv.push(1);
1074 sv.push(2);
1075 sv.push(3);
1076 let collected: Vec<i32> = sv.into_iter().collect();
1077 assert_eq!(collected, vec![1, 2, 3]);
1078 }
1079
1080 #[test]
1081 fn into_iter_heap() {
1082 let mut sv = SmallVec::<i32, 1>::new();
1083 sv.push(1);
1084 sv.push(2);
1085 sv.push(3);
1086 let collected: Vec<i32> = sv.into_iter().collect();
1087 assert_eq!(collected, vec![1, 2, 3]);
1088 }
1089
1090 #[test]
1091 fn into_iter_double_ended() {
1092 let mut sv = SmallVec::<i32, 4>::new();
1093 sv.push(1);
1094 sv.push(2);
1095 sv.push(3);
1096 let collected: Vec<i32> = sv.into_iter().rev().collect();
1097 assert_eq!(collected, vec![3, 2, 1]);
1098 }
1099
1100 #[test]
1101 fn into_iter_exact_size() {
1102 let mut sv = SmallVec::<i32, 4>::new();
1103 sv.push(1);
1104 sv.push(2);
1105 let mut iter = sv.into_iter();
1106 assert_eq!(iter.len(), 2);
1107 iter.next();
1108 assert_eq!(iter.len(), 1);
1109 }
1110
1111 #[test]
1112 fn into_vec_conversion() {
1113 let mut sv = SmallVec::<i32, 4>::new();
1114 sv.push(1);
1115 sv.push(2);
1116 let v = sv.into_vec();
1117 assert_eq!(v, vec![1, 2]);
1118 }
1119
1120 #[test]
1121 fn drop_elements_properly() {
1122 use alloc::rc::Rc;
1123 let rc = Rc::new(());
1124 let mut sv = SmallVec::<Rc<()>, 2>::new();
1125 sv.push(rc.clone());
1126 sv.push(rc.clone());
1127 assert_eq!(Rc::strong_count(&rc), 3);
1128 drop(sv);
1129 assert_eq!(Rc::strong_count(&rc), 1);
1130 }
1131
1132 #[test]
1133 fn drop_elements_on_heap() {
1134 use alloc::rc::Rc;
1135 let rc = Rc::new(());
1136 let mut sv = SmallVec::<Rc<()>, 1>::new();
1137 sv.push(rc.clone());
1138 sv.push(rc.clone());
1139 sv.push(rc.clone());
1140 assert_eq!(Rc::strong_count(&rc), 4);
1141 drop(sv);
1142 assert_eq!(Rc::strong_count(&rc), 1);
1143 }
1144
1145 #[test]
1146 fn into_iter_drops_remaining() {
1147 use alloc::rc::Rc;
1148 let rc = Rc::new(());
1149 let mut sv = SmallVec::<Rc<()>, 4>::new();
1150 sv.push(rc.clone());
1151 sv.push(rc.clone());
1152 sv.push(rc.clone());
1153 let mut iter = sv.into_iter();
1154 iter.next(); assert_eq!(Rc::strong_count(&rc), 3); drop(iter);
1157 assert_eq!(Rc::strong_count(&rc), 1);
1158 }
1159
1160 #[test]
1161 fn as_ref_as_mut_borrow() {
1162 let mut sv = SmallVec::<i32, 4>::new();
1163 sv.push(1);
1164 sv.push(2);
1165 let r: &[i32] = sv.as_ref();
1166 assert_eq!(r, &[1, 2]);
1167 let m: &mut [i32] = sv.as_mut();
1168 m[0] = 99;
1169 assert_eq!(sv[0], 99);
1170 }
1171
1172 #[test]
1173 fn deref_and_deref_mut() {
1174 let mut sv = SmallVec::<i32, 4>::new();
1175 sv.push(3);
1176 sv.push(1);
1177 sv.push(2);
1178 assert!(sv.contains(&1));
1180 sv.sort();
1182 assert_eq!(&*sv, &[1, 2, 3]);
1183 }
1184
1185 #[test]
1186 fn hash_consistent() {
1187 use core::hash::{Hash, Hasher};
1188
1189 struct SimpleHasher(u64);
1190 impl Hasher for SimpleHasher {
1191 fn finish(&self) -> u64 {
1192 self.0
1193 }
1194 fn write(&mut self, bytes: &[u8]) {
1195 for &b in bytes {
1196 self.0 = self.0.wrapping_mul(31).wrapping_add(u64::from(b));
1197 }
1198 }
1199 }
1200
1201 let mut a = SmallVec::<i32, 4>::new();
1202 a.push(1);
1203 a.push(2);
1204
1205 let mut b = SmallVec::<i32, 4>::new();
1206 b.push(1);
1207 b.push(2);
1208
1209 let mut ha = SimpleHasher(0);
1210 let mut hb = SimpleHasher(0);
1211 a.hash(&mut ha);
1212 b.hash(&mut hb);
1213 assert_eq!(ha.finish(), hb.finish());
1214 }
1215
1216 #[test]
1217 fn spill_with_drop_types() {
1218 let mut sv = SmallVec::<String, 2>::new();
1219 sv.push(String::from("hello"));
1220 sv.push(String::from("world"));
1221 sv.spill();
1222 assert!(!sv.is_inline());
1223 assert_eq!(sv.as_slice(), &["hello", "world"]);
1224 }
1225
1226 #[test]
1227 fn shrink_to_fit_stays_heap_when_too_large() {
1228 let mut sv = SmallVec::<i32, 2>::new();
1229 for i in 0..10 {
1230 sv.push(i);
1231 }
1232 sv.shrink_to_fit();
1233 assert!(!sv.is_inline());
1234 assert_eq!(sv.len(), 10);
1235 }
1236
1237 #[test]
1238 fn zero_inline_capacity() {
1239 let mut sv = SmallVec::<i32, 0>::new();
1240 assert!(sv.is_inline());
1241 sv.push(1); assert!(!sv.is_inline());
1243 assert_eq!(sv.as_slice(), &[1]);
1244 }
1245}