Created
April 17, 2022 02:10
-
-
Save leophys/3e339ac1a7a6f6c512a0db4d169e4091 to your computer and use it in GitHub Desktop.
unsafe_ring.rs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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