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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
//! A generational map with a configurable key.
//!
//! [`GenMap`] stores values and hands out a [`Key`] for each one. A key stays
//! valid until its value is removed, and by default it never matches a value
//! that later takes the same slot. The only exceptions are a config that
//! wraps generations and [`reset`](GenMap::reset), both described below.
//! That makes keys safe to hold on to where plain indices or references are
//! not, such as in graphs, entity systems and anything else that refers to
//! values by handle.
//!
//! Inserting, removing and looking up a value are all O(1). The crate is
//! `no_std`, and it only needs an allocator for storage that uses the heap,
//! such as `Vec`. The `Vec` storage comes from the `alloc` feature, which is
//! on by default and can be turned off. See [Cargo features](#cargo-features).
//!
//! # Examples
//!
//! ```
//! use gen_map::GenMap;
//!
//! let mut map = GenMap::new();
//! let a = map.insert("a");
//! let b = map.insert("b");
//! assert_eq!(map[a], "a");
//!
//! assert_eq!(map.remove(a), Some("a"));
//! assert!(map.get(a).is_none());
//!
//! // `c` takes the slot `a` had, but `a` still does not match the new value.
//! let c = map.insert("c");
//! assert_eq!(c.idx(), a.idx());
//! assert!(map.get(a).is_none());
//! assert_eq!(map[c], "c");
//!
//! for (key, value) in &map {
//! assert!(key == b || key == c);
//! assert!(*value == "b" || *value == "c");
//! }
//! ```
//!
//! # How it works
//!
//! The map keeps its values in a list of slots. A key is the index of a slot
//! together with the slot's generation at the time the key was handed out,
//! and [`Key::idx`] and [`Key::generation`] read the two back. A slot's
//! generation goes up by one on every insert and every remove, so it is odd
//! while the slot holds a value and even while it does not. A key only
//! matches its slot while the two generations are equal, so removing a value
//! invalidates every copy of its key at once, and the next value in that
//! slot gets a key with a newer generation.
//!
//! Freed slots go on a free list and are reused before the map adds new
//! ones, so the map only grows when no slot is free.
//!
//! # Configuring the map
//!
//! A [`Config`] decides four things.
//!
//! - [`Idx`](Config::Idx) and [`Gen`](Config::Gen) are the integer types of
//! the index and the generation. Any type that implements [`KeyPiece`]
//! works, which is every unsigned integer from `u8` to `u128`, and
//! `usize`.
//! - [`Layout`](Config::Layout) is how a key stores the generation and index. [`Split`] keeps
//! them as two fields and [`Packed`] puts them in the bits of one integer.
//! - [`Storage`](Config::Storage) is the collection the slots live in, such
//! as a `Vec`.
//! - [`WRAP_ON_OVERFLOW`](Config::WRAP_ON_OVERFLOW) says what happens to a
//! slot whose generation runs out.
//!
//! [`DefaultConfig`] is the config a [`GenMap`] uses when none is named. Its
//! keys are a `u32` index and a `u32` generation stored as two fields, its
//! slots live in a `Vec`, and a slot retires when its generation runs out.
//!
//! A config is only used as a type parameter and never created as a value,
//! so an empty struct is enough.
//!
//! ```
//! use gen_map::{Config, GenMap, Split};
//!
//! /// A `u8` index and a `u8` generation, so keys are two bytes and the map
//! /// holds at most 256 slots.
//! struct Tiny;
//!
//! impl Config for Tiny {
//! type Idx = u8;
//! type Gen = u8;
//! type Layout = Split;
//! type Storage<S> = Vec<S>;
//! }
//!
//! let mut map = GenMap::<u64, Tiny>::new_with_config();
//! let key = map.insert(7);
//! assert_eq!(core::mem::size_of_val(&key), 2);
//! assert_eq!(map[key], 7);
//! ```
//!
//! [`GenMap::new`] only exists for the default config. Rust does not use a
//! default type parameter when it infers types, so a `new` that took any
//! config would need the config written out on every call. Any other config
//! goes through [`GenMap::new_with_config`].
//!
//! ## Key layouts
//!
//! [`Split`] stores the index and the generation as two fields, so a key is
//! as large as the two together, plus any padding their alignment needs.
//! The index and the generation can each use every value of their type.
//!
//! [`Packed`] stores them in the bits of one integer instead. `Packed<R,
//! GEN_BITS>` gives the low `GEN_BITS` bits of an `R` to the generation and
//! the bits above them to the index, so a key is as large as `R`, and the two
//! parts can have any bit counts that add up to the bits of `R`. The config's
//! `Idx` and `Gen` only have to be wide enough for their parts, and a config
//! whose bit counts do not add up fails to compile.
//!
//! ```
//! use gen_map::{Config, GenMap, Key, Packed};
//!
//! /// Four byte keys with 24 bits of index and 8 bits of generation.
//! struct Compact;
//!
//! impl Config for Compact {
//! type Idx = u32;
//! type Gen = u8;
//! type Layout = Packed<u32, 8>;
//! type Storage<S> = Vec<S>;
//! }
//!
//! let mut map = GenMap::<&str, Compact>::new_with_config();
//! let key = map.insert("a");
//! assert_eq!(core::mem::size_of::<Key<Compact>>(), 4);
//! assert_eq!(map[key], "a");
//! ```
//!
//! With either layout, `Option<Key>` is the same size as `Key`.
//!
//! ## When a generation runs out
//!
//! A slot's generation can only go up to the largest one its key can hold,
//! which is `Gen::MAX` for [`Split`] and the largest value of the generation
//! part for [`Packed`]. Each value a slot holds uses up two generations, one
//! when it is inserted and one when it is removed, so a `u32` generation lets
//! a slot hold over two billion values, while a 4 bit generation lets it hold
//! eight. What happens to a slot after that is up to
//! [`WRAP_ON_OVERFLOW`](Config::WRAP_ON_OVERFLOW).
//!
//! By default, the slot retires. It stays in the storage but is never used
//! again, so no stale key can ever match a new value.
//!
//! When `WRAP_ON_OVERFLOW` is `true`, the generation wraps back to zero and
//! the slot is reused. No slot is ever lost, but a key that is old enough can
//! match a new value once the generation wraps around to it again.
//!
//! [`retire`](GenMap::retire) removes a value and retires its slot, no
//! matter how the map is configured. Code built on a map that wraps can use
//! it to keep the slots it chooses from wrapping, and
//! [`Key::is_max_generation`] can be used to determine when a slot has reached that point.
//!
//! ## Storage
//!
//! The slots can live in any collection that implements [`SlotStorage`]. A
//! `Vec` does, and so do two collections from other crates when their
//! features are on. `ArrayVec` from `arrayvec` has a fixed capacity and
//! never allocates, and `SmallVec` from `smallvec` keeps a few slots inline
//! before it allocates. [`SlotStorage`] is an unsafe trait, because the map
//! relies on the storage behaving like a `Vec` when it reads slots without
//! bounds checks.
//!
//! The methods that make room ahead of time, which are
//! [`reserve`](GenMap::reserve), [`try_reserve`](GenMap::try_reserve),
//! [`with_capacity`](GenMap::with_capacity) and
//! [`with_capacity_and_config`](GenMap::with_capacity_and_config), only
//! exist when the storage also implements [`ReserveStorage`], as `Vec` and
//! `SmallVec` do.
//!
//! # When the map is full
//!
//! A map is full when none of its slots are free, and it can not add another
//! one, either because its keys have no index left for a new slot or because
//! the storage can not make room for one. A `u8` index, for example, allows
//! 256 slots.
//!
//! [`insert`](GenMap::insert) panics on a full map. The other ways to insert
//! report a full map as an error.
//!
//! - [`try_insert`](GenMap::try_insert) returns an [`InsertError`] that hands
//! the value back.
//! - [`vacant_entry`](GenMap::vacant_entry) picks the slot before the value
//! exists, and returns a [`FullError`] if there is none. The entry's
//! [`key`](VacantEntry::key) is the key the value will get, and dropping
//! the entry leaves the map as it was.
//! - [`try_insert_with_key`](GenMap::try_insert_with_key) runs a closure that
//! may fail, and returns an [`InsertWithError`] if the map is full or the
//! closure fails.
//!
//! When a `Vec` can not allocate, these methods also return a
//! [`StorageFull`](FullError::StorageFull) error instead of panicking.
//!
//! ```
//! use gen_map::{Config, GenMap, InsertError, Split};
//!
//! struct Tiny;
//!
//! impl Config for Tiny {
//! type Idx = u8;
//! type Gen = u8;
//! type Layout = Split;
//! type Storage<S> = Vec<S>;
//! }
//!
//! let mut map = GenMap::<u32, Tiny>::new_with_config();
//! for i in 0..256 {
//! map.insert(i);
//! }
//! match map.try_insert(256) {
//! Err(InsertError::IndexExhausted(value)) => assert_eq!(value, 256),
//! _ => unreachable!(),
//! }
//! ```
//!
//! # Values that know their own key
//!
//! [`insert_with_key`](GenMap::insert_with_key) gives a closure the new
//! value's key before the value is stored, which helps with values that
//! refer to themselves, such as the nodes of a graph.
//!
//! ```
//! use gen_map::{GenMap, Key};
//!
//! struct Node {
//! me: Key,
//! edges: Vec<Key>,
//! }
//!
//! let mut graph = GenMap::new();
//! let a = graph.insert_with_key(|me| Node { me, edges: Vec::new() });
//! let b = graph.insert_with_key(|me| Node { me, edges: vec![a] });
//! assert_eq!(graph[b].me, b);
//! assert_eq!(graph[b].edges, [a]);
//! ```
//!
//! # Taking a value out for a while
//!
//! [`detach`](GenMap::detach) moves a value out of the map but keeps its slot
//! reserved for its key, and [`reattach`](GenMap::reattach) puts a value back
//! under that same key. In between, the key is invalid and no insert can
//! take the slot. This lets code take a value out, change it while borrowing
//! the rest of the map, and put it back under the same key.
//!
//! ```
//! use gen_map::GenMap;
//!
//! let mut map = GenMap::new();
//! let a = map.insert(1);
//! let b = map.insert(2);
//!
//! let mut value = map.detach(a).unwrap();
//! value += map[b];
//! map.reattach(a, value);
//! assert_eq!(map[a], 3);
//! ```
//!
//! # Several values at once
//!
//! [`get_disjoint_mut`](GenMap::get_disjoint_mut) hands out mutable
//! references to several values at once, after checking that every key is
//! valid and that no two keys point at the same slot.
//! [`get_disjoint_mut_at`](GenMap::get_disjoint_mut_at) does the same with
//! slot indices, and hands each key back with its value.
//!
//! ```
//! use gen_map::GenMap;
//!
//! let mut map = GenMap::new();
//! let a = map.insert(1);
//! let b = map.insert(2);
//!
//! let [x, y] = map.get_disjoint_mut([a, b]).unwrap();
//! core::mem::swap(x, y);
//! assert_eq!((map[a], map[b]), (2, 1));
//! ```
//!
//! # Looking a slot up by its index
//!
//! [`key_at`](GenMap::key_at) and [`get_at`](GenMap::get_at) find the value
//! in the slot at an index along with its current key, for code that only
//! kept the index. [`generation_at`](GenMap::generation_at) returns a slot's
//! generation whether it holds a value or not.
//!
//! # Iterating and removing in bulk
//!
//! Every iterator visits the values in slot order, which is also the order
//! of their keys. [`iter`](GenMap::iter), [`iter_mut`](GenMap::iter_mut),
//! [`keys`](GenMap::keys), [`values`](GenMap::values),
//! [`values_mut`](GenMap::values_mut) and the owning `into_iter` all know
//! their exact length and can run from both ends.
//!
//! [`retain`](GenMap::retain), [`drain`](GenMap::drain) and
//! [`clear`](GenMap::clear) remove values but keep every slot and its
//! generation, so old keys stay invalid. [`reset`](GenMap::reset) removes
//! the slots too while keeping the allocation. The generations start over
//! after a reset, so a key from before the reset can match a value inserted
//! after it.
//!
//! # Unchecked access
//!
//! Every lookup has an `_unchecked` form, such as
//! [`get_unchecked`](GenMap::get_unchecked), that skips the checks the
//! normal form makes, for code that already knows its key or index is valid.
//! Calling one with an invalid key or index is undefined behavior.
//!
//! [`Key::from_raw_parts`] builds a key from an index and a generation. It
//! is unsafe because the generation must be odd and both parts must fit the
//! layout, and looking up a key that breaks either rule is undefined
//! behavior.
//!
//! # Cargo features
//!
//! - `alloc` is on by default. It adds the `Vec` storage, [`DefaultConfig`]
//! and [`GenMap::new`], and makes [`DefaultConfig`] the config that
//! [`GenMap`] and [`Key`] use when none is named. Without it the crate
//! needs no allocator, and every map needs a config whose storage does not
//! allocate, such as an `ArrayVec`.
//! - `arrayvec` lets a config use `arrayvec::ArrayVec` as its storage.
//! - `smallvec` lets a config use `smallvec::SmallVec` as its storage. It
//! uses the 2.0 beta of `smallvec`, which needs an allocator and Rust 1.86.
//! Until smallvec 2.0 is released, a newer smallvec beta or a new release
//! of gen_map may break this feature, so it is not covered by semver.
//!
//! To use the map without any allocator, turn `alloc` off and `arrayvec` on.
//!
//! ```toml
//! [dependencies]
//! gen_map = { version = "0.2", default-features = false, features = ["arrayvec"] }
//! ```
//!
//! # Minimum supported Rust version
//!
//! The crate builds on Rust 1.79 and later. The `smallvec` feature needs
//! Rust 1.86, because the 2.0 beta of `smallvec` does.
extern crate alloc;
extern crate std;
pub use Config;
pub use DefaultConfig;
pub use ;
pub use Key;
pub use ;
pub use KeyPiece;
pub use ;
pub use ;
// The tests use `Vec` storage and the default config, so they need `alloc`.