Skip to content

Instantly share code, notes, and snippets.

@leophys
Created April 17, 2022 02:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leophys/3e339ac1a7a6f6c512a0db4d169e4091 to your computer and use it in GitHub Desktop.
Save leophys/3e339ac1a7a6f6c512a0db4d169e4091 to your computer and use it in GitHub Desktop.
unsafe_ring.rs
use std::ptr;
#[derive(Clone)]
pub struct Ring<T: Clone> {
head: *mut Node<T>,
capacity: usize,
}
impl<T: Clone> Ring<T> {
pub fn capacity(&self) -> usize {
self.capacity
}
}
#[derive(Clone)]
struct Node<T: Clone> {
elem: T,
next: *mut Node<T>,
}
impl<T: Clone> Ring<T> {
pub fn new(capacity: usize, initializer: T) -> Self {
if capacity == 0 {
panic!("null ring is ill defined!");
}
let head: *mut Node<T> = unsafe {
let head = Box::into_raw(Box::new(Node {
elem: initializer.clone(),
next: ptr::null_mut(),
}));
let mut cur: *mut _ = head;
for _ in 1..capacity {
let next = Box::into_raw(Box::new(Node {
elem: initializer.clone(),
next: ptr::null_mut(),
}));
(*cur).next = next;
cur = next;
}
(*cur).next = head;
(*cur).next
};
Self { head, capacity }
}
pub fn next(&mut self) {
unsafe { self.head = (*self.head).next };
}
pub fn get(&self) -> &T {
unsafe { &(*self.head).elem }
}
pub fn set(&mut self, new_val: T) {
unsafe {
(*self.head).elem = new_val;
}
}
}
impl<T: Clone> Drop for Ring<T> {
fn drop(&mut self) {
for _ in 0..self.capacity {
self.head;
self.next();
}
}
}
#[test]
fn test_new_ring() {
let ring: Ring<i32> = Ring::new(3, 0);
assert_eq!(ring.capacity(), 3);
}
#[test]
fn test_ring() {
let mut ring: Ring<i32> = Ring::new(3, 0);
assert_eq!(*ring.get(), 0);
ring.next();
assert_eq!(*ring.get(), 0);
ring.next();
assert_eq!(*ring.get(), 0);
ring.next();
ring.set(1);
ring.next();
ring.set(2);
ring.next();
ring.set(3);
ring.next();
assert_eq!(*ring.get(), 1);
ring.next();
assert_eq!(*ring.get(), 2);
ring.next();
assert_eq!(*ring.get(), 3);
ring.next();
assert_eq!(*ring.get(), 1);
ring.next();
assert_eq!(*ring.get(), 2);
ring.next();
assert_eq!(*ring.get(), 3);
ring.next();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment