dynvec 0.1.4

This crate provides the `DynVec` type that acts like a vector to store any datatype.
Documentation
//! This crate `dynvec` provides the `DynVec` type that acts like a vector to store any datatype.
//!
//! 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`.
//!
//! At the moment, three types of regions are implemented.
//!  * `Block`: A fixed-size block of memory
//!  * `Chunks`: A region that allocates `Block`s (chunks) when one becomes full.
//!  * `Global`: A simple region that maps to rust's allocator (each item is allocated anywhere on the heap memory).
//!
//! # Example
//! Using the default `DynVec`:
//! ```rust
//! use dynvec::DynVec;
//!
//! // Create an empty `DynVec`
//! let mut my_vec = DynVec::new();
//!
//! // By default, each chunk will be allocated with a size of 1024 bytes.
//! // This can be changed using the `DynVec::with_chunk_size` function.
//!
//! // Items can be inserted into the vector
//! let handle_u8 = my_vec.insert(142u8);
//! let handle_str = my_vec.insert("Hello, world!");
//! let handle_vec = my_vec.insert(vec![1, 2, 3]);
//!
//! // They can be accessed normally using indexing operations
//! my_vec[handle_vec].push(4);
//! assert_eq!(my_vec[handle_u8], 142);
//! assert_eq!(my_vec[handle_str], "Hello, world!");
//! assert_eq!(&my_vec[handle_vec][..], &[1, 2, 3, 4][..]);
//!
//! // Removing them is just as easy
//! let vector = my_vec.remove(handle_vec).unwrap();
//! assert_eq!(&vector[..], &[1, 2, 3, 4][..]);
//!
//! // The vector can be cleared (everything gets properly dropped)
//! my_vec.clear();
//! ```
//!
//! Using another type of region:
//! ```rust
//! use dynvec::{RawDynVec, Global};
//!
//! // This is basically a vector of boxes.
//! let mut my_vec = RawDynVec::with_region(Global::default());
//! my_vec.insert(42);
//! my_vec.insert("Hello");
//! ```
//!
//! You might want to avoid having typed handles everywhere.
//! You can use raw handles:
//! ```rust
//! use dynvec::DynVec;
//!     
//! let mut my_vec = DynVec::new();
//! let mut handles = Vec::new();
//!
//! handles.push(my_vec.insert("ABC").raw());
//! handles.push(my_vec.insert(64u8).raw());
//! handles.push(my_vec.insert(String::from("BDE")).raw());
//!
//! for handle in handles {
//!     // This returns nothing
//!     // We do not know the type of the item anymore
//!     // The item gets properly dropped though
//!     my_vec.remove_raw(handle).unwrap();
//! }
//! ```
//!
//! # Note
//! 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.

mod region;
pub use region::Region;

mod raw;
pub use raw::{Handle, RawDynVec, RawHandle};

use raw::Header;

/// A region that allocates in advance a single block of memory.
pub type Block = region::block::Block<Header>;
/// A region that allocates chunks of memory when one gets too small
/// to store the requested data.
pub type Chunks = region::chunks::Chunks<Header>;
/// A region that allocates items using the global allocator.
pub type Global = region::global::Global<Header>;

/// A dynamic vector, able to store any kind of data.
pub type DynVec = RawDynVec<Chunks>;

impl Default for DynVec {
    /// Creates a new empty `DynVec` with a minimal chunk size of 1024 bytes.
    fn default() -> Self {
        Self::with_region(Chunks::new(1024))
    }
}

impl DynVec {
    /// Allocates a new `DynVec` with a minimal chunk size of 1024 bytes.
    pub fn new() -> Self {
        Self::default()
    }

    /// Creates a new `DynVec` with the given chunk size. Note that chunks
    /// can be allocated with a larger size if large objects need to be inserted.
    pub fn with_chunk_size(min_chunk_size: usize) -> Self {
        Self::with_region(Chunks::new(min_chunk_size))
    }

    /// Creates a new `DynVec` with the given chunk size and chunk count.
    /// This function allocates `chunk_count` chunks in advance.
    pub fn with_chunks(min_chunk_size: usize, chunk_count: usize) -> Self {
        Self::with_region(Chunks::with_chuncks(min_chunk_size, chunk_count))
    }
}