#![doc = include_str!("../README.md")]
pub mod compare;
mod pointer;
mod snapshot;
pub use crate::pointer::AtomPtr;
pub use crate::snapshot::Ref;
#[cfg(test)]
use std::sync::Arc;
#[cfg(test)]
#[derive(Clone, Debug, PartialEq)]
struct TestStruct {
name: String,
}
#[test]
fn cloned() {
let ts = TestStruct {
name: "Hello".into(),
};
let ptr1 = AtomPtr::new(ts);
let ptr2 = ptr1.clone();
assert_eq!(ptr1, ptr2);
}
#[test]
fn swap() {
let ts1 = TestStruct {
name: "Hello 1".into(),
};
let ts2 = TestStruct {
name: "Hello 2".into(),
};
let ptr = AtomPtr::new(ts1.clone());
assert_eq!(ptr.get_ref().name, "Hello 1".to_string());
let still_ts1 = ptr.swap(ts2);
assert_eq!(ptr.get_ref().name, "Hello 2".to_string());
assert_eq!(ts1, still_ts1.take_clone());
}
#[test]
fn compare_exchange() {
let ts1 = TestStruct {
name: "Hello 1".into(),
};
let ts2 = TestStruct {
name: "Hello 2".into(),
};
let ts3 = TestStruct {
name: "Hello 3".into(),
};
let ptr = AtomPtr::new(ts1.clone());
assert_eq!(ptr.get_ref().name, "Hello 1".to_string());
let still_ts1 = ptr.compare_exchange(ptr.get_ref(), ts2.clone()).inner();
assert_eq!(ptr.get_ref().name, "Hello 2".to_string());
let still_ts2 = ptr.compare_exchange(ptr.get_ref(), ts3).inner();
assert_eq!(ptr.get_ref().name, "Hello 3".to_string());
assert_eq!(ts1, still_ts1.take_clone());
assert_eq!(ts2, still_ts2.take_clone());
}
#[test]
fn take_from_swap() {
let ts1 = TestStruct {
name: "Hello 1".into(),
};
let ts2 = TestStruct {
name: "Hello 2".into(),
};
let ptr = AtomPtr::new(ts1.clone());
assert_eq!(ptr.get_ref().name, "Hello 1".to_string());
let still_ts1 = ptr.swap(ts2);
assert_eq!(ptr.get_ref().name, "Hello 2".to_string());
assert_eq!(Arc::strong_count(&*still_ts1.inner), 1);
let ts1_again = Arc::try_unwrap(*still_ts1.inner).unwrap();
assert_eq!(ts1_again, ts1);
}
#[test]
fn release() {
let ts1 = TestStruct {
name: "Hello world!".into(),
};
let ts2 = TestStruct {
name: "Isn't it lovely outside?".into(),
};
let ptr = AtomPtr::new(ts1);
let first = ptr.get_ref();
println!("Pointer: {:?}", *first);
let prev = ptr.compare_exchange(first, ts2);
if prev.is_success() {
println!("Successfully swapped pointer values!");
let second = ptr.get_ref();
println!("First: {:?}, Second: {:?}", *prev.inner(), *second);
}
}
#[test]
fn unsafe_mut_ptr() {
let p: AtomPtr<i32> = AtomPtr::new(5);
let p_diddy: &mut i32 = unsafe { p.inplace_mut() }.unwrap();
*p_diddy = 11;
let p2 = p.get_ref();
assert!(p2.take_copy() == 11);
}