bump_scope/
bump_scope_guard.rs1use core::{fmt::Debug, num::NonZeroUsize, ptr::NonNull};
2
3use crate::{
4 BaseAllocator, BumpScope,
5 chunk::ChunkHeader,
6 polyfill::transmute_mut,
7 raw_bump::{RawBump, RawChunk},
8 settings::{BumpAllocatorSettings, BumpSettings},
9 stats::AnyStats,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
17pub struct Checkpoint {
18 pub(crate) chunk: NonNull<ChunkHeader>,
19 pub(crate) address: NonZeroUsize,
20}
21
22impl Checkpoint {
23 pub(crate) fn new<A, S: BumpAllocatorSettings>(chunk: RawChunk<A, S>) -> Self {
24 let address = chunk.pos().addr();
25 let chunk = chunk.header.cast();
26 Checkpoint { chunk, address }
27 }
28
29 pub(crate) unsafe fn reset_within_chunk(self) {
30 unsafe {
31 let ptr = self.chunk.cast::<u8>().with_addr(self.address);
32 self.chunk.as_ref().pos.set(ptr);
33 }
34 }
35}
36
37#[must_use]
41pub struct BumpScopeGuard<'a, A, S = BumpSettings>
42where
43 A: BaseAllocator<S::GuaranteedAllocated>,
44 S: BumpAllocatorSettings,
45{
46 bump: &'a mut RawBump<A, S>,
47 checkpoint: Checkpoint,
48}
49
50impl<A, S> Debug for BumpScopeGuard<'_, A, S>
51where
52 A: BaseAllocator<S::GuaranteedAllocated>,
53 S: BumpAllocatorSettings,
54{
55 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
56 AnyStats::from(self.bump.stats()).debug_format("BumpScopeGuard", f)
57 }
58}
59
60impl<A, S> Drop for BumpScopeGuard<'_, A, S>
61where
62 A: BaseAllocator<S::GuaranteedAllocated>,
63 S: BumpAllocatorSettings,
64{
65 #[inline(always)]
66 fn drop(&mut self) {
67 self.reset();
68 }
69}
70
71impl<'a, A, S> BumpScopeGuard<'a, A, S>
72where
73 A: BaseAllocator<S::GuaranteedAllocated>,
74 S: BumpAllocatorSettings,
75{
76 #[inline(always)]
77 pub(crate) fn new(bump: &'a mut RawBump<A, S>) -> Self {
78 let checkpoint = bump.checkpoint();
79 Self { bump, checkpoint }
80 }
81
82 #[inline(always)]
84 pub fn scope(&mut self) -> &mut BumpScope<'_, A, S> {
85 unsafe { transmute_mut(self.bump) }
86 }
87
88 #[inline(always)]
90 pub fn reset(&mut self) {
91 unsafe { self.bump.reset_to(self.checkpoint) }
92 }
93}