[−][src]Crate generic_vec
A vector that can store items anywhere: in slices, arrays, or the heap!
GenericVec
has complete parity with Vec
, and even provides some features
that are only in nightly
on std
(like GenericVec::drain_filter
), or a more permissive
interface like GenericVec::retain
. In fact, you can trivially convert a Vec
to a
HeapVec
and back!
This crate is no_std
compatible, just turn off all default features.
Features
std
(default) - enables you to use an allocator, andalloc
- enables you to use an allocator, for heap allocated storages (likeVec
)nightly
- enables you to use array ([T; N]
) based storages
Basic Usage
SliceVec
and InitSliceVec
SliceVec
and InitSliceVec
are pretty similar, you give them a slice
buffer, and they store all of thier values in that buffer. But have three major
differences between them.
- You can pass an uninitialized buffer to
SliceVec
- You can only use
Copy
types withInitSliceVec
- You can freely set the length of the
InitSliceVec
as long as you stay within it's capacity (the length of the slice you pass in)
use generic_vec::{SliceVec, InitSliceVec, uninit_array}; let mut uninit_buffer = uninit_array!(16); let mut slice_vec = SliceVec::new(&mut uninit_buffer); assert!(slice_vec.is_empty()); slice_vec.push(10); assert_eq!(slice_vec, [10]);
let mut init_buffer = [0xae; 16]; let mut slice_vec = InitSliceVec::new(&mut init_buffer); assert!(slice_vec.is_full()); assert_eq!(slice_vec.pop(), 0xae); slice_vec.set_len(16); assert!(slice_vec.is_full());
Of course if you try to push past a *SliceVec
's capacity
(the length of the slice you passed in), then it will panic.
let mut init_buffer = [0xae; 16]; let mut slice_vec = InitSliceVec::new(&mut init_buffer); slice_vec.push(0);
TypeVec
TypeVec
is an owned buffer. You can use like so:
use generic_vec::{TypeVec, gvec}; let mut vec: TypeVec<u32, [u32; 4]> = gvec![1, 2, 3, 4]; assert_eq!(vec, [1, 2, 3, 4]); vec.try_push(5).expect_err("Tried to push past capacity!");
The second parameter specifies the buffer type, this can be any type
you want. Only the size of the type matters. There is also a defaulted
third parameter, but you should only use that if you know what you are
doing, and after reading the docs for UninitBuffer
.
As a neat side-effect of this framework, you can also get an efficient
GenericVec
for zero-sized types, just a usize
in size! This feature
can be on stable no_std
.
ArrayVec
and InitArrayVec
ArrayVec
and InitArrayVec
are just like the slice versions, but since they own their data,
they can be freely moved around, unconstrained. You can also create
a new ArrayVec
without passing in an existing buffer,
unlike the slice versions.
On stable, you can use the ArrayVec
or
InitArrayVec
to construct the type. On nightly
,
you can use the type aliases ArrayVec
and
InitArrayVec
. The macros will be deprecated once
min_const_generics
hits stable.
The only limitation on stable is that you can only use InitArrayVec
capacity up to 32. i.e. InitArrayVec![i32; 33]
doesn't work. ArrayVec
does not suffer
from this limitation because it is built atop TypeVec
.
use generic_vec::ArrayVec; let mut array_vec = ArrayVec::<i32, 16>::new(); array_vec.push(10); array_vec.push(20); array_vec.push(30); assert_eq!(array_vec, [10, 20, 30]);
The distinction between ArrayVec
and InitArrayVec
is identical to their slice counterparts.
ZSVec
use generic_vec::ZSVec; struct MyType; let mut vec = ZSVec::new(); vec.push(MyType); vec.push(MyType); vec.push(MyType); assert_eq!(vec.len(), 3); assert_eq!(std::mem::size_of_val(&vec), std::mem::size_of::<usize>());
alloc
A HeapVec
is just Vec
, but built atop GenericVec
,
meaning you get all the features of GenericVec
for free! But this
requries either the alloc
or std
feature to be enabled.
use generic_vec::{HeapVec, gvec}; let mut vec: HeapVec<u32> = gvec![1, 2, 3, 4]; assert_eq!(vec.capacity(), 4); vec.extend(&[5, 6, 7, 8]); assert_eq!(vec, [1, 2, 3, 4, 5, 6, 7, 8]); vec.try_push(5).expect_err("Tried to push past capacity!");
nightly
On nightly
- the restriction on
InitArrayVec
's length goes away. - many functions/methods become
const fn
s - a number of optimizations are enabled
- some diagnostics become better
Note on the documentation: if the feature exists on Vec
, then the documentation
is either exactly the same as Vec
or slightly adapted to better fit GenericVec
Note on implementation: large parts of the implementation came straight from Vec
so thanks for the amazing reference std
!
Modules
iter | The |
raw | The raw vector typse that back-up the |
Macros
ArrayVec | An array backed vector backed by potentially uninitialized memory |
InitArrayVec | An array backed vector backed by initialized memory |
gvec | Create a new generic vector |
save_spare | Save the changes to |
uninit_array | a helper macro to safely create an array of uninitialized memory of any size |
Structs
GenericVec | A vector type that can be backed up by a variety of different backends including slices, arrays, and the heap. |
Type Definitions
ArrayVec | nightly An array backed vector backed by potentially uninitialized memory |
HeapVec | alloc and nightly A heap backed vector with a growable capacity |
InitArrayVec | nightly An array backed vector backed by initialized memory |
InitSliceVec | An slice backed vector backed by initialized memory |
SliceVec | An slice backed vector backed by potentially uninitialized memory |
TypeVec | An type based vector backed by uninitialized memory with the same layout as |
ZSVec | A counter vector that can only store zero-sized types |