heaparray/
lib.rs

1/*!
2This crate aims to give people better control of how they allocate memory,
3by providing a customizable way to allocate blocks of memory, that optionally
4contains metadata about the block itself. This makes it much easier to implement
5Dynamically-Sized Types (DSTs), and also reduces the number of pointer
6indirections necessary to share data between threads.
7
8## Features
9- Safe API to dynamically-sized types
10- Generic implementations of common tasks so you can customize the
11  implementation of a type without having to write additional boilerplate
12- Atomically reference-counted memory blocks of arbitrary size without
13  using a `Vec`; this means you can access reference-counted memory with
14  only a single pointer indirection.
15
16## Examples
17Creating an array:
18
19```rust
20use heaparray::*;
21let len = 10;
22let array = HeapArray::new(len, |idx| idx + 3);
23assert!(array[1] == 4);
24```
25
26Indexing works as you would expect:
27
28```rust
29use heaparray::*;
30let mut array = HeapArray::new(10, |_| 0);
31array[3] = 2;
32assert!(array[3] == 2);
33```
34
35Additionally, you can customize what information should be stored alongside
36the elements in the array using the `HeapArray::with_label` function:
37
38```rust
39# use heaparray::*;
40struct MyLabel {
41    pub even: usize,
42    pub odd: usize,
43}
44
45let array = HeapArray::with_label(
46    MyLabel { even: 0, odd: 0 },
47    100,
48    |label, index| {
49        if index % 2 == 0 {
50            label.even += 1;
51            index
52        } else {
53            label.odd += 1;
54            index
55        }
56    });
57```
58
59## Dynamically Sized Types
60The [Rust documentation on exotically sized types][rust-docs-dsts],
61at the end of the section on dynamically-sized types states that:
62
63[rust-docs-dsts]: https://doc.rust-lang.org/nomicon/exotic-sizes.html
64
65> Currently the only properly supported way to create a custom DST is by
66> making your type generic and performing an unsizing coercion...
67> (Yes, custom DSTs are a largely half-baked feature for now.)
68
69This crate aims to provide *some* of that functionality; the code that
70the docs give is the following:
71
72```rust
73struct MySuperSliceable<T: ?Sized> {
74    info: u32,
75    data: T
76}
77
78fn main() {
79    let sized: MySuperSliceable<[u8; 8]> = MySuperSliceable {
80        info: 17,
81        data: [0; 8],
82    };
83
84    let dynamic: &MySuperSliceable<[u8]> = &sized;
85
86    // prints: "17 [0, 0, 0, 0, 0, 0, 0, 0]"
87    println!("{} {:?}", dynamic.info, &dynamic.data);
88}
89```
90
91using this crate, the `MySuperSliceable<[u8]>` type would be
92implemented like this:
93
94```rust
95use heaparray::*;
96
97type MySuperSliceable = HeapArray<u8, u32>;
98
99fn main() {
100    let info = 17;
101    let len = 8;
102    let dynamic = MySuperSliceable::with_label(info, len, |_,_| 0);
103    println!("{:?}", dynamic);
104}
105```
106*/
107
108extern crate atomic_types;
109extern crate const_utils;
110extern crate containers_rs as containers;
111
112mod api;
113pub mod base;
114pub mod impls;
115pub mod naive_rc;
116mod traits;
117
118mod api_prelude {
119    pub use crate::traits::*;
120    pub use containers::{Container, CopyMap};
121}
122
123mod api_prelude_rc {
124    pub use crate::api_prelude::*;
125    pub use crate::traits::rc::*;
126}
127
128mod prelude {
129    pub use crate::api_prelude::*;
130    pub(crate) use core::fmt;
131    pub(crate) use core::mem;
132    pub(crate) use core::ops::{Index, IndexMut};
133}
134
135pub use api::*;