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
136
137
138
139
140
141
142
143
144
145
//! Data structures with extra flexible storage.
//!
//! # Usage
//!
//! ## Fixed storage
//!
//! Vectors may be allocated in fixed storage, a buffer which might be
//! stored on the stack or statically.
//!
//! ```
//! use flex_alloc::{storage::byte_storage, vec::Vec};
//!
//! let mut buf = byte_storage::<1024>();
//! let mut b = Vec::new_in(&mut buf);
//! b.push(22usize);
//! ```
//!
//! A fixed storage buffer may also be chained to an allocator, meaning that
//! and when the capacity of the buffer is exceeded, then the allocator
//! will be used to obtain additional memory. For critical sections where the
//! size of the input is variable but may often fit on the stack, this can
//! help to eliminate costly allocations and lead to performance improvements.
//!
//! ```
//! # #[cfg(feature = "alloc")] {
//! use flex_alloc::{storage::{array_storage, WithAlloc}, vec::Vec};
//!
//! let mut buf = array_storage::<_, 100>();
//! let mut v = Vec::new_in(buf.with_alloc());
//! v.extend(1..1000);
//! # }
//! ```
//!
//! ### Custom allocators
//!
//! TODO
//!
//! ### `allocator-api2` integration
//!
//! TODO
//!
//! ### `zeroize` integration
//!
//! Integration with `zeroize` is implemented at the allocator level in order
//! to ensure that all buffers are zeroized (including intermediate
//! allocations produced when a `Vec` is resized). This means that `Vec` types
//! will implement `Zeroize` and `ZeroizeOnDrop` when appropriate.
//!
//! ```
//! # #[cfg(feature = "zeroize")] {
//! use flex_alloc::vec::ZeroizingVec;
//!
//! let v = ZeroizingVec::from([1, 2, 3]);
//! # }
//! ```
//!
//! Fixed storage buffers may be wrapped in `Zeroizing`. Allocations produced
//! on overflow when `with_alloc` is used will automatically be zeroized as
//! well.
//!
//! ```
//! # #[cfg(feature = "zeroize")] {
//! use flex_alloc::{storage::{array_storage, WithAlloc}, vec::Vec};
//! use zeroize::Zeroizing;
//!
//! let mut buf = Zeroizing::new(array_storage::<usize, 10>());
//! let v = Vec::new_in(buf.with_alloc());
//! # }
//! ```
//!
//! ### Inline vectors
//!
//! `Vec` can support inline storage of the contained data. This may be
//! appropriate when the maximum number of elements is known and the `Vec`
//! is not being passed around to other functions:
//!
//! ```
//! use flex_alloc::vec::InlineVec;
//!
//! let v = InlineVec::<usize, 5>::from_iter([1, 2, 3, 4, 5]);
//! ```
//!
//! ```
//! use flex_alloc::{vec, storage::Inline};
//!
//! let v = vec![in Inline::<5>; 1, 2, 3, 4, 5];
//! ```
//!
//! ### Thin vectors
//!
//! Like the `thin-vec` crate (but without compatibility with Gecko), `Vec`
//! may be customized to use a pointer-sized representation with the capacity
//! and length stored in the allocation.
//!
//! Note that unlike with a standard `Vec`, an allocation is required to store
//! a collection of ZSTs (zero-sized types).
//!
//! ```
//! # #[cfg(feature = "alloc")] {
//! use flex_alloc::vec::ThinVec;
//!
//! let v = ThinVec::<usize>::from(&[1, 2, 3, 4, 5]);
//! # }
//! ```
//!
//! ### Custom index sizes
//!
//! `Vec` may be parameterized to use an alternative index type when memory
//! consumption is a concern. The supported index types are `u8`, `u16`,
//! `u32`, and `usize` (the default).
//!
//! ```
//! # #[cfg(feature = "alloc")] {
//! use flex_alloc::{storage::Global, vec::{config::Custom, Vec}};
//!
//! type Cfg = Custom<Global, u8>;
//! let v = Vec::<usize, Cfg>::new();
//! # }
//! ```

#![cfg_attr(not(feature = "std"), no_std)]
// #![warn(missing_docs)]

#[doc = include_str!("../README.md")]
#[cfg(doctest)]
struct _ReadmeDoctests;

#[cfg(test)]
#[macro_use]
extern crate std;

#[cfg(feature = "alloc")]
extern crate alloc;

pub mod borrow;

pub(crate) mod error;

pub mod index;

pub mod storage;

pub mod vec;

pub use self::error::{InsertionError, StorageError};