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
/// A mark used to indicate which slots in an [`XNode`] contain items that have been marked.
///
/// [`Xnode`]: crate::node::XNode
///
/// It internally stores a `u64`, functioning as a bitmap, where each bit that is set to 1
/// represents a slot at the corresponding offset that has been marked.
#[derive(Debug, Clone, Copy)]
pub(super) struct Mark {
inner: u64,
}
impl Mark {
pub const EMPTY: Self = Self::new(0);
pub const fn new(inner: u64) -> Self {
Self { inner }
}
pub fn set(&mut self, offset: u8) {
self.inner |= 1 << offset as u64;
}
pub fn unset(&mut self, offset: u8) {
self.inner &= !(1 << offset as u64);
}
pub fn update(&mut self, offset: u8, set: bool) -> bool {
let mut new_inner = self.inner;
if set {
new_inner |= 1 << offset as u64;
} else {
new_inner &= !(1 << offset as u64);
}
let changed = new_inner != self.inner;
self.inner = new_inner;
changed
}
pub fn clear(&mut self) {
self.inner = 0
}
pub fn is_marked(&self, offset: u8) -> bool {
(self.inner & 1 << offset as u64) != 0
}
pub fn is_clear(&self) -> bool {
self.inner == 0
}
}
/// The mark type used in the [`XArray`].
///
/// The `XArray` itself and an item in it can have up to three different marks.
///
/// Users can use a self-defined type to distinguish which kind of mark they want to set. Such a
/// type must implement the `Into<XMark>` trait.
///
/// [`XArray`]: crate::XArray
pub enum XMark {
Mark0,
Mark1,
Mark2,
}
pub const NUM_MARKS: usize = 3;
impl XMark {
/// Maps the `XMark` to an index in the range 0 to 2.
pub(super) fn index(&self) -> usize {
match self {
XMark::Mark0 => 0,
XMark::Mark1 => 1,
XMark::Mark2 => 2,
}
}
}
/// A meaningless mark used as a default generic parameter for `XArray`, indicating that the
/// marking functionality is not needed.
#[derive(Clone, Copy)]
pub struct NoneMark {}
impl Into<XMark> for NoneMark {
fn into(self) -> XMark {
panic!("NoneMark can not be used!");
}
}