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