Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #[derive(Debug)]
- struct Node<T> where T: Debug, T: Default {
- prev: Option<Rc<RefCell<Node<T>>>>,
- next: Option<Rc<RefCell<Node<T>>>>,
- value: T,
- }
- impl<T> Node<T> where T: Debug, T: Default {
- /// Create a self-linked node: prev == this, next == this.
- fn new(value: T) -> Rc<RefCell<Self>> {
- let node = Rc::new(RefCell::new(Self { prev: None, next: None, value }));
- {
- let mut n = node.borrow_mut();
- n.prev = Some(Rc::clone(&node));
- n.next = Some(Rc::clone(&node));
- }
- node
- }
- /// Splice a new node *after* `this` in the circular ring; returns the new node.
- fn add_next(this: &Rc<RefCell<Node<T>>>, value: T) -> Rc<RefCell<Node<T>>> {
- let new = Node::new(value); // self-linked; we’ll rewire below
- // Current successor of `this`
- let next = {
- let t = this.borrow();
- t.next.as_ref().expect("ring invariant").clone()
- };
- // Rewire: this <-> new <-> next
- {
- let mut nb = new.borrow_mut();
- nb.prev = Some(Rc::clone(this));
- nb.next = Some(Rc::clone(&next));
- }
- this.borrow_mut().next = Some(Rc::clone(&new));
- next.borrow_mut().prev = Some(Rc::clone(&new));
- new
- }
- pub fn remove(node: Rc<RefCell<Self>>) -> (Option<Rc<RefCell<Self>>>, Self) {
- // Snapshot neighbors
- let (prev, next) = {
- let n = node.borrow();
- (
- n.prev.as_ref().expect("prev").clone(),
- n.next.as_ref().expect("next").clone(),
- )
- };
- let singleton = Rc::ptr_eq(&prev, &node) && Rc::ptr_eq(&next, &node);
- if !singleton {
- // Rewire neighbors
- {
- let mut pb = prev.borrow_mut();
- pb.next = Some(Rc::clone(&next));
- }
- {
- let mut nb = next.borrow_mut();
- nb.prev = Some(Rc::clone(&prev));
- }
- }
- // Break this node's own links
- {
- let mut n = node.borrow_mut();
- n.prev = None;
- n.next = None;
- }
- // Determine return-next *before* any potential drops.
- let ret_next = if singleton { None } else { Some(Rc::clone(&next)) };
- // In the singleton case, our local `prev`/`next` are extra strong refs to `node`.
- // Drop them so Rc::try_unwrap sees a strong count of 1.
- if singleton {
- drop(prev);
- drop(next);
- }
- let owned = Rc::try_unwrap(node)
- .ok()
- .expect("Node::remove: other strong Rc clones exist")
- .into_inner();
- (ret_next, owned)
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment