use std::rc::{Rc, Weak}; use std::cell::RefCell; use r9_macro::SharedFromSelf; use r9_macro_derive::SharedFromSelf; #[derive(Default)] #[derive(SharedFromSelf)] pub struct ListHead { prev: Weak::>>, next: Weak::>>, data: Weak::>, _self_wp: Weak::>>, } impl ListHead { fn new(data: Weak::>) -> Rc::> { let this = Rc::new(RefCell::new(ListHead{ 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::> { return Self::new(Default::default()); } pub fn new_node(data: Weak::>) -> Rc::> { 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::> { 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.next.ptr_eq(&self.prev); } pub fn add_tail(&self, pnew: &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: &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.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(); } } }