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::*;