fastvec/lib.rs
1//! ## Intro
2//!
3//! A high-performance vector library that stores small collections on the stack
4//! and automatically spills to the heap when needed.
5//!
6//! Similar to [`SmallVec`], but we split the responsibility into two distinct containers instead of one.
7//!
8//! Many workloads have small collections that fit comfortably in a fixed-size stack buffer,
9//! but occasionally need to grow larger. Stack allocation is much faster than heap allocation,
10//! especially for cache locality and allocator overhead.
11//!
12//! FastVec solves this by keeping data on the stack initially and transparently moving to the heap
13//! only when necessary—with zero cost for the common case.
14//!
15//! ## Containers
16//!
17//! ### `StackVec`
18//!
19//! - **Fixed capacity** on the stack
20//! - **Array-like** performance
21//! - **Vec-like** interface
22//! - **Panics** if capacity is exceeded
23//! - Use when: You know the maximum size in advance
24//!
25//! ```
26//! # use fastvec::StackVec;
27//! let mut vec: StackVec<i32, 10> = StackVec::new();
28//! assert_eq!(vec.capacity(), 10);
29//!
30//! vec.push(1);
31//! vec.push(2);
32//! assert_eq!(vec.len(), 2);
33//! // Cannot push more than 10 items (will panic)
34//! ```
35//!
36//! ### `AutoVec`
37//!
38//! - **Flexible capacity**: stack initially, heap when needed
39//! - **Enum-based**: internally either `StackVec` or `Vec`
40//! - **Vec-like** interface
41//! - **Never panics** from capacity limits
42//! - Use when: Size is unknown but usually small.
43//!
44//! ```
45//! # use fastvec::{AutoVec, autovec};
46//! let mut vec: AutoVec<i32, 5> = autovec![1, 2, 3];
47//! assert!(vec.in_stack()); // Still on stack
48//!
49//! // Push beyond capacity—automatically migrates to heap
50//! vec.extend([4, 5, 6, 7, 8]);
51//! assert!(!vec.in_stack()); // Now on heap
52//! ```
53//!
54//! Note: For large collections, [`AutoVec`] adds a small overhead vs [`Vec`]
55//! due to a branch to select stack or heap storage. Benchmark your use case.
56//!
57//! ## Comparison
58//!
59//! | Feature | StackVec | AutoVec | SmallVec | Vec |
60//! |---------|----------|---------|----------|-----|
61//! | Stack storage | ✓ | ✓ | ✓ | ✗ |
62//! | Flexible capacity | ✗ | ✓ | ✓ | ✓ |
63//!
64//!
65//! See detailed documentation in [`StackVec`] and [`AutoVec`] for method signatures and examples.
66//!
67//! ### Aliases
68//!
69//! - [`MiniVec<T>`] = `AutoVec<T, 8>` — for tiny collections
70//! - [`FastVec<T>`] = `AutoVec<T, 16>` — general-purpose balance
71//!
72//! ## `no_std` support
73//!
74//! This crate requires only `core` and `alloc`, making it suitable for embedded and no_std environments.
75//!
76//! ## Optional features
77//!
78//! ### `serde`
79//!
80//! When this optional dependency is enabled,
81//! [`StackVec`] and [`AutoVec`] implement the [`serde::Serialize`] and [`serde::Deserialize`] traits.
82//!
83//!
84//! [`serde::Serialize`]: https://docs.rs/serde/latest/serde/trait.Serialize.html
85//! [`serde::Deserialize`]: https://docs.rs/serde/latest/serde/trait.Deserialize.html
86//! [`SmallVec`]: https://docs.rs/smallvec/latest/smallvec
87//! [`Vec`]: alloc::vec::Vec
88#![cfg_attr(docsrs, feature(doc_cfg))]
89#![no_std]
90
91extern crate alloc;
92
93mod utils;
94
95pub mod stack_vec;
96
97#[cfg(feature = "serde")]
98mod serde;
99
100#[doc(inline)]
101pub use stack_vec::StackVec;
102
103pub mod auto_vec;
104#[doc(inline)]
105pub use auto_vec::AutoVec;
106
107/// A small `AutoVec` with a stack capacity of 8 elements.
108///
109/// This is an alias for [`AutoVec<T, 8>`].
110///
111/// `MiniVec` is optimized for scenarios where you expect small collections most of the time,
112/// typically 8 or fewer elements. It provides zero-cost stack allocation for small data
113/// and automatically spills to the heap when capacity is exceeded.
114///
115/// # Examples
116///
117/// ```
118/// # use fastvec::MiniVec;
119/// let mut vec: MiniVec<i32> = MiniVec::new();
120///
121/// // Small collections stay on the stack with no heap allocation
122/// vec.push(1);
123/// vec.push(2);
124/// vec.push(3);
125/// assert!(vec.in_stack());
126/// assert_eq!(vec, [1, 2, 3]);
127///
128/// // Exceeding capacity automatically moves to heap
129/// vec.extend(&[4, 5, 6, 7, 8, 9]);
130/// assert!(!vec.in_stack());
131/// assert_eq!(vec.len(), 9);
132/// ```
133pub type MiniVec<T> = AutoVec<T, 8>;
134
135/// A fast `AutoVec` with a stack capacity of 16 elements.
136///
137/// This is an alias for [`AutoVec<T, 16>`].
138///
139/// `FastVec` is a balanced choice between stack efficiency and flexibility,
140/// suitable for most general-purpose use cases. It can hold 16 elements on the stack
141/// before spilling to the heap, making it ideal for collections that frequently stay small
142/// but occasionally grow larger.
143///
144/// # Examples
145///
146/// ```
147/// # use fastvec::FastVec;
148/// let mut vec: FastVec<String> = FastVec::new();
149///
150/// // Moderate collections typically remain on the stack
151/// vec.push("hello".to_string());
152/// vec.push("world".to_string());
153/// assert!(vec.in_stack());
154///
155/// // Can be extended up to 16 elements without heap allocation
156/// for i in 0..14 {
157/// vec.push(format!("item_{}", i));
158/// }
159/// assert!(vec.in_stack());
160/// assert_eq!(vec.len(), 16);
161///
162/// // Beyond 16 elements, automatically uses heap
163/// vec.push("beyond".to_string());
164/// assert!(!vec.in_stack());
165/// ```
166pub type FastVec<T> = AutoVec<T, 16>;