librust/r9/src/listhead.rs
2024-05-12 13:46:55 +08:00

97 lines
3.0 KiB
Rust

use std::rc::{Rc, Weak};
use std::cell::RefCell;
use std::ptr;
use r9_macro::SharedFromSelf;
use r9_macro_derive::SharedFromSelf;
#[derive(Default)]
#[derive(SharedFromSelf)]
pub struct ListHead<T> {
prev: Weak::<RefCell::<Self>>,
next: Weak::<RefCell::<Self>>,
data: Weak::<RefCell::<T>>,
_self_wp: Weak::<RefCell::<Self>>,
}
impl<T> ListHead<T> {
fn new(data: Weak::<RefCell::<T>>) -> Rc::<RefCell::<Self>> {
let this = Rc::new(RefCell::new(Self{
prev: Default::default(),
next: Default::default(),
data: data,
_self_wp: Default::default(),
}));
this.borrow_mut()._self_wp = Rc::downgrade(&this);
this.borrow_mut().init();
return this;
}
pub fn new_head() -> Rc::<RefCell::<Self>> {
return Self::new(Default::default());
}
pub fn new_node(data: Weak::<RefCell::<T>>) -> Rc::<RefCell::<Self>> {
return Self::new(data);
}
fn init(&mut self) {
self.prev = Rc::downgrade(&self.shared_from_self());
self.next = Rc::downgrade(&self.shared_from_self());
}
pub fn data(&self) -> Weak::<RefCell::<T>> {
return self.data.clone();
}
pub fn del_init(&mut self) {
self.next.upgrade().unwrap().borrow_mut().prev = self.prev.clone();
self.prev.upgrade().unwrap().borrow_mut().next = self.next.clone();
self.init();
}
pub fn empty(&self) -> bool {
return ptr::eq(self.next.as_ptr(), Rc::as_ptr(&self.shared_from_self()));
}
pub fn add_tail(head: &Rc::<RefCell::<Self>>, pnew: &Rc::<RefCell::<Self>>) {
let prev = &head.borrow_mut().prev.clone();
let next = head;
next.borrow_mut().prev = Rc::downgrade(pnew);
pnew.borrow_mut().next = Rc::downgrade(&next);
pnew.borrow_mut().prev = prev.clone();
prev.upgrade().unwrap().borrow_mut().next = Rc::downgrade(pnew);
}
pub fn first_entry(&self) -> Weak::<RefCell::<T>> {
if self.empty() {
panic!("");
}
return self.next.upgrade().unwrap().borrow().data();
}
pub fn replace_init(head: &Rc::<RefCell::<Self>>, pnew: &Rc::<RefCell::<Self>>) {
if head.borrow().empty() {
return;
}
pnew.borrow_mut().next = head.borrow().next.clone();
pnew.borrow_mut().next.upgrade().unwrap().borrow_mut().prev = Rc::downgrade(pnew);
pnew.borrow_mut().prev = head.borrow().prev.clone();
pnew.borrow_mut().prev.upgrade().unwrap().borrow_mut().next = Rc::downgrade(pnew);
head.borrow_mut().init();
}
pub fn for_each(&self, cb: fn (&Weak::<RefCell::<T>>) -> bool) {
let mut pos = self.next.clone();
let self_weak = Rc::downgrade(&self.shared_from_self());
while !Weak::ptr_eq(&pos, &self_weak) {
if !cb(&pos.upgrade().unwrap().borrow().data()) {
break;
}
pos = pos.upgrade().unwrap().borrow().next.clone();
}
}
}