From 7b65860fb718ab23a9f93d317d0531497f966e27 Mon Sep 17 00:00:00 2001 From: "iliya.saroukha" <iliya.saroukha@hes-so.ch> Date: Thu, 14 Sep 2023 11:51:42 +0200 Subject: [PATCH] working on runtime sized stack --- unsafe_stack/.gitignore | 1 + unsafe_stack/Cargo.toml | 8 +++ unsafe_stack/src/main.rs | 16 ++++++ unsafe_stack/src/unsafe_stack/mod.rs | 78 ++++++++++++++++++++++++++++ 4 files changed, 103 insertions(+) create mode 100644 unsafe_stack/.gitignore create mode 100644 unsafe_stack/Cargo.toml create mode 100644 unsafe_stack/src/main.rs create mode 100644 unsafe_stack/src/unsafe_stack/mod.rs diff --git a/unsafe_stack/.gitignore b/unsafe_stack/.gitignore new file mode 100644 index 0000000..b83d222 --- /dev/null +++ b/unsafe_stack/.gitignore @@ -0,0 +1 @@ +/target/ diff --git a/unsafe_stack/Cargo.toml b/unsafe_stack/Cargo.toml new file mode 100644 index 0000000..9d61588 --- /dev/null +++ b/unsafe_stack/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "unsafe_stack" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/unsafe_stack/src/main.rs b/unsafe_stack/src/main.rs new file mode 100644 index 0000000..97a00b3 --- /dev/null +++ b/unsafe_stack/src/main.rs @@ -0,0 +1,16 @@ +use unsafe_stack::{Stack, StackError}; +mod unsafe_stack; + +fn main() -> Result<(), StackError> { + let mut new_stack: Stack<f64> = Stack::new(10).unwrap(); + + for i in 0..new_stack.capacity { + unsafe { + new_stack.push(i as f64).unwrap(); + } + } + + println!("{}", new_stack); + + Ok(()) +} diff --git a/unsafe_stack/src/unsafe_stack/mod.rs b/unsafe_stack/src/unsafe_stack/mod.rs new file mode 100644 index 0000000..346df6c --- /dev/null +++ b/unsafe_stack/src/unsafe_stack/mod.rs @@ -0,0 +1,78 @@ +#[derive(Debug)] +pub enum StackError { + AllocationFailed, + StackFull, + StackEmpty, +} + +#[derive(Debug)] +pub struct Stack<T> { + pointer: *mut T, + length: usize, + pub capacity: usize, +} + +impl<T: Copy + std::fmt::Display> std::fmt::Display for Stack<T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + Ok(for i in 0..self.capacity { + unsafe { + write!(f, "{} ", *self.pointer.offset(i as isize) as T)?; + } + }) + } +} + +#[allow(dead_code)] +impl<T: Copy> Stack<T> { + pub fn new(capacity: usize) -> Result<Self, StackError> { + unsafe { + let layout = std::alloc::Layout::array::<T>(capacity); + + if let Ok(val) = layout { + let ptr = std::alloc::alloc(val); + if ptr.is_null() { + return Err(StackError::AllocationFailed); + } + + Ok(Self { + pointer: ptr as *mut T, + length: 0, + capacity, + }) + } else { + Err(StackError::AllocationFailed) + } + } + } + + pub fn is_full(&self) -> bool { + self.length == self.capacity + } + + pub fn is_empty(&self) -> bool { + self.length == 0 + } + + pub unsafe fn push(&mut self, value: T) -> Result<(), StackError> { + match self.is_full() { + true => Err(StackError::StackFull), + false => unsafe { + let location = self.pointer.offset(self.length as isize); + *location = value; + self.length += 1; + Ok(()) + }, + } + } + + pub unsafe fn pop(&mut self) -> Result<T, StackError> { + match self.is_empty() { + true => Err(StackError::StackEmpty), + false => unsafe { + let location = self.pointer.offset(self.length as isize - 1); + self.length -= 1; + Ok(*location) + }, + } + } +} -- GitLab