Skip to main content

dynvec/
lib.rs

1//! This crate `dynvec` provides the `DynVec` type that acts like a vector to store any datatype.
2//!
3//! By default, the `DynVec` uses a system of chunks that are allocated on the heap when needed but this can be changed using the `RawDynVec` structure along with a `Region`.
4//!
5//! At the moment, three types of regions are implemented.
6//!  * `Block`: A fixed-size block of memory
7//!  * `Chunks`: A region that allocates `Block`s (chunks) when one becomes full.
8//!  * `Global`: A simple region that maps to rust's allocator (each item is allocated anywhere on the heap memory).
9//!
10//! # Example
11//! Using the default `DynVec`:
12//! ```rust
13//! use dynvec::DynVec;
14//!
15//! // Create an empty `DynVec`
16//! let mut my_vec = DynVec::new();
17//!
18//! // By default, each chunk will be allocated with a size of 1024 bytes.
19//! // This can be changed using the `DynVec::with_chunk_size` function.
20//!
21//! // Items can be inserted into the vector
22//! let handle_u8 = my_vec.insert(142u8);
23//! let handle_str = my_vec.insert("Hello, world!");
24//! let handle_vec = my_vec.insert(vec![1, 2, 3]);
25//!
26//! // They can be accessed normally using indexing operations
27//! my_vec[handle_vec].push(4);
28//! assert_eq!(my_vec[handle_u8], 142);
29//! assert_eq!(my_vec[handle_str], "Hello, world!");
30//! assert_eq!(&my_vec[handle_vec][..], &[1, 2, 3, 4][..]);
31//!
32//! // Removing them is just as easy
33//! let vector = my_vec.remove(handle_vec).unwrap();
34//! assert_eq!(&vector[..], &[1, 2, 3, 4][..]);
35//!
36//! // The vector can be cleared (everything gets properly dropped)
37//! my_vec.clear();
38//! ```
39//!
40//! Using another type of region:
41//! ```rust
42//! use dynvec::{RawDynVec, Global};
43//!
44//! // This is basically a vector of boxes.
45//! let mut my_vec = RawDynVec::with_region(Global::default());
46//! my_vec.insert(42);
47//! my_vec.insert("Hello");
48//! ```
49//!
50//! You might want to avoid having typed handles everywhere.
51//! You can use raw handles:
52//! ```rust
53//! use dynvec::DynVec;
54//!     
55//! let mut my_vec = DynVec::new();
56//! let mut handles = Vec::new();
57//!
58//! handles.push(my_vec.insert("ABC").raw());
59//! handles.push(my_vec.insert(64u8).raw());
60//! handles.push(my_vec.insert(String::from("BDE")).raw());
61//!
62//! for handle in handles {
63//!     // This returns nothing
64//!     // We do not know the type of the item anymore
65//!     // The item gets properly dropped though
66//!     my_vec.remove_raw(handle).unwrap();
67//! }
68//! ```
69//!
70//! # Note
71//! I used `DynVec` as a name even though it is not at all a vector because it makes it easy to understand what it does.
72
73mod region;
74pub use region::Region;
75
76mod raw;
77pub use raw::{Handle, RawDynVec, RawHandle};
78
79use raw::Header;
80
81/// A region that allocates in advance a single block of memory.
82pub type Block = region::block::Block<Header>;
83/// A region that allocates chunks of memory when one gets too small
84/// to store the requested data.
85pub type Chunks = region::chunks::Chunks<Header>;
86/// A region that allocates items using the global allocator.
87pub type Global = region::global::Global<Header>;
88
89/// A dynamic vector, able to store any kind of data.
90pub type DynVec = RawDynVec<Chunks>;
91
92impl Default for DynVec {
93    /// Creates a new empty `DynVec` with a minimal chunk size of 1024 bytes.
94    fn default() -> Self {
95        Self::with_region(Chunks::new(1024))
96    }
97}
98
99impl DynVec {
100    /// Allocates a new `DynVec` with a minimal chunk size of 1024 bytes.
101    pub fn new() -> Self {
102        Self::default()
103    }
104
105    /// Creates a new `DynVec` with the given chunk size. Note that chunks
106    /// can be allocated with a larger size if large objects need to be inserted.
107    pub fn with_chunk_size(min_chunk_size: usize) -> Self {
108        Self::with_region(Chunks::new(min_chunk_size))
109    }
110
111    /// Creates a new `DynVec` with the given chunk size and chunk count.
112    /// This function allocates `chunk_count` chunks in advance.
113    pub fn with_chunks(min_chunk_size: usize, chunk_count: usize) -> Self {
114        Self::with_region(Chunks::with_chuncks(min_chunk_size, chunk_count))
115    }
116}