use crate::NodeRefContainer; use crate::context::{ BinaryTreeChildrenGetterContext, BinaryTreeChildrenSetterContext, BinaryTreeParentGetterContext, BinaryTreeParentSetterContext, }; use crate::directed::context::{ DirectedBinaryTreeChildrenGetterContext, DirectedBinaryTreeChildrenSetterContext, }; macro_rules! _mut_switch { ($macro:tt $excl_mark:tt ( $($args:tt)+) ) => { $macro$excl_mark($($args)+); $macro$excl_mark($($args)+ mut); }; } pub struct FixedLeftDirectedBinaryTreeContextFromContext { ctx: CtxRef, } pub struct FixedRightDirectedBinaryTreeContextFromContext { ctx: CtxRef, } macro_rules! _constructor { ($name:ident) => { impl<'ctx, Ctx: NodeRefContainer> $name <&'ctx Ctx> { pub fn wrap(ctx: &'ctx Ctx) -> Self { return Self { ctx }; } } }; ($name:ident mut) => { impl<'ctx, Ctx: NodeRefContainer> $name <&'ctx mut Ctx> { pub fn wrap_mut(ctx: &'ctx mut Ctx) -> Self { return Self { ctx }; } } }; } _mut_switch!(_constructor!(FixedLeftDirectedBinaryTreeContextFromContext)); _mut_switch!(_constructor!(FixedRightDirectedBinaryTreeContextFromContext)); macro_rules! _node_ref { ($name:ident $($mut:tt)?) => { impl NodeRefContainer for $name<& $($mut)? Ctx> { type NodeRef = Ctx::NodeRef; } }; } _mut_switch!(_node_ref!(FixedLeftDirectedBinaryTreeContextFromContext)); _mut_switch!(_node_ref!(FixedRightDirectedBinaryTreeContextFromContext)); macro_rules! _parent_get { ($name:ident $($mut:tt)?) => { impl BinaryTreeParentGetterContext for $name<& $($mut)? Ctx> { fn getParent(&self, node: Self::NodeRef) -> Option { return self.ctx.getParent(node); } } }; } _mut_switch!(_parent_get!(FixedLeftDirectedBinaryTreeContextFromContext)); _mut_switch!(_parent_get!(FixedRightDirectedBinaryTreeContextFromContext)); macro_rules! _children_get { ($name:ident $fwd:ident $op:ident $($mut:tt)? ) => { impl DirectedBinaryTreeChildrenGetterContext for $name <& $($mut)? Ctx> { fn getForwardChild(&self, node: Self::NodeRef) -> Option { return self.ctx.$fwd(node); } fn getOppositeChild(&self, node: Self::NodeRef) -> Option { return self.ctx.$op(node); } } }; } _mut_switch!(_children_get!(FixedLeftDirectedBinaryTreeContextFromContext getLeftChild getRightChild)); _mut_switch!(_children_get!(FixedRightDirectedBinaryTreeContextFromContext getRightChild getLeftChild)); macro_rules! _parent_set { ($name:ident) => { unsafe impl BinaryTreeParentSetterContext for $name <&mut Ctx> { fn xSetParent(&mut self, node: Self::NodeRef, newParent: Option) { self.ctx.xSetParent(node, newParent); } fn setParent(&mut self, node: Self::NodeRef, newParent: Self::NodeRef) { self.ctx.setParent(node, newParent); } fn clearParent(&mut self, node: Self::NodeRef) { self.ctx.clearParent(node) } } }; } _parent_set!(FixedLeftDirectedBinaryTreeContextFromContext); _parent_set!(FixedRightDirectedBinaryTreeContextFromContext); macro_rules! _children_set { ( $name:ident $fwd_xset:ident $fwd_set:ident $fwd_clear:ident $op_xset:ident $op_set:ident $op_clear:ident ) => { unsafe impl DirectedBinaryTreeChildrenSetterContext for $name<&mut Ctx> { fn xSetForwardChild(&mut self, node: Self::NodeRef, newChild: Option) { self.ctx.$fwd_xset(node, newChild) } fn xSetOppositeChild(&mut self, node: Self::NodeRef, newChild: Option) { self.ctx.$op_xset(node, newChild) } fn setForwardChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { self.ctx.$fwd_set(node, newChild) } fn setOppositeChild(&mut self, node: Self::NodeRef, newChild: Self::NodeRef) { self.ctx.$op_set(node, newChild) } fn clearForwardChild(&mut self, node: Self::NodeRef) { self.ctx.$fwd_clear(node) } fn clearOppositeChild(&mut self, node: Self::NodeRef) { self.ctx.$op_clear(node) } } }; } _children_set!( FixedLeftDirectedBinaryTreeContextFromContext xSetLeftChild setLeftChild clearLeftChild xSetRightChild setRightChild clearRightChild ); _children_set!( FixedRightDirectedBinaryTreeContextFromContext xSetRightChild setRightChild clearRightChild xSetLeftChild setLeftChild clearLeftChild );