[][src]Crate heaparray

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.


  • 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.


Creating an array:

use heaparray::*;
let len = 10;
let array = HeapArray::new(len, |idx| idx + 3);
assert!(array[1] == 4);

Indexing works as you would expect:

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:

struct MyLabel {
    pub even: usize,
    pub odd: usize,

let array = HeapArray::with_label(
    MyLabel { even: 0, odd: 0 },
    |label, index| {
        if index % 2 == 0 {
            label.even += 1;
        } else {
            label.odd += 1;

Dynamically Sized Types

The Rust documentation on exotically sized types, at the end of the section on dynamically-sized types states that:

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:

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:

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);



Defines the BaseArray struct.


Implementations of safe APIs to the BaseArray struct.


This module contains naively reference counted arrays, both as atomic and regular versions; i.e. if you're not careful, you could make a cycle that never gets deallocated.



Trait for a simple container.


Trait for a container indexed by a value that implements Copy and Eq.


Trait for a labelled array with a default value.


Array with an optional label struct stored next to the data.


Array with optional label struct stored next to the data that can be mutated


An array of arbitrary (sized) values that can be safely initialized.


Array that returns a slice into its contents


Array that returns a mutable slice into its contents

Type Definitions


2-word reference to an array on the heap that takes ownership of its contained data.