coca/collections/mod.rs
1//! Collection types.
2
3pub mod binary_heap;
4pub mod cache;
5pub mod deque;
6pub mod list_map;
7pub mod list_set;
8pub mod option_group;
9pub mod pool;
10pub mod vec;
11
12use crate::storage::{ArenaStorage, ArrayLayout, InlineStorage, SliceStorage};
13
14use binary_heap::BinaryHeap;
15use cache::{CacheTable, UnitCache, LruCache2};
16use deque::Deque;
17use list_map::{ListMap, ListMapLayout};
18use list_set::ListSet;
19use option_group::OptionGroup;
20use pool::DefaultHandle;
21use pool::direct::{DirectPool, DirectPoolLayout};
22use pool::packed::{PackedPool, PackedPoolLayout};
23use vec::Vec;
24
25/// A binary heap using a mutable slice for storage.
26///
27/// # Examples
28/// ```
29/// use core::mem::MaybeUninit;
30/// let mut backing_array = [MaybeUninit::<char>::uninit(); 32];
31/// let (slice1, slice2) = (&mut backing_array[..]).split_at_mut(16);
32/// let mut heap1 = coca::collections::SliceHeap::<_>::from(slice1);
33/// let mut heap2 = coca::collections::SliceHeap::<_>::from(slice2);
34/// assert_eq!(heap1.capacity(), 16);
35/// assert_eq!(heap2.capacity(), 16);
36/// ```
37pub type SliceHeap<'a, T, I = usize> = BinaryHeap<T, SliceStorage<'a, T>, I>;
38/// A binary heap using an arena-allocated slice for storage.
39///
40/// # Examples
41/// ```
42/// use coca::arena::Arena;
43/// use coca::collections::ArenaHeap;
44/// use core::mem::MaybeUninit;
45///
46/// let mut backing_region = [MaybeUninit::uninit(); 1024];
47/// let mut arena = Arena::from(&mut backing_region[..]);
48///
49/// let heap: ArenaHeap<'_, i64, usize> = arena.try_with_capacity(100).unwrap();
50/// assert!(arena.try_with_capacity::<_, ArenaHeap<'_, i64, usize>>(100).is_none());
51/// ```
52pub type ArenaHeap<'a, T, I = usize> = BinaryHeap<T, ArenaStorage<'a, ArrayLayout<T>>, I>;
53
54/// A binary heap using an inline array for storage.
55///
56/// # Examples
57/// ```
58/// let mut heap = coca::collections::InlineHeap::<char, 3, u8>::new();
59/// heap.push('a');
60/// let vec = heap.into_vec();
61/// assert_eq!(vec[0u8], 'a');
62/// ```
63pub type InlineHeap<T, const C: usize, I = usize> = BinaryHeap<T, InlineStorage<T, C>, I>;
64
65#[cfg(feature = "alloc")]
66#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
67/// A binary heap using a heap-allocated slice for storage.
68///
69/// Note this still has a fixed capacity, and will never reallocate.
70///
71/// # Examples
72/// ```
73/// let mut heap = coca::collections::AllocHeap::<char>::with_capacity(3);
74/// heap.push('a');
75/// heap.push('b');
76/// heap.push('c');
77/// assert!(heap.try_push('d').is_err());
78/// ```
79pub type AllocHeap<T, I = usize> = BinaryHeap<T, crate::storage::AllocStorage<ArrayLayout<T>>, I>;
80
81/// A direct-mapped cache using an arena-allocated slice for storage.
82///
83/// # Examples
84/// ```
85/// # extern crate rustc_hash;
86/// use rustc_hash::FxHasher;
87/// use coca::{arena::Arena, collections::ArenaDirectMappedCache};
88/// use core::{hash::BuildHasherDefault, mem::MaybeUninit};
89///
90/// # fn test() -> Option<()> {
91/// let mut backing_region = [MaybeUninit::uninit(); 1024];
92/// let mut arena = Arena::from(&mut backing_region[..]);
93/// let mut cache: ArenaDirectMappedCache<'_, i32, &'static str, BuildHasherDefault<FxHasher>> = arena.try_with_capacity(8)?;
94/// cache.insert(1, "a");
95/// assert_eq!(cache.get(&1), Some(&"a"));
96/// # Some(())
97/// # }
98/// # assert!(test().is_some());
99/// ```
100pub type ArenaDirectMappedCache<'src, K, V, H> = CacheTable<K, V, ArenaStorage<'src, ArrayLayout<UnitCache<K, V>>>, UnitCache<K, V>, H>;
101/// A 2-way set-associative cache with a least recently used eviction policy,
102/// using an arena-allocated slice for storage.
103///
104/// # Examples
105/// ```
106/// # extern crate rustc_hash;
107/// use rustc_hash::FxHasher;
108/// use coca::{arena::Arena, collections::Arena2WayLruCache};
109/// use core::{hash::BuildHasherDefault, mem::MaybeUninit};
110///
111/// # fn test() -> Option<()> {
112/// let mut backing_region = [MaybeUninit::uninit(); 1024];
113/// let mut arena = Arena::from(&mut backing_region[..]);
114/// let mut cache: Arena2WayLruCache<'_, i32, &'static str, BuildHasherDefault<FxHasher>> = arena.try_with_capacity(8)?;
115/// cache.insert(1, "a");
116/// assert_eq!(cache.get(&1), Some(&"a"));
117/// # Some(())
118/// # }
119/// # assert!(test().is_some());
120/// ```
121pub type Arena2WayLruCache<'src, K, V, H> = CacheTable<K, V, ArenaStorage<'src, ArrayLayout<LruCache2<K, V>>>, LruCache2<K, V>, H>;
122
123/// A direct-mapped cache using an inline array for storage.
124///
125/// # Examples
126/// ```
127/// # extern crate rustc_hash;
128/// use rustc_hash::FxHasher;
129/// # use coca::collections::InlineDirectMappedCache;
130/// # use core::hash::BuildHasherDefault;
131/// # fn main() {
132/// let keys = ["Alice", "Bob", "Charlie", "Eve"];
133/// let mut cache = InlineDirectMappedCache::<&'static str, usize, BuildHasherDefault<FxHasher>, 3>::new();
134///
135/// for k in &keys {
136/// cache.insert(k, k.len());
137/// assert_eq!(cache.get(k), Some(&k.len()));
138/// }
139///
140/// let mut remembered = 0;
141/// for k in &keys {
142/// if let Some(len) = cache.get(k) {
143/// assert_eq!(len, &k.len());
144/// remembered += 1;
145/// }
146/// }
147///
148/// assert!(0 < remembered);
149/// assert!(remembered < keys.len());
150/// # }
151/// ```
152pub type InlineDirectMappedCache<K, V, H, const N: usize> = CacheTable<K, V, InlineStorage<UnitCache<K, V>, N>, UnitCache<K, V>, H>;
153/// A 2-way set-associative cache with a least recently used eviction policy,
154/// using an inline array for storage.
155///
156/// Note that the constant generic parameter `N` is the number of cache lines,
157/// i.e. caches of this type have capacity for `2 * N` key-value pairs.
158///
159/// # Examples
160/// ```
161/// # extern crate rustc_hash;
162/// use rustc_hash::FxHasher;
163/// # use coca::collections::Inline2WayLruCache;
164/// # use core::hash::BuildHasherDefault;
165/// # fn main() {
166/// let keys = ["Alice", "Bob", "Charlie", "David", "Eve", "Faythe", "Grace"];
167/// let mut cache = Inline2WayLruCache::<&'static str, usize, BuildHasherDefault<FxHasher>, 3>::new();
168/// assert_eq!(cache.capacity(), 6);
169///
170/// for k in &keys {
171/// cache.insert(k, k.len());
172/// assert_eq!(cache.get(k), Some(&k.len()));
173/// }
174///
175/// let mut remembered = 0;
176/// for k in &keys {
177/// if let Some(len) = cache.get(k) {
178/// assert_eq!(len, &k.len());
179/// remembered += 1;
180/// }
181/// }
182///
183/// assert!(0 < remembered);
184/// assert!(remembered < keys.len());
185/// # }
186/// ```
187pub type Inline2WayLruCache<K, V, H, const N: usize> = CacheTable<K, V, InlineStorage<LruCache2<K, V>, N>, LruCache2<K, V>, H>;
188
189/// A direct-mapped cache using a heap-allocated array for storage.
190///
191/// # Examples
192/// ```
193/// # extern crate rustc_hash;
194/// use rustc_hash::FxHasher;
195/// # use coca::collections::AllocDirectMappedCache;
196/// # use core::hash::BuildHasherDefault;
197/// let mut cache = AllocDirectMappedCache::<&'static str, usize, BuildHasherDefault<FxHasher>>::with_capacity(3);
198/// assert_eq!(cache.capacity(), 3);
199///
200/// let keys = ["Alice", "Bob", "Charlie", "Eve"];
201/// for k in &keys {
202/// cache.insert(k, k.len());
203/// assert_eq!(cache.get(k), Some(&k.len()));
204/// }
205///
206/// let mut remembered = 0;
207/// for k in &keys {
208/// if let Some(len) = cache.get(k) {
209/// assert_eq!(len, &k.len());
210/// remembered += 1;
211/// }
212/// }
213///
214/// assert!(0 < remembered);
215/// assert!(remembered < keys.len());
216/// ```
217#[cfg(feature = "alloc")]
218#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
219pub type AllocDirectMappedCache<K, V, H> = CacheTable<K, V, crate::storage::AllocStorage<ArrayLayout<UnitCache<K, V>>>, UnitCache<K, V>, H>;
220
221/// A 2-way set-associative cache with a least recently used eviction policy,
222/// using a heap-allocated array for storage.
223///
224/// # Examples
225/// ```
226/// # extern crate rustc_hash;
227/// use rustc_hash::FxHasher;
228/// # use coca::collections::Alloc2WayLruCache;
229/// # use core::hash::BuildHasherDefault;
230/// let mut cache = Alloc2WayLruCache::<&'static str, usize, BuildHasherDefault<FxHasher>>::with_capacity(6);
231/// assert_eq!(cache.capacity(), 6);
232///
233/// let keys = ["Alice", "Bob", "Charlie", "David", "Eve", "Faythe", "Grace"];
234/// for k in &keys {
235/// cache.insert(k, k.len());
236/// assert_eq!(cache.get(k), Some(&k.len()));
237/// }
238///
239/// let mut remembered = 0;
240/// for k in &keys {
241/// if let Some(len) = cache.get(k) {
242/// assert_eq!(len, &k.len());
243/// remembered += 1;
244/// }
245/// }
246///
247/// assert!(0 < remembered);
248/// assert!(remembered < keys.len());
249/// ```
250#[cfg(feature = "alloc")]
251#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
252pub type Alloc2WayLruCache<K, V, H> = CacheTable<K, V, crate::storage::AllocStorage<ArrayLayout<LruCache2<K, V>>>, LruCache2<K, V>, H>;
253
254/// A double-ended queue using any mutable slice for storage.
255///
256/// # Examples
257/// ```
258/// use core::mem::MaybeUninit;
259/// let mut backing_array = [MaybeUninit::<char>::uninit(); 32];
260/// let (slice1, slice2) = (&mut backing_array[..]).split_at_mut(16);
261/// let mut deque1 = coca::collections::SliceDeque::<_>::from(slice1);
262/// let mut deque2 = coca::collections::SliceDeque::<_>::from(slice2);
263/// assert_eq!(deque1.capacity(), 16);
264/// assert_eq!(deque2.capacity(), 16);
265/// ```
266pub type SliceDeque<'a, T, I = usize> = Deque<T, SliceStorage<'a, T>, I>;
267/// A double-ended queue using an arena-allocated slice for storage.
268///
269/// # Examples
270/// ```
271/// use core::mem::MaybeUninit;
272/// use coca::arena::Arena;
273/// use coca::collections::ArenaDeque;
274///
275/// # fn test() -> Option<()> {
276/// let mut backing_region = [MaybeUninit::uninit(); 1024];
277/// let mut arena = Arena::from(&mut backing_region[..]);
278/// let mut deque: ArenaDeque<'_, char, usize> = arena.try_with_capacity(4)?;
279///
280/// deque.push_front('b');
281/// deque.push_front('a');
282/// deque.push_back('c');
283/// deque.push_back('d');
284///
285/// assert_eq!(deque, &['a', 'b', 'c', 'd']);
286/// assert_eq!(deque.try_push_back('e'), Err('e'));
287/// # Some(())
288/// # }
289/// # assert!(test().is_some());
290/// ```
291pub type ArenaDeque<'a, T, I = usize> = Deque<T, ArenaStorage<'a, ArrayLayout<T>>, I>;
292
293#[cfg(feature = "alloc")]
294#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
295/// A deque using a heap-allocated slice for storage.
296///
297/// Note that this still has a fixed capacity, and will never reallocate.
298///
299/// # Examples
300/// ```
301/// let mut deque = coca::collections::AllocDeque::<char>::with_capacity(4);
302///
303/// deque.push_front('b');
304/// deque.push_front('a');
305/// deque.push_back('c');
306/// deque.push_back('d');
307///
308/// assert_eq!(deque, &['a', 'b', 'c', 'd']);
309/// assert_eq!(deque.try_push_back('e'), Err('e'));
310/// ```
311pub type AllocDeque<T, I = usize> = Deque<T, crate::storage::AllocStorage<ArrayLayout<T>>, I>;
312
313/// A deque using an inline array for storage.
314///
315/// # Examples
316/// ```
317/// let mut deque = coca::collections::InlineDeque::<char, 4, u8>::new();
318/// deque.push_front('a');
319/// assert_eq!(deque[0u8], 'a');
320/// ```
321pub type InlineDeque<T, const C: usize, I = usize> = Deque<T, InlineStorage<T, C>, I>;
322
323/// An association list that stores its contents in an arena-allocated memory block.
324///
325/// # Examples
326/// ```
327/// use coca::arena::Arena;
328/// use coca::collections::ArenaListMap;
329/// use core::mem::MaybeUninit;
330///
331/// let mut backing_region = [MaybeUninit::uninit(); 2048];
332/// let mut arena = Arena::from(&mut backing_region[..]);
333///
334/// let map: ArenaListMap<'_, &'static str, u32> = arena.try_with_capacity(100).unwrap();
335/// assert!(arena.try_with_capacity::<_, ArenaListMap<'_, &'static str, u32>>(100).is_none());
336/// ```
337pub type ArenaListMap<'a, K, V, I = usize> = ListMap<K, V, ArenaStorage<'a, ListMapLayout<K, V>>, I>;
338/// An association list that stores its contents in globally allocated memory.
339///
340/// # Examples
341/// ```
342/// use coca::collections::AllocListMap;
343/// let mut map = AllocListMap::<&'static str, u32>::with_capacity(13);
344/// assert_eq!(map.capacity(), 13);
345/// ```
346#[cfg(feature = "alloc")]
347#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
348pub type AllocListMap<K, V, I = usize> = ListMap<K, V, crate::storage::AllocStorage<ListMapLayout<K, V>>, I>;
349/// An association list that stores its contents inline.
350///
351/// # Examples
352/// ```
353/// use coca::collections::InlineListMap;
354/// let mut map = InlineListMap::<&'static str, u32, 3, u8>::new();
355/// # assert!(map.is_empty());
356/// ```
357pub type InlineListMap<K, V, const N: usize, I = usize> = ListMap<K, V, list_map::InlineStorage<K, V, N>, I>;
358
359/// A set based on an arena-allocated array.
360///
361/// # Examples
362/// ```
363/// use coca::arena::Arena;
364/// use coca::collections::ArenaListSet;
365/// use core::mem::MaybeUninit;
366///
367/// let mut backing_region = [MaybeUninit::uninit(); 2048];
368/// let mut arena = Arena::from(&mut backing_region[..]);
369///
370/// let map: ArenaListSet<'_, &'static str> = arena.try_with_capacity(100).unwrap();
371/// assert!(arena.try_with_capacity::<_, ArenaListSet<'_, &'static str>>(100).is_none());
372/// ```
373pub type ArenaListSet<'a, T, I = usize> = ListSet<T, ArenaStorage<'a, ArrayLayout<T>>, I>;
374/// A set based on a globally allocated array.
375///
376/// # Examples
377/// ```
378/// use coca::collections::AllocListSet;
379/// let mut map = AllocListSet::<&'static str>::with_capacity(13);
380/// assert_eq!(map.capacity(), 13);
381/// ```
382#[cfg(feature = "alloc")]
383#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
384pub type AllocListSet<T, I = usize> = ListSet<T, crate::storage::AllocStorage<ArrayLayout<T>>, I>;
385/// A set based on any mutable array slice.
386///
387/// # Examples
388/// ```
389/// use core::mem::MaybeUninit;
390/// let mut backing_array = [MaybeUninit::<char>::uninit(); 32];
391/// let (slice1, slice2) = (&mut backing_array[..]).split_at_mut(16);
392/// let mut set1 = coca::collections::SliceListSet::<_>::from(slice1);
393/// let mut set2 = coca::collections::SliceListSet::<_>::from(slice2);
394/// assert_eq!(set1.capacity(), 16);
395/// assert_eq!(set2.capacity(), 16);
396/// ```
397pub type SliceListSet<'a, T, I = usize> = ListSet<T, SliceStorage<'a, T>, I>;
398/// A set based on an inline array.
399///
400/// # Examples
401/// ```
402/// use coca::collections::InlineListSet;
403/// let mut set = InlineListSet::<&'static str, 20, u8>::new();
404/// ```
405pub type InlineListSet<T, const N: usize, I = usize> = ListSet<T, InlineStorage<T, N>, I>;
406
407/// A group of up to eight [`Option`]s with the discriminants packed into a single `u8`.
408pub type OptionGroup8<T> = OptionGroup<u8, T>;
409/// A group of up to sixteen [`Option`]s with the discriminants packed into a single `u16`.
410pub type OptionGroup16<T> = OptionGroup<u16, T>;
411/// A group of up to 32 [`Option`]s with the discriminants packed into a single `u32`.
412pub type OptionGroup32<T> = OptionGroup<u32, T>;
413/// A group of up to 64 [`Option`]s with the discriminants packed into a single `u64`.
414pub type OptionGroup64<T> = OptionGroup<u64, T>;
415
416/// A direct-mapped pool that stores its contents in an arena-allocated memory block.
417///
418/// # Examples
419/// ```
420/// use coca::arena::Arena;
421/// use coca::collections::{DirectArenaPool, pool::DefaultHandle};
422/// use core::mem::MaybeUninit;
423///
424/// let mut backing_region = [MaybeUninit::uninit(); 1024];
425/// let mut arena = Arena::from(&mut backing_region[..]);
426///
427/// let pool: DirectArenaPool<'_, i64, DefaultHandle> = arena.try_with_capacity(50).unwrap();
428/// assert!(arena.try_with_capacity::<_, DirectArenaPool<'_, i64, DefaultHandle>>(50).is_none());
429/// ```
430pub type DirectArenaPool<'src, T, H = DefaultHandle> =
431 DirectPool<T, ArenaStorage<'src, DirectPoolLayout<T, H>>, H>;
432
433/// A direct-mapped pool that stores its content in globally allocated memory.
434///
435/// # Examples
436/// ```
437/// # use coca::collections::DirectAllocPool;
438/// let mut pool = DirectAllocPool::<u128>::with_capacity(4);
439/// assert_eq!(pool.capacity(), 4);
440///
441/// pool.insert(1);
442/// pool.insert(2);
443/// pool.insert(3);
444/// pool.insert(4);
445/// assert_eq!(pool.try_insert(5), Err(5));
446/// ```
447#[cfg(feature = "alloc")]
448#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
449pub type DirectAllocPool<T, H = DefaultHandle> =
450 DirectPool<T, crate::storage::AllocStorage<DirectPoolLayout<T, H>>, H>;
451
452
453/// A direct-mapped pool that stores its contents in an inline array,
454/// indexed by the specified custom [`Handle`](pool::Handle).
455///
456/// # Examples
457/// ```
458/// # use coca::handle_type;
459/// # use coca::collections::DirectInlinePool;
460/// handle_type! { CustomHandle: 8 / 32; }
461///
462/// const A: u128 = 0x0123_4567_89AB_CDEF_0123_4567_89AB_CDEF;
463/// const B: u128 = 0xFEDC_BA98_7654_3210_FEDC_BA98_7654_3210;
464///
465/// let mut pool = DirectInlinePool::<u128, 8, CustomHandle>::new();
466/// let a: CustomHandle = pool.insert(A);
467/// let b = pool.insert(B);
468/// assert_eq!(pool.len(), 2);
469/// assert_eq!(pool.remove(a), Some(A));
470/// assert_eq!(pool.remove(b), Some(B));
471/// assert!(pool.is_empty());
472/// ```
473pub type DirectInlinePool<T, const N: usize, H = DefaultHandle> = DirectPool<T, pool::direct::InlineStorage<T, H, N>, H>;
474
475/// A densely packed pool that stores its contents in a arena-allocated memory block.
476///
477/// # Examples
478/// ```
479/// use coca::arena::Arena;
480/// use coca::collections::{PackedArenaPool, pool::DefaultHandle};
481/// use core::mem::MaybeUninit;
482///
483/// let mut backing_region = [MaybeUninit::uninit(); 1024];
484/// let mut arena = Arena::from(&mut backing_region[..]);
485///
486/// let pool: PackedArenaPool<'_, i64, DefaultHandle> = arena.try_with_capacity(30).unwrap();
487/// assert!(arena.try_with_capacity::<_, PackedArenaPool<'_, i64, DefaultHandle>>(30).is_none());
488/// ```
489pub type PackedArenaPool<'src, T, H> = PackedPool<T, ArenaStorage<'src, PackedPoolLayout<T, H>>, H>;
490
491/// A densely packed pool that stores its contents in globally allocated memory.
492///
493/// # Examples
494/// ```
495/// # use coca::collections::pool::DefaultHandle;
496/// # use coca::collections::PackedAllocPool;
497/// const A: u128 = 0x0123_4567_89AB_CDEF_0123_4567_89AB_CDEF;
498/// const B: u128 = 0xFEDC_BA98_7654_3210_FEDC_BA98_7654_3210;
499///
500/// let mut pool = PackedAllocPool::<u128>::with_capacity(8);
501/// let a = pool.insert(A);
502/// let b = pool.insert(B);
503/// assert_eq!(pool.len(), 2);
504/// assert_eq!(pool.remove(a), Some(A));
505/// assert_eq!(pool.remove(b), Some(B));
506/// assert!(pool.is_empty());
507/// ```
508#[cfg(feature = "alloc")]
509#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
510pub type PackedAllocPool<T, H = DefaultHandle> = PackedPool<T, crate::storage::AllocStorage<PackedPoolLayout<T, H>>, H>;
511
512/// A densely packed pool that stores its contents inline, indexed by the specified custom [`Handle`](pool::Handle).
513///
514/// # Examples
515/// ```
516/// # use coca::handle_type;
517/// # use coca::collections::PackedInlinePool;
518/// handle_type! { CustomHandle: 8 / 32; }
519///
520/// const A: u128 = 0x0123_4567_89AB_CDEF_0123_4567_89AB_CDEF;
521/// const B: u128 = 0xFEDC_BA98_7654_3210_FEDC_BA98_7654_3210;
522///
523/// let mut pool = PackedInlinePool::<u128, 8, CustomHandle>::new();
524/// let a: CustomHandle = pool.insert(A);
525/// let b = pool.insert(B);
526/// assert_eq!(pool.len(), 2);
527/// assert_eq!(pool.remove(a), Some(A));
528/// assert_eq!(pool.remove(b), Some(B));
529/// assert!(pool.is_empty());
530/// ```
531pub type PackedInlinePool<T, const N: usize, H = DefaultHandle> = PackedPool<T, pool::packed::InlineStorage<T, H, N>, H>;
532
533/// A vector using any mutable slice for storage.
534///
535/// # Examples
536/// ```
537/// use core::mem::MaybeUninit;
538/// let mut backing_array = [MaybeUninit::<char>::uninit(); 32];
539/// let (slice1, slice2) = (&mut backing_array[..]).split_at_mut(16);
540/// let mut vec1 = coca::collections::SliceVec::<_>::from(slice1);
541/// let mut vec2 = coca::collections::SliceVec::<_>::from(slice2);
542/// assert_eq!(vec1.capacity(), 16);
543/// assert_eq!(vec2.capacity(), 16);
544/// ```
545pub type SliceVec<'a, T, I = usize> = Vec<T, SliceStorage<'a, T>, I>;
546/// A vector using an arena-allocated slice for storage.
547///
548/// # Examples
549/// ```
550/// use coca::arena::Arena;
551/// use coca::collections::ArenaVec;
552/// use core::mem::MaybeUninit;
553///
554/// let mut backing_region = [MaybeUninit::uninit(); 1024];
555/// let mut arena = Arena::from(&mut backing_region[..]);
556///
557/// let v: ArenaVec<'_, i64, usize> = arena.try_with_capacity(100).unwrap();
558/// assert!(arena.try_with_capacity::<_, ArenaVec<'_, i64, usize>>(100).is_none());
559/// ```
560pub type ArenaVec<'a, T, I = usize> = Vec<T, ArenaStorage<'a, ArrayLayout<T>>, I>;
561
562#[cfg(feature = "alloc")]
563#[cfg_attr(docs_rs, doc(cfg(feature = "alloc")))]
564/// A vector using a heap-allocated slice for storage.
565///
566/// Note this still has a fixed capacity, and will never reallocate.
567///
568/// # Examples
569/// ```
570/// let mut vec = coca::collections::AllocVec::<char>::with_capacity(3);
571/// vec.push('a');
572/// vec.push('b');
573/// vec.push('c');
574/// assert!(vec.try_push('d').is_err());
575/// ```
576pub type AllocVec<T, I = usize> = Vec<T, crate::storage::AllocStorage<ArrayLayout<T>>, I>;
577
578/// A vector using an inline array for storage.
579///
580/// # Examples
581/// ```
582/// let mut vec = coca::collections::InlineVec::<char, 3, u8>::new();
583/// vec.push('a');
584/// assert_eq!(vec[0u8], 'a');
585/// ```
586pub type InlineVec<T, const C: usize, Index = usize> = Vec<T, InlineStorage<T, C>, Index>;