swc_allocator/lib.rs
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
//! Allocator for swc.
//!
//! # Features
//!
//! - `scoped`: Enable `scoped` mode.
//!
//! # Modes
//!
//! ## Default mode
//!
//! In default mode, [crate::boxed::Box] and [crate::vec::Vec] are identical to
//! the original types in [std].
//!
//! ## Scoped mode
//!
//! - You need to enable `scoped` feature to use this mode.
//!
//! In `scoped` mode you can use [FastAlloc] to make [crate::boxed::Box] and
//! [crate::vec::Vec] very fast.
//!
//! In this mode, you need to be careful while using [crate::boxed::Box] and
//! [crate::vec::Vec]. You should ensure that [Allocator] outlives all
//! [crate::boxed::Box] and [crate::vec::Vec] created in the scope.
//!
//! Recommened way to use this mode is to wrap the whole operations in
//! a call to [Allocator::scope].
#![allow(clippy::needless_doctest_main)]
#![cfg_attr(docsrs, feature(doc_cfg))]
#![cfg_attr(
feature = "nightly",
feature(allocator_api, fundamental, with_negative_coherence, box_into_inner)
)]
#![deny(missing_docs)]
#![allow(clippy::derivable_impls)]
pub use crate::alloc::Allocator;
mod alloc;
#[cfg(feature = "nightly")]
pub mod boxed;
pub mod collections;
#[cfg(feature = "nightly")]
pub mod vec;
/// Box<T> and Vec<T> depeding on the feature.
pub mod maybe {
#[cfg(not(feature = "nightly"))]
pub use std::{boxed, vec};
#[cfg(feature = "nightly")]
pub use crate::{boxed, vec};
}
/// Fast allocator, effectively working as a cache.
///
/// This type implements [Default] and [Copy]. This type is intended to stored
/// in a variable or a field in a struct before allocating code, and used as the
/// seocnd argument in [crate::boxed::Box::new_in] and
/// [crate::vec::Vec::new_in].
///
/// [crate::boxed::Box::new] and [crate::vec::Vec::new] are slower than using
/// this field because they use [FastAlloc::default] internally, which is slower
/// than store [FastAlloc] in a variable.
///
///
///
/// # Misc
///
/// It implements [`std::alloc::Allocator`]. So it can be used as the
/// second argument for [`std::boxed::Box`] and
/// [`std::vec::Vec`]. But you should prefer using
/// [`crate::boxed::Box`] and [`crate::vec::Vec`], which is a wrapper around the
/// original types.
#[derive(Clone, Copy)]
pub struct FastAlloc {
#[cfg(feature = "scoped")]
alloc: Option<&'static Allocator>,
}
impl FastAlloc {
/// [crate::boxed::Box] or [crate::vec::Vec] created with this instance is
/// managed by the global allocator and it can outlive the
/// [crate::Allocator] instance used for [Allocator::scope].
pub const fn global() -> Self {
Self {
#[cfg(feature = "scoped")]
alloc: None,
}
}
}
/// This expands to the given tokens if the `nightly` feature is enabled.
#[cfg(feature = "nightly")]
#[macro_export]
macro_rules! nightly_only {
(
$($item:item)*
) => {
$(
#[cfg_attr(docsrs, doc(cfg(feature = "nightly")))]
$item
)*
};
}
/// This expands to the given tokens if the `nightly` feature is enabled.
#[cfg(not(feature = "nightly"))]
#[macro_export]
macro_rules! nightly_only {
(
$($item:item)*
) => {};
}
/// Usage: `swc_allocator::Type!(Vec<T>)` or `swc_allocator::Type!(Box<T>)`.
#[macro_export]
macro_rules! Type {
(Box<$($tt:tt)*>) => {
#[cfg(feature = "nightly")]
$crate::boxed::Box<$crate::Type!($($tt)*)>
#[cfg(not(feature = "nightly"))]
std::boxed::Box<$crate::Type!($($tt)*)>
};
(Vec<$($tt:tt)*>) => {
#[cfg(feature = "nightly")]
$crate::vec::Vec<$crate::Type!($($tt)*)>
#[cfg(not(feature = "nightly"))]
std::vec::Vec<$crate::Type!($($tt)*)>
};
($t:ty) => {
$t
};
}