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