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
/*
* Copyright (C) 2021-2022 taylor.fish <contact@taylor.fish>
*
* This file is part of fixed-typed-arena.
*
* fixed-typed-arena is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* fixed-typed-arena is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with fixed-typed-arena. If not, see <https://www.gnu.org/licenses/>.
*/
#![no_std]
#![cfg_attr(feature = "dropck_eyepatch", feature(dropck_eyepatch))]
#![deny(unsafe_op_in_unsafe_fn)]
#![warn(clippy::pedantic)]
#![allow(clippy::default_trait_access)]
#![allow(clippy::module_name_repetitions)]
#![allow(clippy::must_use_candidate)]
//! An arena that allocates values of a single type (similar to [typed-arena])
//! using chunks of memory that have a configurable fixed size. This enables it
//! to perform allocations in non-amortized O(1) (constant) time.
//!
//! Other arena implementations, like [typed-arena], are optimized for
//! throughput: they allocate chunks of memory with exponentially increasing
//! sizes, which results in *amortized* constant-time allocations.
//!
//! [typed-arena]: https://docs.rs/typed-arena
//!
//! **fixed-typed-arena** is optimized for latency: it allocates chunks of
//! memory with a fixed, configurable size, and individual value allocations
//! are performed in non-amortized constant time.
//!
//! This crate depends only on [`core`] and [`alloc`], so it can be used in
//! `no_std` environments that support [`alloc`].
//!
//! [`core`]: https://doc.rust-lang.org/core/
//! [`alloc`]: https://doc.rust-lang.org/alloc/
//!
//! Example
//! -------
//!
//! ```rust
//! use fixed_typed_arena::Arena;
//! struct Item(u64);
//!
//! let arena = Arena::<_, 128>::new();
//! let item1 = arena.alloc(Item(1));
//! let item2 = arena.alloc(Item(2));
//! item1.0 += item2.0;
//!
//! assert_eq!(item1.0, 3);
//! assert_eq!(item2.0, 2);
//! ```
//!
//! References
//! ----------
//!
//! Items allocated by an [`Arena`] can contain references with the same life
//! as the arena itself, including references to other items, but the crate
//! feature `dropck_eyepatch` must be enabled. This requires Rust nightly, as
//! fixed-typed-arena must use the [eponymous unstable language feature][drop].
//!
//! [drop]: https://github.com/rust-lang/rust/issues/34761
//!
//! Alternatively, you may be able to use a [`ManuallyDropArena`] instead.
//!
//! ManuallyDropArena
//! -----------------
//!
//! This crate also provides [`ManuallyDropArena`], which is like [`Arena`] but
//! returns references of any lifetime, including `'static`. The advantage of
//! this type is that it can be used without being borrowed, but it comes with
//! the tradeoff that it will leak memory unless the unsafe [`drop`] method is
//! called.
//!
//! Iteration
//! ---------
//!
//! fixed-typed-arena’s arena types allow iteration over all allocated items.
//! Safe mutable iteration is provided for [`Arena`], and safe immutable
//! iteration is provided for all arena types if [`Options::Mutable`] is false.
//! Unsafe mutable and immutable iteration is provided for all arena types
//! regardless of options.
//!
//! [`Arena`]: arena::Arena
//! [`ManuallyDropArena`]: manually_drop::ManuallyDropArena
//! [`drop`]: manually_drop::ManuallyDropArena::drop
extern crate alloc;
mod chunk;
pub mod options;
#[cfg(test)]
mod tests;
pub mod arena;
pub mod manually_drop;
pub use options::{ArenaOptions, Options};
/// Arena iterators.
pub mod iter {
pub use super::manually_drop::iter::*;
}
#[rustfmt::skip]
/// Convenience alias for [`arena::Arena`].
pub type Arena<
T,
const CHUNK_SIZE: usize = 16,
const SUPPORTS_POSITIONS: bool = false,
const MUTABLE: bool = true,
> = arena::Arena<
T,
Options<
CHUNK_SIZE,
SUPPORTS_POSITIONS,
MUTABLE,
>,
>;
#[rustfmt::skip]
/// Convenience alias for [`manually_drop::ManuallyDropArena`].
pub type ManuallyDropArena<
T,
const CHUNK_SIZE: usize = 16,
const SUPPORTS_POSITIONS: bool = false,
const MUTABLE: bool = true,
> = manually_drop::ManuallyDropArena<
T,
Options<
CHUNK_SIZE,
SUPPORTS_POSITIONS,
MUTABLE,
>,
>;