smallnum

crates.io GitHub Actions

Integer optimization: macros return the smallest integer type capable of fitting a static bounds. Both signed (e.g. macro input is maximum) and unsigned (e.g. macro input is maximum or minimum) numbers supported. Saves memory on embedded devices. !#[no_std], #![forbid(unsafe_code)], zero-cost.

Example: Statically-sized Collection Index

When the size of a collection is known at compile-time, the variable used to index it can be size-optimized.

```rust use smallnum::{smallunsigned, SmallUnsigned}; use core::mem::sizeof_val;

const MAXCAPACITY: usize = 500; let myarray: [u8; MAXCAPACITY] = [0; MAXCAPACITY];

let idx: usize = 5; let smallidx: smallunsigned!(MAX_CAPACITY) = 5;

asserteq!(idx, smallidx.usize()); // Equivalent values asserteq!(myarray[idx], myarray[smallidx.usize()]); // Equivalent collection indexing assert!(sizeofval(&idx) > sizeofval(&small_idx)); // Memory savings (6 bytes on 64-bit)

[cfg(targetpointerwidth = "64")]

asserteq!(sizeof_val(&idx), 8);

[cfg(targetpointerwidth = "64")]

asserteq!(sizeofval(&smallidx), 2); ```

Example: Tree Node Metadata

When the maximum capacity of a tree is known at compile-time, metadata stored in every node can be size-optimized.

```rust use smallnum::smallunsigned; use core::mem::sizeof;

const MAX_CAPACITY: usize = 500;

// Regular node in a binary tree struct BinTree { value: T, leftchild: Option>>, rightchild: Option>>, subtree_size: Option, }

// Node with size-optimized metadata struct SmallBinTree { value: T, leftchild: Option>>, rightchild: Option>>, subtree_size: Option

// Per-node memory savings (16 bytes on 64-bit) assert!(sizeof::>() > sizeof::>());

[cfg(targetpointerwidth = "64")]

asserteq!(sizeof::>(), 40);

[cfg(targetpointerwidth = "64")]

asserteq!(sizeof::>(), 24); ```