Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::ptr;
- use std::sync::atomic::{ AtomicPtr, Ordering };
- struct List<T> {
- head: AtomicPtr<Node<T>>,
- }
- impl<T> List<T> {
- pub fn new() -> Self {
- let first = Node::new(None);
- List {
- head: AtomicPtr::new(first),
- }
- }
- pub fn head(self) -> Node<T> {
- *Box::from(self.head)
- }
- pub fn tail(self) -> List<T> {
- List {
- head: self.head().next
- }
- }
- }
- struct Node<T> {
- value: Option<T>,
- next: AtomicPtr<Node<T>>,
- }
- impl<T> From<AtomicPtr<Node<T>>> for Box<Node<T>> {
- fn from(aptr: AtomicPtr<Node<T>>) -> Box<Node<T>> {
- let ptr = ptr::null_mut();
- loop {
- aptr.swap(ptr, Ordering::SeqCst);
- if ptr == ptr::null_mut() {
- continue;
- } else {
- break;
- }
- }
- unsafe {
- Box::from_raw(ptr)
- }
- }
- }
- impl<T> Node<T> {
- pub fn new(value: Option<T>) -> *mut Self {
- let b = Box::new(Node {
- value,
- next: AtomicPtr::new(ptr::null_mut()),
- });
- Box::into_raw(b)
- }
- }
- #[cfg(test)]
- mod tests {
- use super::*;
- #[test]
- fn empty_list() {
- let lst: List<f64> = List::new();
- assert_eq!(lst.head().value, None);
- }
- }
Add Comment
Please, Sign In to add comment