Skip to main content

safe_bump/
checkpoint.rs

1use std::marker::PhantomData;
2
3/// Saved allocation state for rollback.
4///
5/// Created by [`Arena::checkpoint`](crate::Arena::checkpoint) or
6/// [`SharedArena::checkpoint`](crate::SharedArena::checkpoint). Rolling back
7/// to a checkpoint drops all values allocated after it and retains everything
8/// before.
9pub struct Checkpoint<T> {
10    len: usize,
11    _marker: PhantomData<T>,
12}
13
14impl<T> Checkpoint<T> {
15    /// Creates a checkpoint from a saved length.
16    ///
17    /// The caller must ensure the length is valid for the target arena.
18    #[must_use]
19    pub const fn from_len(len: usize) -> Self {
20        Self {
21            len,
22            _marker: PhantomData,
23        }
24    }
25
26    /// Returns the saved length.
27    #[must_use]
28    pub const fn len(&self) -> usize {
29        self.len
30    }
31
32    /// Returns `true` if the checkpoint was taken at an empty state.
33    #[must_use]
34    pub const fn is_empty(&self) -> bool {
35        self.len == 0
36    }
37}
38
39impl<T> Clone for Checkpoint<T> {
40    fn clone(&self) -> Self {
41        *self
42    }
43}
44
45impl<T> Copy for Checkpoint<T> {}
46
47impl<T> PartialEq for Checkpoint<T> {
48    fn eq(&self, other: &Self) -> bool {
49        self.len == other.len
50    }
51}
52
53impl<T> Eq for Checkpoint<T> {}
54
55impl<T> std::hash::Hash for Checkpoint<T> {
56    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
57        self.len.hash(state);
58    }
59}
60
61impl<T> std::fmt::Debug for Checkpoint<T> {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        write!(f, "Checkpoint({})", self.len)
64    }
65}
66
67impl<T> PartialOrd for Checkpoint<T> {
68    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
69        Some(self.cmp(other))
70    }
71}
72
73impl<T> Ord for Checkpoint<T> {
74    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
75        self.len.cmp(&other.len)
76    }
77}