tiny_vec/lib.rs
1/* Copyright (C) 2025 Saúl Valdelvira
2 *
3 * This program is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <https://www.gnu.org/licenses/>. */
14
15//! Tiny Vec
16//!
17//! A dynamic array that can store a small amount of elements on the stack.
18//!
19//! This struct provides a vec-like API, but performs small-vector optimization.
20//! This means that a `TinyVec<T, N>` stores up to N elements on the stack.
21//! If the vector grows bigger than that, it moves the contents to the heap.
22//!
23//! # Example
24//! ```
25//! use tiny_vec::TinyVec;
26//!
27//! let mut tv = TinyVec::<u8, 16>::new();
28//!
29//! for n in 0..16 {
30//! tv.push(n);
31//! }
32//!
33//! // Up to this point, no heap allocations are needed.
34//! // All the elements are stored on the stack.
35//!
36//! tv.push(123); // This moves the vector to the heap
37//!
38//! assert_eq!(&tv[..], &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
39//! 10, 11, 12, 13, 14, 15, 123])
40//! ```
41//!
42//! # Memory layout
43//! For a TinyVec<T, N>
44//!
45//! On the stack (length <= N)
46//! - [T; N] : Data
47//! - usize : Length
48//!
49//! On the heap (length > N)
50//! - T* : Data
51//! - usize : Capacity
52//! - usize : Length
53//!
54//! If N is equal to `sizeof (T*, usize) / sizeof T`, the
55//! TinyVec is the same size as a regular vector \
56//! NOTE: The [n_elements_for_stack] function returns the maximun
57//! number of elements for a type, such that it doesn't waste extra
58//! space when moved to the heap
59
60#![allow(incomplete_features)]
61#![cfg_attr(feature = "default-size", feature(generic_const_exprs))]
62#![cfg_attr(feature = "use-specialization", feature(min_specialization))]
63
64#![no_std]
65
66extern crate alloc;
67use alloc::vec::Vec;
68use alloc::boxed::Box;
69
70use core::mem::{self, ManuallyDrop, MaybeUninit};
71use core::ops::{Deref, DerefMut};
72use core::ptr::NonNull;
73use core::{fmt, ptr};
74use core::slice;
75
76mod raw;
77use raw::RawVec;
78
79union TinyVecInner<T, const N: usize> {
80 stack: ManuallyDrop<[MaybeUninit<T>; N]>,
81 raw: RawVec<T>,
82}
83
84impl<T, const N: usize> TinyVecInner<T, N> {
85
86 #[inline(always)]
87 const unsafe fn as_ptr_stack(&self) -> *const T {
88 unsafe { &self.stack as *const _ as *const T }
89 }
90
91 #[inline(always)]
92 const unsafe fn as_ptr_stack_mut(&mut self) -> *mut T {
93 unsafe { &mut self.stack as *mut _ as *mut T }
94 }
95
96 #[inline(always)]
97 const unsafe fn as_ptr_heap(&self) -> *const T {
98 unsafe { self.raw.ptr.as_ptr() }
99 }
100
101 #[inline(always)]
102 const unsafe fn as_ptr_heap_mut(&mut self) -> *mut T {
103 unsafe { self.raw.ptr.as_ptr() }
104 }
105}
106
107#[repr(transparent)]
108struct Length(usize);
109
110impl Length {
111 #[inline(always)]
112 const fn new_stack(len: usize) -> Self {
113 Self(len << 1)
114 }
115
116 #[inline(always)]
117 const fn new_heap(len: usize) -> Self {
118 Self(len << 1 | 0b1)
119 }
120
121 #[inline(always)]
122 const fn is_stack(&self) -> bool {
123 (self.0 & 0b1) == 0
124 }
125
126 #[inline(always)]
127 const fn set_heap(&mut self) {
128 self.0 |= 0b1;
129 }
130
131 #[inline(always)]
132 const fn set_stack(&mut self) {
133 self.0 &= 0b0;
134 }
135
136 #[inline(always)]
137 const fn set(&mut self, n: usize) {
138 self.0 &= 0b1;
139 self.0 |= n << 1;
140 }
141
142 #[inline(always)]
143 const fn get(&self) -> usize {
144 self.0 >> 1
145 }
146
147 #[inline(always)]
148 const fn add(&mut self, n: usize) {
149 self.0 += n << 1;
150 }
151
152 #[inline(always)]
153 const fn sub(&mut self, n: usize) {
154 self.0 -= n << 1;
155 }
156}
157
158/// Macro to create [TinyVec]s
159///
160/// # Example
161/// ```
162/// use tiny_vec::{TinyVec, tinyvec};
163///
164/// // Create a TinyVec with a list of elements
165/// let v: TinyVec<_, 10> = tinyvec![1, 2, 3, 4];
166/// assert_eq!(&v[0..4], &[1, 2, 3, 4]);
167///
168/// // Create a TinyVec with 100 zeroes
169/// let v: TinyVec<_, 10> = tinyvec![0; 100];
170/// assert_eq!(v[20], 0);
171/// ```
172#[macro_export]
173macro_rules! tinyvec {
174 ($elem:expr; $n:expr) => ({
175 let mut tv = $crate::TinyVec::new();
176 tv.resize($n, $elem);
177 tv
178 });
179 ($($x:expr),*$(,)?) => ({
180 $crate::TinyVec::from(&[ $( $x ,)*])
181 });
182}
183
184/// The maximun number of elements that can be stored in the stack
185/// for the vector, without incrementing it's size
186///
187/// This means, that [`n_elements_for_stack`] for T returns the max
188/// number of elements, so that when switching to a heap allocated
189/// buffer, no stack size is wasted
190///
191/// # Examples
192/// ```
193/// use tiny_vec::n_elements_for_stack;
194///
195/// assert_eq!(n_elements_for_stack::<u8>(), 16);
196/// assert_eq!(n_elements_for_stack::<u16>(), 8);
197/// assert_eq!(n_elements_for_stack::<i32>(), 4);
198/// ```
199pub const fn n_elements_for_stack<T>() -> usize {
200 mem::size_of::<RawVec<T>>() / mem::size_of::<T>()
201}
202
203/// A dynamic array that can store a small amount of elements on the stack.
204pub struct TinyVec<T,
205 #[cfg(not(feature = "default-size"))]
206 const N: usize,
207
208 #[cfg(feature = "default-size")]
209 const N: usize = { n_elements_for_stack::<T>() },
210> {
211 inner: TinyVecInner<T, N>,
212 len: Length,
213}
214
215impl<T, const N: usize> TinyVec<T, N> {
216
217 unsafe fn switch_to_heap(&mut self, n: usize, exact: bool) {
218 debug_assert!(self.lives_on_stack());
219
220 let mut vec = RawVec::new();
221 if exact {
222 vec.expand_if_needed_exact(0, self.len.get() + n);
223 } else {
224 vec.expand_if_needed(0, self.len.get() + n);
225 }
226 unsafe {
227 let src = self.inner.as_ptr_stack();
228 let dst = vec.ptr.as_ptr();
229 ptr::copy_nonoverlapping(src, dst, self.len());
230 self.inner.raw = vec;
231 }
232 self.len.set_heap();
233 }
234
235 unsafe fn switch_to_stack(&mut self) {
236 debug_assert!(!self.lives_on_stack());
237
238 let mut rv = unsafe { self.inner.raw };
239
240 let stack = [ const { MaybeUninit::uninit() }; N ];
241
242 unsafe {
243 let src = rv.ptr.as_ptr();
244 let dst = stack.as_ptr() as *mut T;
245 ptr::copy_nonoverlapping(src,dst,self.len());
246 rv.destroy();
247 }
248
249 self.inner.stack = ManuallyDrop::new(stack);
250 self.len.set_stack();
251 }
252}
253
254impl<T, const N: usize> TinyVec<T, N> {
255
256 /// Creates a new [TinyVec]
257 pub const fn new() -> Self {
258 let stack = [ const { MaybeUninit::uninit() }; N ];
259 Self {
260 inner: TinyVecInner { stack: ManuallyDrop::new(stack) },
261 len: Length::new_stack(0),
262 }
263 }
264
265 /// Creates a new [TinyVec] with the specified initial capacity
266 pub fn with_capacity(cap: usize) -> Self {
267 let mut len = Length(0);
268 let inner = if cap <= N {
269 let s = [const { MaybeUninit::uninit() }; N];
270 TinyVecInner {
271 stack: ManuallyDrop::new(s)
272 }
273 } else {
274 len.set_heap();
275 TinyVecInner {
276 raw: RawVec::with_capacity(cap)
277 }
278 };
279
280 Self { inner, len }
281 }
282
283 /// Creates a new [TinyVec] from the given array
284 ///
285 /// # Example
286 /// ```
287 /// use tiny_vec::TinyVec;
288 ///
289 /// let tv = TinyVec::<i32, 10>::from_array([1, 2, 3, 4]);
290 ///
291 /// assert_eq!(tv.capacity(), 10);
292 /// assert!(tv.lives_on_stack());
293 /// ```
294 pub fn from_array<const M: usize>(arr: [T; M]) -> Self {
295 let arr = ManuallyDrop::new(arr);
296 let mut tv = Self::with_capacity(M);
297
298 let src = arr.as_ptr();
299 let dst = tv.as_mut_ptr();
300
301 unsafe {
302 ptr::copy(src, dst, M);
303 tv.set_len(M);
304 }
305
306 tv
307 }
308
309 /// Like [from_array](Self::from_array), but the array's length
310 /// and the TinyVec's N are equal, so we can call it on const functions.
311 ///
312 /// # Example
313 /// ```
314 /// use tiny_vec::TinyVec;
315 ///
316 /// let tv = TinyVec::from_array_eq_size([1, 2, 3, 4]);
317 ///
318 /// assert_eq!(tv.capacity(), 4);
319 /// assert!(tv.lives_on_stack());
320 /// ```
321 pub const fn from_array_eq_size(arr: [T; N]) -> Self {
322 let mut tv = Self::new();
323
324 let src = arr.as_ptr();
325 let dst = tv.as_mut_ptr();
326
327 unsafe {
328 ptr::copy(src, dst, N);
329 tv.set_len(N);
330 }
331
332 mem::forget(arr);
333 tv
334 }
335
336 /// Creates a new [TinyVec] from the given [Vec]
337 ///
338 /// The returned TinyVec will have no extra capacity.
339 /// This means that it won't reuse the Vec's buffer,
340 /// and won't allocate more that vec.len() elements.
341 ///
342 /// If the vector has less than N elements, they'll
343 /// be stored in the stack.
344 ///
345 /// If you want to reuse the Vec's buffer, use the
346 /// [from_vec_reuse_buffer](Self::from_vec_reuse_buffer) function
347 ///
348 /// # Example
349 /// ```
350 /// use tiny_vec::TinyVec;
351 ///
352 /// let vec = vec![1, 2, 3, 4, 5];
353 ///
354 /// let tv = TinyVec::<i32, 10>::from_vec(vec);
355 ///
356 /// /* vec fits on the stack, so it won't heap-allocate the TinyVec */
357 /// assert!(tv.lives_on_stack());
358 /// ```
359 pub fn from_vec(mut vec: Vec<T>) -> Self {
360 let mut tv = Self::with_capacity(vec.len());
361 let dst = tv.as_mut_ptr();
362 let src = vec.as_ptr();
363 unsafe {
364 ptr::copy(src, dst, vec.len());
365 vec.set_len(0);
366 }
367 tv
368 }
369
370 /// Like [from_vec](Self::from_vec), but it reuses the
371 /// [Vec]'s buffer.
372 ///
373 /// The returned TinyVec will have no extra capacity.
374 /// This means that it won't reuse the Vec's buffer,
375 /// and won't allocate more that vec.len() elements.
376 ///
377 /// For a version that creates a TinyVec with the mininum
378 /// capacity for this vec, check [from_vec](Self::from_vec)
379 ///
380 /// # Example
381 /// ```
382 /// use tiny_vec::TinyVec;
383 ///
384 /// let vec = vec![1, 2, 3, 4, 5];
385 ///
386 /// let tv = TinyVec::<i32, 10>::from_vec_reuse_buffer(vec);
387 ///
388 /// /* This version of from_vec, will use the same buffer vec used */
389 /// assert!(!tv.lives_on_stack());
390 /// ```
391 pub fn from_vec_reuse_buffer(vec: Vec<T>) -> Self {
392 let mut vec = ManuallyDrop::new(vec);
393
394 let ptr = vec.as_mut_ptr();
395 let ptr = unsafe { NonNull::new_unchecked(ptr) };
396
397 let len = Length::new_heap(vec.len());
398 let cap = vec.capacity();
399 let raw = RawVec { cap, ptr };
400
401 let inner = TinyVecInner { raw };
402 Self { inner, len }
403 }
404
405 /// Creates a TinyVec from a boxed slice of T
406 pub fn from_boxed_slice(boxed: Box<[T]>) -> Self {
407 let len = boxed.len();
408 let ptr = Box::into_raw(boxed);
409 let ptr = unsafe { NonNull::new_unchecked(ptr as *mut T) };
410
411 let raw = RawVec { ptr, cap: len };
412
413 Self {
414 inner: TinyVecInner { raw },
415 len: Length::new_heap(len)
416 }
417 }
418
419 /// Builds a TinyVec from a TinyVec with a different capacity generic parameter
420 ///
421 /// # Example
422 /// ```
423 /// use tiny_vec::TinyVec;
424 ///
425 /// let v1 = TinyVec::<i32, 10>::from(&[1, 2, 3, 4]);
426 ///
427 /// let v2 = TinyVec::<i32, 7>::from_tiny_vec(v1.clone());
428 /// assert!(v2.lives_on_stack());
429 ///
430 /// let v3 = TinyVec::<i32, 2>::from_tiny_vec(v1);
431 /// /* v3 must be heap-allocated, since it can only store 2 elements
432 /// on the stack, and v1 has 3*/
433 /// assert!(!v3.lives_on_stack());
434 ///
435 /// ```
436 pub fn from_tiny_vec<const M: usize>(mut vec: TinyVec<T, M>) -> Self {
437 let len = vec.len();
438 if len > N && len > M {
439 /* If the buffer must be on the heap on both src and dest,
440 * just copy the RawVec from vec to Self */
441 let tv = Self {
442 len: Length::new_heap(len),
443 inner: TinyVecInner {
444 raw: unsafe { vec.inner.raw }
445 }
446 };
447 mem::forget(vec);
448 return tv
449 }
450
451 let mut tv = Self::with_capacity(len);
452 let src = vec.as_ptr();
453 let dst = tv.as_mut_ptr();
454 unsafe {
455 /* SAFETY: src points to vec, and dst to tv. They are two different
456 * objects, so their buffers can't overap */
457 ptr::copy_nonoverlapping(src, dst, len);
458 vec.set_len(0);
459 tv.set_len(len);
460 }
461 tv
462 }
463
464 /// Creates a new [TinyVec] from the given slice.
465 ///
466 /// This function clones the elements in the slice.
467 /// If the type T is [Copy], the [from_slice_copied](Self::from_slice_copied)
468 /// function is a more optimized alternative
469 pub fn from_slice(slice: &[T]) -> Self
470 where
471 T: Clone
472 {
473 let mut v = Self::with_capacity(slice.len());
474 v.extend_from_slice(slice);
475 v
476 }
477
478 /// Creates a new [TinyVec] from the given slice.
479 ///
480 /// This function copies the slice into the buffer, which
481 /// is faster that calling [clone](Clone::clone).
482 /// That's why it requires T to implement [Copy].
483 ///
484 /// For a cloning alternative, use [from_slice](Self::from_slice)
485 pub fn from_slice_copied(slice: &[T]) -> Self
486 where
487 T: Copy
488 {
489 let mut v = Self::with_capacity(slice.len());
490 v.extend_from_slice_copied(slice);
491 v
492 }
493
494 /// Returns the number of elements inside this vec
495 #[inline]
496 pub const fn len(&self) -> usize { self.len.get() }
497
498 /// Returns true if the vector is empty
499 #[inline]
500 pub const fn is_empty(&self) -> bool { self.len.get() == 0 }
501
502 /// Returns the allocated capacity for this vector
503 #[inline]
504 pub const fn capacity(&self) -> usize {
505 if self.len.is_stack() {
506 N
507 } else {
508 unsafe { self.inner.raw.cap }
509 }
510 }
511
512 /// Returns true if the vector is currently using stack memory.
513 ///
514 /// This means that [Self::len] <= `N`
515 ///
516 /// # Example
517 /// ```
518 /// use tiny_vec::TinyVec;
519 ///
520 /// let mut vec = TinyVec::<i32, 5>::new();
521 ///
522 /// for n in 0..5 {
523 /// vec.push(n)
524 /// }
525 ///
526 /// assert!(vec.lives_on_stack());
527 /// vec.push(6);
528 /// assert!(!vec.lives_on_stack());
529 /// ```
530 #[inline]
531 pub const fn lives_on_stack(&self) -> bool { self.len.is_stack() }
532
533 /// Gets a const pointer to the vec's buffer
534 #[inline]
535 pub const fn as_ptr(&self) -> *const T {
536 unsafe {
537 if self.len.is_stack() {
538 self.inner.as_ptr_stack()
539 } else {
540 self.inner.as_ptr_heap()
541 }
542 }
543 }
544
545 /// Gets a mutable pointer to the vec's buffer
546 #[inline]
547 pub const fn as_mut_ptr(&mut self) -> *mut T {
548 unsafe {
549 if self.len.is_stack() {
550 self.inner.as_ptr_stack_mut()
551 } else {
552 self.inner.as_ptr_heap_mut()
553 }
554 }
555 }
556
557 /// Gets a mutable pointer to the vec's buffer as a [NonNull]
558 #[inline]
559 pub const fn as_non_null(&mut self) -> NonNull<T> {
560 debug_assert!(!self.as_mut_ptr().is_null());
561 unsafe {
562 /* SAFETY: as_mut_ptr should never return a null ptr */
563 NonNull::new_unchecked(self.as_mut_ptr())
564 }
565 }
566
567 /// Gets a slice of the whole vector
568 #[inline]
569 pub const fn as_slice(&self) -> &[T] {
570 unsafe {
571 slice::from_raw_parts(self.as_ptr(), self.len.get())
572 }
573 }
574
575 /// Gets a mutable slice of the whole vector
576 #[inline]
577 pub const fn as_mut_slice(&mut self) -> &mut [T] {
578 unsafe {
579 slice::from_raw_parts_mut(self.as_mut_ptr(), self.len.get())
580 }
581 }
582
583 /// Reserves space for, at least, n elements
584 ///
585 /// # Example
586 /// ```
587 /// use tiny_vec::TinyVec;
588 ///
589 /// let mut vec = TinyVec::<i32, 5>::new();
590 ///
591 /// assert_eq!(vec.capacity(), 5);
592 /// assert!(vec.lives_on_stack());
593 /// vec.reserve(10);
594 /// assert!(vec.capacity() >= 10);
595 /// assert!(!vec.lives_on_stack());
596 /// ```
597 pub fn reserve(&mut self, n: usize) {
598 if self.len.is_stack() {
599 if self.len.get() + n > N {
600 unsafe { self.switch_to_heap(n, false); }
601 }
602 } else {
603 unsafe {
604 self.inner.raw.expand_if_needed(self.len.get(), n);
605 }
606 }
607 }
608
609 /// Reserves space for n more elements, but unline
610 /// [reserve](Self::reserve), this function doesn't over-allocate.
611 ///
612 /// # Example
613 /// ```
614 /// use tiny_vec::TinyVec;
615 ///
616 /// let mut vec = TinyVec::<i32, 5>::new();
617 ///
618 /// assert_eq!(vec.capacity(), 5);
619 /// assert!(vec.lives_on_stack());
620 /// vec.reserve_exact(10);
621 /// assert_eq!(vec.capacity(), 10);
622 /// assert!(!vec.lives_on_stack());
623 /// ```
624 pub fn reserve_exact(&mut self, n: usize) {
625 if self.len.is_stack() {
626 if self.len.get() + n > N {
627 unsafe { self.switch_to_heap(n, true); }
628 }
629 } else {
630 let vec = unsafe { &mut self.inner.raw };
631 let len = self.len.get();
632 let new_cap = vec.cap.max(len + n);
633 vec.expand_if_needed_exact(len, new_cap);
634 }
635 }
636
637 /// Appends an element to the back of the vector
638 /// This operation is O(1), if no resize takes place.
639 /// If the buffer needs to be resized, it has an O(n)
640 /// time complexity.
641 ///
642 /// See also: [push_within_capacity](Self::push_within_capacity)
643 ///
644 /// # Example
645 /// ```
646 /// use tiny_vec::TinyVec;
647 ///
648 /// let mut vec = TinyVec::<i32, 5>::from(&[1, 2, 3, 4]);
649 ///
650 /// vec.push(5); // No resize. O(1)
651 /// vec.push(6); // Resize, must realloc. O(n)
652 ///
653 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4, 5, 6]);
654 /// ```
655 #[inline]
656 pub fn push(&mut self, elem: T) {
657 self.reserve(1);
658 unsafe { self.push_unchecked(elem); }
659 }
660
661 /// Appends an element to the back of the vector without
662 /// checking for space.
663 ///
664 /// # Safety
665 /// The caller must ensure that there's enought capacity
666 /// for this element.
667 /// This means that [Self::len] < [Self::capacity]
668 ///
669 /// # Example
670 /// ```
671 /// use tiny_vec::TinyVec;
672 ///
673 /// let mut vec = TinyVec::<i32, 10>::with_capacity(10);
674 ///
675 /// // We've allocated a TinyVec with an initial capacity of 10.
676 /// // We can skip the bounds checking, since there will be room
677 /// // for all the elements on the iterator
678 /// for n in 0..10 {
679 /// unsafe { vec.push_unchecked(n); }
680 /// }
681 /// assert_eq!(vec.as_slice(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
682 /// ```
683 pub unsafe fn push_unchecked(&mut self, elem: T) {
684 unsafe {
685 let dst = self.as_mut_ptr().add(self.len.get());
686 dst.write(elem);
687 }
688 self.len.add(1);
689 }
690
691 /// Try to push an element inside the vector, only if
692 /// there's room for it. If the push would've caused a
693 /// reallocation of the buffer, returns the value wrapped
694 /// on an [Err] variant.
695 ///
696 /// This operation has O(1) time complexity in all cases.
697 ///
698 /// # Example
699 /// ```
700 /// use tiny_vec::TinyVec;
701 ///
702 /// let mut vec = TinyVec::<i32, 5>::from(&[1, 2, 3, 4]);
703 ///
704 /// assert!(vec.push_within_capacity(5).is_ok());
705 ///
706 /// // No room left, the value is returned
707 /// assert_eq!(vec.push_within_capacity(6), Err(6));
708 /// ```
709 pub fn push_within_capacity(&mut self, val: T) -> Result<(),T> {
710 if self.len.get() < self.capacity() {
711 unsafe { self.push_unchecked(val); }
712 Ok(())
713 } else {
714 Err(val)
715 }
716 }
717 /// Removes the last element of this vector (if present)
718 pub fn pop(&mut self) -> Option<T> {
719 if self.len.get() == 0 {
720 None
721 } else {
722 self.len.sub(1);
723 let val = unsafe {
724 self.as_ptr()
725 .add(self.len.get())
726 .read()
727 };
728 Some(val)
729 }
730 }
731
732 /// Inserts an element in the given index position
733 ///
734 /// This operation has a worst case time complexity of O(n),
735 /// since it needs to move elements on range [index, len) one
736 /// position to the right.
737 ///
738 /// # Example
739 /// ```
740 /// use tiny_vec::TinyVec;
741 ///
742 /// let mut vec = TinyVec::<i32, 10>::from(&[1, 2, 3, 4]);
743 ///
744 /// vec.insert(2, -1);
745 /// assert_eq!(vec.as_slice(), &[1, 2, -1, 3, 4]);
746 ///
747 /// // An insert on vec.len() behaves like a push
748 /// vec.insert(vec.len(), 5);
749 /// assert_eq!(vec.as_slice(), &[1, 2, -1, 3, 4, 5]);
750 /// ```
751 pub fn insert(&mut self, index: usize, elem: T) -> Result<(),T> {
752 if index > self.len.get() {
753 return Err(elem)
754 }
755 unsafe { self.insert_unckecked(index, elem); }
756 Ok(())
757 }
758
759 /// Like [insert](Self::insert), but without bounds checking
760 ///
761 /// # Safety
762 /// The index should be <= self.len
763 pub unsafe fn insert_unckecked(&mut self, index: usize, elem: T) {
764 self.reserve(1);
765 unsafe {
766 let ptr = self.as_mut_ptr();
767 ptr::copy(
768 ptr.add(index),
769 ptr.add(index + 1),
770 self.len.get() - index,
771 );
772 ptr.add(index).write(elem);
773 }
774 self.len.add(1);
775 }
776
777 /// Inserts all the elements of the given slice into the
778 /// vector, at the given index
779 ///
780 /// This function clones the elements in the slice.
781 ///
782 /// If the type T is [Copy], the [insert_slice_copied]
783 /// function is a more optimized alternative
784 ///
785 /// # Errors
786 /// If the index is out of bounds, returns the slice as an [Err] variant
787 ///
788 /// # Example
789 /// ```
790 /// use tiny_vec::TinyVec;
791 ///
792 /// let mut vec = TinyVec::from(["abc".to_string(), "ghi".to_string()]);
793 /// vec.insert_slice(1, &[
794 /// "__".to_string(),
795 /// "def".to_string(),
796 /// "__".to_string(),
797 /// ]);
798 ///
799 /// assert_eq!(vec.as_slice(), &["abc", "__", "def", "__", "ghi"]);
800 /// ```
801 /// [insert_slice_copied]: Self::insert_slice_copied
802 pub fn insert_slice<'a>(&mut self, index: usize, elems: &'a [T]) -> Result<(), &'a [T]>
803 where
804 T: Clone
805 {
806 self.insert_iter(index, elems.iter().cloned()).map_err(|_| elems)
807 }
808
809 /// Inserts all the elements of the given slice into the
810 /// vector, at the given index
811 ///
812 /// This function copies the slice into the buffer, which
813 /// is faster that calling [clone]
814 /// That's why it requires T to implement [Copy].
815 ///
816 /// For a cloning alternative, use [insert_slice]
817 ///
818 /// # Example
819 /// ```
820 /// use tiny_vec::TinyVec;
821 ///
822 /// let mut vec = TinyVec::from([1, 2, 3, 4]);
823 /// vec.insert_slice_copied(2, &[-1, -2, -3]);
824 /// assert_eq!(vec.as_slice(), &[1, 2, -1, -2, -3, 3, 4]);
825 /// ```
826 /// [clone]: Clone::clone
827 /// [insert_slice]: Self::insert_slice
828 pub fn insert_slice_copied<'a>(&mut self, index: usize, elems: &'a [T]) -> Result<(), &'a [T]>
829 where
830 T: Copy
831 {
832 if index > self.len() {
833 return Err(elems)
834 }
835
836 let len = elems.len();
837 self.reserve(len);
838 unsafe {
839 let ptr = self.as_mut_ptr();
840 ptr::copy(
841 ptr.add(index),
842 ptr.add(index + len),
843 self.len.get() - index,
844 );
845 ptr::copy_nonoverlapping(
846 elems.as_ptr(),
847 ptr.add(index),
848 len
849 );
850 }
851 self.len.add(len);
852
853 Ok(())
854 }
855
856 /// Inserts all the elements on the given iterator at the given index
857 ///
858 /// # Errors
859 /// If the index is out of bounds, returns the passed iterator, wrapped
860 /// on an [Err] variant.
861 ///
862 /// # Example
863 /// ```
864 /// use tiny_vec::TinyVec;
865 ///
866 /// let mut vec = TinyVec::from([1, 2, 3, 4]);
867 ///
868 /// vec.insert_iter(2, (-3..-1));
869 /// assert_eq!(vec.as_slice(), &[1, 2, -3, -2, 3, 4]);
870 /// ```
871 pub fn insert_iter<I>(&mut self, index: usize, it: I) -> Result<(), I>
872 where
873 I: IntoIterator<Item = T>,
874 <I as IntoIterator>::IntoIter: ExactSizeIterator,
875 {
876 if index > self.len() {
877 return Err(it);
878 }
879
880 let it = it.into_iter();
881 let len = it.len();
882 self.reserve(len);
883 unsafe {
884 let ptr = self.as_mut_ptr();
885 ptr::copy(
886 ptr.add(index),
887 ptr.add(index + len),
888 self.len.get() - index,
889 );
890 let mut ptr = ptr.add(index);
891 for elem in it {
892 ptr.write(elem);
893 ptr = ptr.add(1);
894 self.len.add(1);
895 }
896 }
897 Ok(())
898 }
899
900 /// Resizes the vector, cloning elem to fill any possible new slots
901 ///
902 /// If new_len < self.len, behaves like [truncate](Self::truncate)
903 ///
904 /// # Example
905 /// ```
906 /// use tiny_vec::TinyVec;
907 ///
908 /// let mut vec = TinyVec::<i32, 5>::new();
909 ///
910 /// vec.resize(5, 0);
911 /// assert_eq!(vec.len(), 5);
912 /// assert_eq!(vec.as_slice(), &[0, 0, 0, 0, 0]);
913 /// ```
914 pub fn resize(&mut self, new_len: usize, elem: T)
915 where
916 T: Clone
917 {
918 if new_len < self.len() {
919 self.truncate(new_len);
920 } else {
921 let n = new_len - self.len();
922 self.reserve(n);
923
924 unsafe {
925 let mut ptr = self.as_mut_ptr().add(self.len());
926 let len = &mut self.len;
927
928 for _ in 1..n {
929 ptr::write(ptr, elem.clone());
930 ptr = ptr.add(1);
931 len.add(1);
932 }
933
934 if n > 0 {
935 ptr::write(ptr, elem);
936 len.add(1);
937 }
938 }
939 }
940 }
941
942 /// Resizes the vector, using the given generator closure
943 /// to fill any possible new slots
944 ///
945 /// If new_len < self.len, behaves like [truncate](Self::truncate)
946 ///
947 /// # Example
948 /// ```
949 /// use tiny_vec::TinyVec;
950 ///
951 /// let mut v = TinyVec::<i32, 10>::new();
952 ///
953 /// let mut n = 0;
954 /// v.resize_with(5, || {
955 /// n += 1;
956 /// n
957 /// });
958 ///
959 /// assert_eq!(v.len(), 5);
960 /// assert_eq!(v.as_slice(), &[1, 2, 3, 4, 5]);
961 /// ```
962 pub fn resize_with<F>(&mut self, cap: usize, mut f: F)
963 where
964 F: FnMut() -> T
965 {
966 if cap < self.len() {
967 self.truncate(cap);
968 } else {
969 let n = cap - self.len();
970 self.reserve(n);
971
972 unsafe {
973 let mut ptr = self.as_mut_ptr().add(self.len());
974 let len = &mut self.len;
975
976 for _ in 0..n {
977 ptr::write(ptr, f());
978 ptr = ptr.add(1);
979 len.add(1);
980 }
981 }
982 }
983 }
984
985 /// Resizes the vector, initializing the new memory to 0
986 ///
987 /// # Safety
988 /// The caller must ensure that an all-zero byte representation
989 /// is valid for T.
990 ///
991 /// If [mem::zeroed] is valid for T, this function is valid too.
992 ///
993 /// # Example
994 /// ```
995 /// use tiny_vec::TinyVec;
996 ///
997 /// let mut v = TinyVec::<_, 10>::from(&[1, 2, 3]);
998 ///
999 /// /* SAFETY: i32 can be initialized to 0b0 */
1000 /// unsafe { v.resize_zeroed(8); }
1001 ///
1002 /// /* The above is the same as
1003 /// v.resize_with(8, || unsafe { core::mem::zeroed() }); */
1004 ///
1005 /// assert_eq!(v.len(), 8);
1006 /// assert_eq!(v.as_slice(), &[1, 2, 3, 0, 0, 0, 0, 0]);
1007 /// ```
1008 pub unsafe fn resize_zeroed(&mut self, cap: usize) {
1009 if cap < self.len() {
1010 self.truncate(cap);
1011 } else {
1012 let n = cap - self.len();
1013 self.reserve(n);
1014 unsafe {
1015 let ptr = self.as_mut_ptr().add(self.len());
1016 ptr.write_bytes(0, n);
1017 }
1018 self.len.add(n);
1019 }
1020 }
1021
1022 /// Like [remove](Self::remove), but without bounds checking
1023 ///
1024 /// # Safety
1025 /// index must be within bounds (less than self.len)
1026 pub unsafe fn remove_unchecked(&mut self, index: usize) -> T {
1027 debug_assert!(
1028 index < self.len(),
1029 "Index is >= than {}, this will trigger UB",
1030 self.len()
1031 );
1032
1033 unsafe {
1034 self.len.sub(1);
1035 let result = self.as_mut_ptr().add(index).read();
1036 ptr::copy(
1037 self.as_ptr().add(index + 1),
1038 self.as_mut_ptr().add(index),
1039 self.len.get() - index,
1040 );
1041 result
1042 }
1043 }
1044
1045 /// Removes the element at the given index.
1046 /// If the index is out of bounds, returns [None]
1047 #[inline]
1048 pub fn remove(&mut self, index: usize) -> Option<T> {
1049 if index >= self.len.get() { return None }
1050 /* SAFETY: We've just checked that index is < self.len */
1051 Some(unsafe { self.remove_unchecked(index) })
1052 }
1053
1054 /// Swaps the elements on index a and b
1055 ///
1056 /// For a non-panicking version of this function,
1057 /// see [swap_checked](Self::swap_checked)
1058 ///
1059 /// # Panics
1060 /// If either a or b are out of bounds for [0, len)
1061 ///
1062 /// # Example
1063 /// ```
1064 /// use tiny_vec::TinyVec;
1065 ///
1066 /// let mut vec = TinyVec::from([1, 2, 3, 4, 5]);
1067 ///
1068 /// vec.swap(1, 3);
1069 /// assert_eq!(vec.as_slice(), &[1, 4, 3, 2, 5]);
1070 /// ```
1071 #[inline]
1072 pub fn swap(&mut self, a: usize, b: usize) {
1073 self.swap_checked(a, b).unwrap_or_else(|n| {
1074 panic!("Index {n} out of bounds")
1075 });
1076 }
1077
1078 /// Swaps the elements on index a and b
1079 ///
1080 /// # Errors
1081 /// If an index is out of bounds for [0, len),
1082 /// returns that index inside an [Err] variant.
1083 pub const fn swap_checked(&mut self, a: usize, b: usize) -> Result<(),usize> {
1084 if a >= self.len.get() {
1085 return Err(a)
1086 };
1087 if b >= self.len.get() {
1088 return Err(b)
1089 };
1090 /* SAFETY: a and b are in bounds */
1091 unsafe { self.swap_unchecked(a, b); }
1092 Ok(())
1093 }
1094
1095 /// Swaps the elements on index a and b, without checking bounds
1096 ///
1097 /// # Safety
1098 /// The caller must ensure that both `a` and `b` are in bounds [0, len)
1099 /// For a checked version of this function, check [swap_checked](Self::swap_checked)
1100 pub const unsafe fn swap_unchecked(&mut self, a: usize, b: usize) {
1101 unsafe {
1102 let ptr = self.as_mut_ptr();
1103 let ap = ptr.add(a);
1104 let bp = ptr.add(b);
1105 ptr::swap(ap, bp);
1106 }
1107 }
1108
1109 /// Removes the element at the given index by swaping it with the last one
1110 pub fn swap_remove(&mut self, index: usize) -> Option<T> {
1111 if index >= self.len.get() {
1112 None
1113 } else if index == self.len.get() - 1 {
1114 self.pop()
1115 } else {
1116 /* SAFETY: index in < self.len */
1117 unsafe { self.swap_unchecked(index, self.len.get() - 1) }
1118 self.pop()
1119 }
1120 }
1121
1122 /// Shrinks the capacity of the vector to fit exactly it's length
1123 #[inline]
1124 pub fn shrink_to_fit(&mut self) {
1125 if self.len.is_stack() { return }
1126
1127 /* SAFETY: It's safe to assume that we are on the heap,
1128 * because of the check above */
1129 if self.len.get() <= N {
1130 unsafe { self.switch_to_stack(); }
1131 } else {
1132 unsafe { self.inner.raw.shrink_to_fit(self.len.get()); };
1133 }
1134 }
1135
1136 /// Sets the length of the vector.
1137 ///
1138 /// # Safety
1139 /// The caller must ensure that changing the length doesn't
1140 /// leave the vector in an inconsistent state. This is:
1141 ///
1142 /// - If you reduce de length, you may leak memory, if the type
1143 /// stored need to be droped
1144 /// - If you extend the length, you may access uninitialized memory
1145 #[inline]
1146 pub const unsafe fn set_len(&mut self, len: usize) {
1147 self.len.set(len);
1148 }
1149
1150 /// Reduces the length in the vector, dropping the elements
1151 /// in range [new_len, old_len)
1152 ///
1153 /// If the new_len is >= old_len, this function does nothing.
1154 ///
1155 /// # Example
1156 /// ```
1157 /// use tiny_vec::TinyVec;
1158 ///
1159 /// let mut vec = TinyVec::from([1, 2, 3, 4, 5]);
1160 /// vec.truncate(3);
1161 /// assert_eq!(vec.as_slice(), &[1, 2, 3]);
1162 /// ```
1163 pub fn truncate(&mut self, len: usize) {
1164 if len < self.len.get() {
1165 for e in &mut self[len..] {
1166 unsafe { ptr::drop_in_place(e) }
1167 }
1168 unsafe { self.set_len(len); }
1169 }
1170 }
1171
1172 /// Copies all the elements of the given slice into the vector
1173 ///
1174 /// This function clones the elements in the slice.
1175 ///
1176 /// If the type T is [Copy], the [extend_from_slice_copied]
1177 /// function is a more optimized alternative
1178 ///
1179 /// # Example
1180 /// ```
1181 /// use tiny_vec::TinyVec;
1182 ///
1183 /// let mut vec = TinyVec::<String, 5>::new();
1184 /// vec.extend_from_slice(&[
1185 /// "abc".to_string(),
1186 /// "def".to_string(),
1187 /// "__".to_string(),
1188 /// ]);
1189 ///
1190 /// assert_eq!(vec.as_slice(), &["abc", "def", "__"]);
1191 /// ```
1192 /// [extend_from_slice_copied]: Self::extend_from_slice_copied
1193 pub fn extend_from_slice(&mut self, s: &[T])
1194 where
1195 T: Clone
1196 {
1197 self.extend(s.iter().cloned());
1198 }
1199
1200 /// Copies all the elements of the given slice into the vector
1201 ///
1202 /// This function copies the slice into the buffer, which
1203 /// is faster that calling [clone]
1204 /// That's why it requires T to implement [Copy].
1205 ///
1206 /// For a cloning alternative, use [extend_from_slice]
1207 ///
1208 /// # Example
1209 /// ```
1210 /// use tiny_vec::TinyVec;
1211 ///
1212 /// let mut vec = TinyVec::<i32, 5>::new();
1213 /// vec.extend_from_slice_copied(&[1, 2, 3, 4]);
1214 ///
1215 /// assert_eq!(vec.as_slice(), &[1, 2, 3, 4]);
1216 /// ```
1217 /// [clone]: Clone::clone
1218 /// [extend_from_slice]: Self::extend_from_slice
1219 pub fn extend_from_slice_copied(&mut self, s: &[T])
1220 where
1221 T: Copy
1222 {
1223 let len = s.len();
1224 let src = s.as_ptr();
1225
1226 self.reserve(len);
1227
1228 unsafe {
1229 ptr::copy(
1230 src,
1231 self.as_mut_ptr().add(self.len.get()),
1232 len
1233 )
1234 }
1235
1236 self.len.add(len);
1237 }
1238
1239 /// Converts this [TinyVec] into a boxed slice
1240 ///
1241 /// # Example
1242 /// ```
1243 /// use tiny_vec::TinyVec;
1244 ///
1245 /// let mut v = TinyVec::<_, 10>::from(&[1, 2, 3, 4]);
1246 /// let b = v.into_boxed_slice();
1247 ///
1248 /// assert_eq!(&b[..], [1, 2, 3, 4]);
1249 /// ```
1250 pub fn into_boxed_slice(self) -> Box<[T]> {
1251 let mut vec = ManuallyDrop::new(self);
1252
1253 if vec.lives_on_stack() {
1254 unsafe { vec.switch_to_heap(0, true) };
1255 }
1256 debug_assert!(!vec.lives_on_stack());
1257
1258 let len = vec.len();
1259 unsafe { vec.inner.raw.shrink_to_fit(len); }
1260 debug_assert_eq!(len, vec.capacity());
1261
1262 let ptr = vec.as_mut_ptr();
1263 unsafe {
1264 let slice = slice::from_raw_parts_mut(ptr, len);
1265 Box::from_raw(slice)
1266 }
1267 }
1268
1269 /// Converts this [TinyVec] into a standard [Vec]
1270 ///
1271 /// # Example
1272 /// ```
1273 /// use tiny_vec::TinyVec;
1274 ///
1275 /// let mut v = TinyVec::from([1, 2, 3, 4]);
1276 /// let b = v.into_vec();
1277 ///
1278 /// assert_eq!(&b[..], &[1, 2, 3, 4]);
1279 /// ```
1280 pub fn into_vec(self) -> Vec<T> {
1281 let mut vec = ManuallyDrop::new(self);
1282
1283 if vec.lives_on_stack() {
1284 unsafe { vec.switch_to_heap(0, false) };
1285 }
1286
1287 let ptr = vec.as_mut_ptr();
1288 let len = vec.len();
1289 let cap = vec.capacity();
1290
1291 unsafe { Vec::from_raw_parts(ptr, len, cap) }
1292 }
1293}
1294
1295impl<T, const N: usize> Extend<T> for TinyVec<T, N> {
1296 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1297 let iter = iter.into_iter();
1298
1299 let (min, max) = iter.size_hint();
1300 let reserve = match max {
1301 Some(max) => max,
1302 None => min,
1303 };
1304
1305 if reserve > 0 {
1306 self.reserve(reserve);
1307 }
1308
1309 for elem in iter {
1310 unsafe { self.push_unchecked(elem); }
1311 }
1312 }
1313}
1314
1315#[cfg(feature = "use-specialization")]
1316macro_rules! maybe_default {
1317 ($($t:tt)*) => {
1318 default $($t)*
1319 };
1320}
1321
1322#[cfg(not(feature = "use-specialization"))]
1323macro_rules! maybe_default {
1324 ($($t:tt)*) => {
1325 $($t)*
1326 };
1327}
1328
1329impl<T, const N: usize> Default for TinyVec<T, N> {
1330 fn default() -> Self {
1331 Self::new()
1332 }
1333}
1334
1335impl<T: fmt::Debug, const N: usize> fmt::Debug for TinyVec<T, N> {
1336 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1337 fmt::Debug::fmt(&self[..], f)
1338 }
1339}
1340
1341impl<T: PartialEq, const N: usize, S> PartialEq<S> for TinyVec<T, N>
1342where
1343 S: AsRef<[T]>,
1344{
1345 fn eq(&self, other: &S) -> bool {
1346 self.as_slice() == other.as_ref()
1347 }
1348}
1349
1350impl<T: PartialEq, const N: usize> Eq for TinyVec<T, N> {}
1351
1352impl<T, const N: usize> Deref for TinyVec<T, N> {
1353 type Target = [T];
1354
1355 fn deref(&self) -> &Self::Target {
1356 self.as_slice()
1357 }
1358}
1359
1360impl<T, const N: usize> DerefMut for TinyVec<T, N> {
1361 fn deref_mut(&mut self) -> &mut Self::Target {
1362 self.as_mut_slice()
1363 }
1364}
1365
1366impl<T, const N: usize> Drop for TinyVec<T, N> {
1367 fn drop(&mut self) {
1368 if mem::needs_drop::<T>() {
1369 for e in self.deref_mut() {
1370 unsafe { ptr::drop_in_place(e) };
1371 }
1372 }
1373 if !self.len.is_stack() {
1374 unsafe { self.inner.raw.destroy(); }
1375 }
1376 }
1377}
1378
1379macro_rules! impl_from_call {
1380 ($( $({$($im:tt)*})? $t:ty => $c:ident ),* $(,)?) => {
1381 $(
1382 impl<T, const N: usize, $($($im)*)?> From<$t> for TinyVec<T, N> {
1383 fn from(value: $t) -> Self {
1384 Self:: $c (value)
1385 }
1386 }
1387 )*
1388 };
1389}
1390
1391impl_from_call! {
1392 Vec<T> => from_vec,
1393 Box<[T]> => from_boxed_slice,
1394 [T; N] => from_array_eq_size,
1395}
1396
1397macro_rules! impl_from_call_w_copy_spec {
1398 ( $( $({$($im:tt)*})? $t:ty => $def_call:ident, $copy_call:ident ;)* ) => {
1399 $(
1400 impl<T: Clone, const N: usize, $( $($im)* )? > From<$t> for TinyVec<T, N> {
1401 maybe_default!(
1402 fn from(value: $t) -> Self {
1403 Self:: $def_call (value)
1404 }
1405 );
1406 }
1407
1408 #[cfg(feature = "use-specialization")]
1409 impl<T: Clone + Copy, const N: usize, $( $($im)* )? > From<$t> for TinyVec<T, N> {
1410 fn from(value: $t) -> Self {
1411 Self:: $copy_call (value)
1412 }
1413 }
1414 )*
1415 };
1416}
1417
1418impl_from_call_w_copy_spec! {
1419 &[T] => from_slice, from_slice_copied;
1420 &mut [T] => from_slice, from_slice_copied;
1421
1422 { const M: usize } &[T; M] => from_slice, from_slice_copied;
1423 { const M: usize } &mut [T; M] => from_slice, from_slice_copied;
1424}
1425
1426impl<T, const N: usize> FromIterator<T> for TinyVec<T, N> {
1427 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1428 let iter = iter.into_iter();
1429 let cap = match iter.size_hint() {
1430 (_, Some(max)) => max,
1431 (n, None) => n,
1432 };
1433 let mut vec = Self::with_capacity(cap);
1434 for elem in iter {
1435 unsafe { vec.push_unchecked(elem) };
1436 }
1437 vec
1438 }
1439}
1440
1441impl<T, const N: usize> From<TinyVec<T, N>> for Vec<T> {
1442 fn from(value: TinyVec<T, N>) -> Self {
1443 value.into_vec()
1444 }
1445}
1446
1447impl<T, const N: usize> AsRef<[T]> for TinyVec<T, N> {
1448 fn as_ref(&self) -> &[T] {
1449 self.as_slice()
1450 }
1451}
1452
1453impl<T, const N: usize> AsMut<[T]> for TinyVec<T, N> {
1454 fn as_mut(&mut self) -> &mut [T] {
1455 self.as_mut_slice()
1456 }
1457}
1458
1459impl<T: Clone, const N: usize> Clone for TinyVec<T, N> {
1460 maybe_default!(
1461 fn clone(&self) -> Self {
1462 Self::from_slice(self.as_slice())
1463 }
1464 );
1465}
1466
1467#[cfg(feature = "use-specialization")]
1468impl<T: Clone + Copy, const N: usize> Clone for TinyVec<T, N> {
1469 fn clone(&self) -> Self {
1470 Self::from_slice_copied(self.as_slice())
1471 }
1472}
1473
1474#[cfg(test)]
1475mod test;