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
//! # sefer-region — typed handle-addressed store
//!
//! A thin typed membrane over [`slotmap`](https://docs.rs/slotmap): values live
//! in slotmap's dense, cache-friendly, always-compact backing store, and every
//! operation exposes only typed [`Handle<T>`] values — raw `DefaultKey`s never
//! escape the crate boundary.
//!
//! ## What makes this different from using slotmap directly?
//!
//! Slotmap's `DefaultKey` is untyped: a `DefaultKey` from one map can be passed
//! to another of a different value type without a compile error. `sefer-region`
//! wraps it in `Handle<T>` — a `PhantomData<fn() -> T>`-branded key — so the
//! compiler rejects cross-region handle confusion at the type level.
//!
//! ## Invariants upheld (I1–I5)
//!
//! - **I1 — resolution:** a fresh handle resolves via [`Region::get`] to the
//! inserted value until it is [`Region::remove`]d.
//! - **I2 — tombstone:** after `remove(h)`, `get(h)` is `None` forever; a
//! second `remove(h)` is a no-op `None`.
//! - **I3 — no ABA:** a stale handle — one whose slot has since been reused —
//! never resolves to a live value. slotmap's `DefaultKey` carries a generation
//! that is bumped on removal, so the old handle fails the version check.
//! - **I4 — accounting:** [`Region::len`] equals the number of live entries and
//! [`Region::is_empty`] agrees.
//! - **I5 — drop-once:** every live value is dropped exactly once — on `remove`
//! (returned to the caller) or on `Region` drop — never twice, never leaked.
//!
//! ## Pure Rust / zero own unsafe
//!
//! `#![forbid(unsafe_code)]` at the top of this crate. The internal `unsafe` in
//! the `slotmap` dependency is its own, audited and battle-tested. This crate
//! adds no C / C++ libraries and contributes zero `unsafe` blocks of its own.
//!
//! ## `no_std` support
//!
//! With `default-features = false` (disabling `std`) the crate compiles under
//! `no_std + alloc`, providing [`Region<T>`] and [`Handle<T>`]. The `std`
//! feature (on by default) additionally enables [`SyncRegion<T>`], which wraps
//! `Region<T>` in `std::sync::RwLock`.
extern crate alloc;
pub use Handle;
pub use Region;
pub use SyncRegion;