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