use std::{
cell::RefCell,
ops::{Deref, DerefMut},
rc::Rc,
sync::{Arc, Mutex},
};
pub type RcCell<T> = Rc<RefCell<T>>;
pub type ArcMutex<T> = Arc<Mutex<T>>;
pub trait RefCount<T>: Sized + Clone {
type Ref<'r>: Deref<Target = T> + 'r
where
Self: 'r,
T: 'r;
type RefMut<'r>: DerefMut<Target = T> + 'r
where
Self: 'r,
T: 'r;
fn get_<'r, 's: 'r>(&'s self) -> Self::Ref<'r>;
fn mut_<'r, 's: 'r>(&'s mut self) -> Self::RefMut<'r>;
fn new_(t: T) -> Self;
fn n_strong_(&self) -> usize;
fn n_weak_(&self) -> usize;
fn clone_(&self) -> Self
where
T: Clone,
{
self.clone()
}
fn clone_inner(&self) -> T
where
T: Clone,
{
self.get_().clone()
}
fn ref_eq(&self, other: &Self) -> bool;
}
impl<T> RefCount<T> for RcCell<T> {
type Ref<'a> = std::cell::Ref<'a, T> where T: 'a;
type RefMut<'a> = std::cell::RefMut<'a, T> where T: 'a;
#[inline(always)]
fn get_<'r, 's: 'r>(&'s self) -> Self::Ref<'r> {
RefCell::borrow(self)
}
#[inline(always)]
fn mut_<'r, 's: 'r>(&'s mut self) -> Self::RefMut<'r> {
RefCell::borrow_mut(self)
}
#[inline(always)]
fn new_(t: T) -> Self {
Rc::new(RefCell::new(t))
}
#[inline(always)]
fn n_strong_(&self) -> usize {
Rc::strong_count(self)
}
#[inline(always)]
fn n_weak_(&self) -> usize {
Rc::weak_count(self)
}
#[inline(always)]
fn ref_eq(&self, other: &Self) -> bool {
Rc::ptr_eq(self, other)
}
}
impl<T> RefCount<T> for ArcMutex<T> {
type Ref<'a> = std::sync::MutexGuard<'a, T> where T: 'a;
type RefMut<'a> = std::sync::MutexGuard<'a, T> where T: 'a;
#[inline(always)]
fn get_<'r, 's: 'r>(&'s self) -> Self::Ref<'r> {
self.lock().expect("互斥锁已中毒")
}
#[inline(always)]
fn mut_<'r, 's: 'r>(&'s mut self) -> Self::RefMut<'r> {
self.lock().expect("互斥锁已中毒")
}
#[inline(always)]
fn new_(t: T) -> Self {
Arc::new(Mutex::new(t))
}
#[inline(always)]
fn n_strong_(&self) -> usize {
Arc::strong_count(self)
}
#[inline(always)]
fn n_weak_(&self) -> usize {
Arc::weak_count(self)
}
#[inline(always)]
fn ref_eq(&self, other: &Self) -> bool {
Arc::ptr_eq(self, other)
}
}
#[cfg(test)]
pub mod tests {
use super::*;
fn test_rc<R: std::fmt::Debug + RefCount<i32>>() {
let mut rc = R::new_(0);
dbg!(rc.clone_());
let mut r = rc.mut_();
*r += 1;
assert_eq!(*r, 1);
drop(r);
let rc2 = dbg!(rc.clone_());
let value = *rc.get_();
let value2 = *rc2.get_();
assert_eq!(value, value2);
}
#[test]
fn tests_ref_count() {
test_rc::<RcCell<i32>>();
test_rc::<ArcMutex<i32>>();
}
type R<T> = ArcMutex<T>;
#[derive(Debug, Clone)]
struct Task {
pub content: String,
parent: Option<R<Task>>,
}
impl Task {
pub fn new(content: impl Into<String>, parent_task: Option<&R<Task>>) -> Self {
Self {
content: content.into(),
parent: parent_task.map(R::clone),
}
}
pub fn new_rc(content: impl Into<String>, parent_task: Option<&R<Task>>) -> R<Self> {
R::new_(Self::new(content, parent_task))
}
pub fn parent(&self) -> Option<R<Task>> {
self.parent.clone()
}
pub fn set_parent(&mut self, parent: &R<Task>) -> &mut R<Task> {
self.parent.insert(parent.clone())
}
pub fn delete_parent(&mut self) -> Option<R<Task>> {
self.parent.take()
}
}
#[test]
fn test_set_parent() {
let task_i = Task::new_rc("input.", None);
let task_j = Task::new_rc("JnPut.", Some(&task_i));
let mut task_k = Task::new_rc("KnPut.", Some(&task_i));
task_k.mut_().set_parent(&task_j);
dbg!(task_i, task_j, task_k);
}
#[test]
fn test_recursive() {
let mut task_i = Task::new_rc("recursive.", None);
let task_i_self = task_i.clone();
task_i.mut_().set_parent(&task_i_self);
let parent = task_i.get_().parent().unwrap();
assert_eq!(parent.get_().content, "recursive.");
task_i.mut_().delete_parent(); dbg!(task_i.n_strong_(), task_i.n_weak_());
}
}