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
//! Arena allocation for Mago.
//!
//! Three bump arenas, all implementing the [`Arena`] trait:
//!
//! - [`LocalArena`]: single-threaded, fastest, `Send` but `!Sync`.
//! - [`SharedArena`]: `Send + Sync`, safe to share across threads (for example
//! behind a `&SharedArena` handed to every worker in a `rayon` pass).
//! - [`ScopedArena`]: a thread-local view into a [`SharedArena`] (via
//! [`SharedArena::scoped`]) for contention-free, non-escaping scratch.
//!
//! Because all three implement [`Arena`] (and the underlying `Allocator` trait),
//! allocation code is written generically over `A: Arena` and never needs to know
//! which arena it was given:
//!
//! ```ignore
//! fn lower<'arena, A: Arena + ?Sized>(arena: &'arena A, ast: &Ast) -> &'arena Ir<'arena> {
//! arena.alloc(Ir::from(ast))
//! }
//! ```
//!
//! Allocations live as long as the borrow of the arena they came from, and are
//! reclaimed wholesale when the arena is dropped or reset. For growable
//! collections, use the aliases in [`vec`](mod@vec), [`boxed`], and
//! [`collections`], each built with its `*_in(arena)` constructor; to collect an
//! iterator straight into the arena, use [`CollectIn`] (and `ParallelCollectIn`
//! under the `rayon` feature); for an immutable string copied into the arena, use
//! [`Arena::alloc_str`]; to deep-copy an arena-resident value into a different
//! arena, implement [`CopyInto`].
//!
//! Each module also re-exports the items of its underlying crate (`allocator_api2`
//! for [`alloc`](mod@alloc), [`boxed`], [`vec`](mod@vec); `hashbrown` for
//! [`collections`]), so anything not surfaced by the aliases above is still
//! reachable.
pub use Arena;
pub use LocalArena;
pub use ScopedArena;
pub use SharedArena;
pub use CopyInto;
pub use CollectIn;
pub use FromIteratorIn;
pub use ParallelCollectIn;
/// Builds an arena-allocated [`Vec`](vec::Vec), analogous to [`std::vec!`].
///
/// The first argument is the arena (or any `&allocator`); the elements follow a
/// `;`:
///
/// ```
/// use mago_allocator::prelude::*;
///
/// let arena = LocalArena::new();
/// let evens = vec_in![&arena; 0, 2, 4];
/// assert_eq!(evens.as_slice(), &[0, 2, 4]);
/// ```
/// Formats its arguments into an arena, returning `&mut str`.
///
/// The macro form of [`Arena::alloc_fmt`], reading like [`format!`] but with no
/// intermediate global allocation:
///
/// ```
/// use mago_allocator::prelude::*;
///
/// let arena = LocalArena::new();
/// let label = format_in!(arena, "{}::{}", "App", "VERSION");
/// assert_eq!(label, "App::VERSION");
/// ```