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