blink_alloc/
lib.rs

1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(feature = "nightly", feature(allocator_api))]
4
5#[cfg(feature = "alloc")]
6extern crate alloc;
7
8macro_rules! feature_switch {
9    ( ($feature:literal => $with:path | $without:path) ($($args:tt)*)) => {
10        #[cfg(feature = $feature)]
11        $with!($($args)*);
12
13        #[cfg(not(feature = $feature))]
14        $without!($($args)*);
15    };
16}
17
18#[allow(unused)]
19macro_rules! with_default {
20    ($(#[$meta:meta])* $v:vis struct $name:ident<$($lt:lifetime,)* $($generic:ident $(: $bound:path $(: $bounds:path )*)? $(= +$default:ty)? $(= $default_type:ty)?),+> { $($(#[$fmeta:meta])*  $fvis:vis $fname:ident: $ftype:ty),* $(,)? }) => {
21        $(#[$meta])*
22        $v struct $name<$($lt,)* $($generic $(: $bound $(+ $bounds)*)? $(= $default)? $(= $default_type)?)+> {
23            $($(#[$fmeta])* $fvis $fname: $ftype,)*
24        }
25    };
26}
27
28#[allow(unused)]
29macro_rules! without_default {
30    ($(#[$meta:meta])* $v:vis struct $name:ident<$($lt:lifetime,)* $($generic:ident $(: $bound:path $(: $bounds:path )*)? $(= +$default:ty)? $(= $default_type:ty)?),+> { $($(#[$fmeta:meta])* $fvis:vis $fname:ident: $ftype:ty),* $(,)? }) => {
31        $(#[$meta])*
32        $v struct $name<$($lt,)* $($generic $(: $bound $(+ $bounds)*)? $(= $default_type)?)+> {
33            $($(#[$fmeta])* $fvis $fname: $ftype,)*
34        }
35    };
36}
37
38macro_rules! switch_alloc_default {
39    ($($args:tt)*) => {
40        feature_switch!{("alloc" => with_default | without_default) ($($args)*)}
41    };
42}
43
44macro_rules! switch_std_default {
45    ($($args:tt)*) => {
46        feature_switch!{("std" => with_default | without_default) ($($args)*)}
47    };
48}
49
50mod api;
51mod arena;
52mod blink;
53mod drop_list;
54mod global;
55mod local;
56
57#[cfg(feature = "sync")]
58mod sync;
59
60#[cfg(all(feature = "sync", feature = "alloc"))]
61mod cache;
62
63#[cfg(test)]
64mod tests;
65
66#[cfg(not(no_global_oom_handling))]
67mod oom;
68
69pub use self::{
70    api::BlinkAllocator,
71    blink::{Blink, Emplace, IteratorExt, SendBlink},
72    global::local::UnsafeGlobalBlinkAlloc,
73    local::BlinkAlloc,
74};
75
76#[cfg(feature = "sync")]
77pub use self::sync::{LocalBlinkAlloc, SyncBlinkAlloc};
78
79#[cfg(feature = "sync")]
80pub use self::global::sync::GlobalBlinkAlloc;
81
82#[cfg(all(feature = "sync", feature = "alloc"))]
83pub use self::cache::BlinkAllocCache;
84
85pub(crate) trait ResultExt<T> {
86    fn safe_ok(self) -> T;
87}
88
89impl<T> ResultExt<T> for Result<T, core::convert::Infallible> {
90    #[inline]
91    fn safe_ok(self) -> T {
92        match self {
93            Ok(value) => value,
94            Err(never) => match never {},
95        }
96    }
97}
98
99#[inline]
100unsafe fn in_place<'a, T, I>(ptr: *mut T, init: I, f: impl FnOnce(I) -> T) -> &'a mut T {
101    // Ask compiler very nicely to store return directly into memory.
102    core::ptr::write(ptr, f(init));
103    &mut *ptr
104}
105
106#[cold]
107fn cold() {}
108
109// #[cfg(debug_assertions)]
110// #[track_caller]
111// unsafe fn unreachable_unchecked() -> ! {
112//     unreachable!()
113// }
114
115// #[cfg(not(debug_assertions))]
116// unsafe fn unreachable_unchecked() -> ! {
117//     unsafe { core::hint::unreachable_unchecked() }
118// }