flex_array/
lib.rs

1//! # Flexible Array
2//!
3//! The `flex_array` crate provides a `#[no_std]` flexible array similar to `std::Vec`, but with
4//! greater control over memory usage. It allows customization of the types used for length,
5//! capacity, and indexing operations, making it more efficient in certain use cases.
6//!
7//! ## Why Use `FlexArr`?
8//!
9//! I wrote `FlexArr` to address some limitations of Rust’s standard `std::Vec`:
10//!
11//! - **Reduced Memory Overhead**: The `std::Vec` on a 64-bit system typically uses 24 bytes.
12//!   By specifying a smaller type for length and capacity (e.g., `u32`), `FlexArr` can reduce
13//!   this to just 16 bytes, helping one optimizing memory usage.
14//!
15//! - **Fallible Allocations**: Instead of panicking on allocation failure, `FlexArr` returns an
16//!   error, allowing for more robust or graceful error handling. While `std::Vec` has some fallible
17//!   methods, most are still unstable.
18//!
19//! - **Custom Allocator Support**: Since Rust’s allocator API is unstable, `FlexArr` introduces
20//!   the `AltAllocator` trait as an alternative to the standard `Allocator` trait. If the the
21//!   allocator API is stabilized, this will basically just become an an alias for `Allocator`.
22//!
23//! ## Feature Flags
24//!
25//! - `std_alloc` – Enables a wrapper called `Global` that implements `AltAllocator` using the standard
26//!   allocator APIs.
27//!
28//! - `alloc_unstable` – Enables support for Rust’s unstable `Allocator` trait for custom
29//!   allocators. When used with `std_alloc`, this re-exports the `Global` type from `std` instead
30//!   of the custom wrapper named `Global`.
31//!
32//! - `alloc_api2`
33//!   Enables support for the `allocator-api2` crate, which also provides an `Allocator` trait
34//!   in stable rust. This way if you already have allocators written against this you can use
35//!   them with the `flex_array` crate.
36//!   **Note:** This feature should not be enabled with `alloc_unstable` feature. If
37//!   you want to use both just able to enable `alloc_unstable` and `nightly` in the
38//!   `allocator-api2` crate. Additionally, if you are using the `nightly` feature of the
39//!  `allocator-api2` crate you will need to enable the `alloc_unstable` feature.
40
41#![no_std]
42#![cfg_attr(feature = "alloc_unstable", feature(allocator_api))]
43
44#[cfg(any(feature = "std_alloc", test))]
45extern crate std;
46
47pub mod alloc;
48mod flex_array;
49pub mod types;
50
51pub use flex_array::FlexArr;
52
53// Kinda annoying I could avoid this with specialization, but I can only have one blanket impl for AltAllocator unless
54// I used specialization. However, I decided against having a specialization flag. Specialization has soundness holes
55// and can crash the compiler. So just treat this as a compiler error for now. =(
56#[cfg(all(feature = "alloc_api2", feature = "alloc_unstable"))]
57compile_error!(
58    "Cannot enable both `alloc_api2` and `alloc_unstable` features, Instead, enable `nightly` for the Allocator Api2 crate and just `alloc_unstable`"
59);