r9/src/listhead.rs
aozhiwei b246bd745a 1
2023-10-07 20:58:22 +08:00

99 lines
3.3 KiB
Rust

use std::rc::{Rc, Weak};
use std::cell::RefCell;
pub struct ListHead<T> {
prev: Weak::<RefCell::<ListHead<T>>>,
next: Weak::<RefCell::<ListHead<T>>>,
data: Weak::<RefCell::<T>>,
}
impl<T> ListHead<T> {
pub fn new_head() -> Rc::<RefCell::<ListHead<T>>> {
let this = Rc::new(RefCell::new(ListHead{
prev: Weak::<RefCell::<ListHead<T>>>::new(),
next: Weak::<RefCell::<ListHead<T>>>::new(),
data: Weak::<RefCell::<T>>::new()
}));
this.borrow_mut().init();
return this;
}
pub fn new_node(data: Weak::<RefCell::<T>>) -> Rc::<RefCell::<ListHead<T>>> {
let this = Rc::new(RefCell::new(ListHead{
prev: Weak::<RefCell::<ListHead<T>>>::new(),
next: Weak::<RefCell::<ListHead<T>>>::new(),
data: data
}));
this.borrow_mut().init();
return this;
}
fn get_rc_refcell(&self) -> Rc::<RefCell::<ListHead<T>>> {
let cell_rc: &Rc<RefCell<ListHead<T>>> = &self.next.upgrade().unwrap();
let head: &ListHead<T> = &*cell_rc.borrow();
let cell_start = cell_rc.as_ptr() as *const u8;
let data_start = head as *const ListHead<T> as *const u8;
let cell_offset = unsafe { data_start.offset_from(cell_start) };
unsafe {
return Rc::from_raw(cell_start as *const RefCell::<ListHead<T>>);
};
}
fn init(&mut self) {
self.prev = Rc::downgrade(&self.get_rc_refcell());
self.next = Rc::downgrade(&self.get_rc_refcell());
}
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 self as *const ListHead<T> == self.next.upgrade().unwrap().as_ptr();
}
pub fn add_tail(head: &mut Rc::<RefCell::<ListHead<T>>>,
pnew: &mut Rc::<RefCell::<ListHead<T>>>) {
let prev = &mut head.borrow_mut().prev;
let next = Rc::downgrade(head);
next.upgrade().unwrap().borrow_mut().prev = Rc::downgrade(pnew);
pnew.borrow_mut().next = 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() {
}
return self.next.upgrade().unwrap().borrow().data();
}
pub fn replace_init(head: &mut Rc::<RefCell::<ListHead<T>>>,
pnew: &mut Rc::<RefCell::<ListHead<T>>>) {
pnew.borrow_mut().next = head.borrow_mut().next.clone();
pnew.borrow_mut().next.upgrade().unwrap().borrow_mut().prev = Rc::downgrade(pnew);
pnew.borrow_mut().prev = head.borrow_mut().prev.clone();
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.get_rc_refcell());
while !Weak::ptr_eq(&pos, self_weak) {
if !cb(&pos.upgrade().unwrap().borrow().data()) {
break;
}
pos = pos.upgrade().unwrap().borrow().next.clone();
}
}
}