add: Fast Stack
This is an implementation of a stack that does minimal bookeeping, has zero heap allocations, and is guaranteed to not panic
This commit is contained in:
parent
045887cd62
commit
191bc824c2
3 changed files with 79 additions and 0 deletions
60
crates/core/src/util/fast_stack.rs
Normal file
60
crates/core/src/util/fast_stack.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
use super::gurantee;
|
||||
|
||||
pub struct FastStack {
|
||||
storage: [u8; 256],
|
||||
pos: usize
|
||||
}
|
||||
|
||||
impl FastStack {
|
||||
#[inline(always)]
|
||||
pub fn new() -> FastStack {
|
||||
FastStack {
|
||||
storage: [0; 256],
|
||||
pos: 0
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn push(&mut self, value: u8) {
|
||||
gurantee(!self.overgrown());
|
||||
|
||||
self.storage[self.pos] = value;
|
||||
self.pos += 1;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn peek(&self) -> u8 {
|
||||
gurantee(!self.overgrown());
|
||||
|
||||
return self.storage[self.pos - 1];
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn last(&self) -> Option<u8> {
|
||||
if self.is_empty() || self.overgrown() {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(self.peek());
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn pop(&mut self) {
|
||||
// SAFETY: The buffer does not need to be mutated because the stack is
|
||||
// only ever read from or written to its current position. Its current
|
||||
// position is only ever incremented after writing to it. Meaning that
|
||||
// the buffer can be dirty for the next use and still be correct since
|
||||
// reading/writing always starts at position `0`.
|
||||
self.pos = self.pos.saturating_sub(1);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
return self.pos == 0;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn overgrown(&self) -> bool {
|
||||
self.pos > 256
|
||||
}
|
||||
}
|
||||
11
crates/core/src/util/gurantee.rs
Normal file
11
crates/core/src/util/gurantee.rs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#[inline(always)]
|
||||
pub const fn gurantee(expr: bool) {
|
||||
#[cfg(debug_assertions)]
|
||||
if !expr {
|
||||
panic!("gurantee failed")
|
||||
}
|
||||
|
||||
unsafe {
|
||||
std::hint::assert_unchecked(expr)
|
||||
}
|
||||
}
|
||||
8
crates/core/src/util/mod.rs
Normal file
8
crates/core/src/util/mod.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
mod fast_stack;
|
||||
mod gurantee;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
pub use crate::util::fast_stack::*;
|
||||
|
||||
#[allow(unused_imports)]
|
||||
pub use crate::util::gurantee::*;
|
||||
Loading…
Add table
Add a link
Reference in a new issue