Advertisement
Guest User

Untitled

a guest
Jul 25th, 2017
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.19 KB | None | 0 0
  1. #include <memory> // std::unique_ptr
  2. #include <vector>
  3. using std::vector;
  4.  
  5. // abstract visitor
  6. struct visitor {
  7. virtual ~visitor(void) {};
  8. virtual void visit(struct realConstantNode &) = 0;
  9. virtual void visit(struct sinNode &) = 0;
  10. };
  11.  
  12. // node hierarchy
  13. struct node {
  14. node() {};
  15. virtual ~node(void) {};
  16. virtual void accept(visitor &) = 0;
  17. };
  18. struct terminalNode : public virtual node {
  19. };
  20. struct nonterminalNode : public virtual node {
  21. virtual void add_child(node* child) = 0;
  22. };
  23. struct unaryNode : public virtual nonterminalNode {
  24. std::unique_ptr<node> child;
  25. void add_child(node * child) {
  26. this->child = std::unique_ptr<node>(child);
  27. };
  28. };
  29.  
  30. // sample terminal node
  31. struct realConstantNode : public terminalNode {
  32. realConstantNode(double value) : value(value) {};
  33. double value;
  34. void accept(visitor & vis) {
  35. vis.visit(*this);
  36. };
  37. };
  38.  
  39. // sample nonterminal node
  40. struct sinNode : public unaryNode {
  41. void accept(visitor & vis) {
  42. vis.visit(*this);
  43. };
  44. };
  45.  
  46. // copy visitor
  47. template<typename copyNodeType>
  48. struct copyCreator : public visitor {
  49. copyCreator() {}
  50. copyCreator(node * firstVisit) {
  51. firstVisit->accept(*this);
  52. }
  53. ~copyCreator() {
  54. copy.reset();
  55. for(auto ptr : openList) {
  56. delete ptr;
  57. }
  58. }
  59.  
  60. std::unique_ptr<copyNodeType> copy = 0;
  61. vector<nonterminalNode *> openList;
  62. bool error = true;
  63.  
  64. // push to tree
  65. template<typename nodeType> // templated bc we want a specific handle, not
  66. bool push(nodeType * ptr) { // a generic node * that we need to cast!
  67. if (copy) {
  68. openList.back()->add_child(ptr); // if root is set, append to tree
  69. }
  70. else {
  71. //setCopy<nodeType>(ptr);
  72. auto temp = dynamic_cast<copyNodeType *>(ptr);
  73. if(temp) {
  74. copy = std::unique_ptr<copyNodeType>(temp);
  75. error = false;
  76. }
  77. else {
  78. /*
  79. Is there a nicer way to dispose of the newly created node `ptr`
  80. or `next` other than checking the return value and wrapping the
  81. entire visit method of all nodes in an if statement?
  82. */
  83. return false;
  84. }
  85. }
  86. return true;
  87. }
  88.  
  89. void visit(struct realConstantNode & nod) {
  90. auto next = new realConstantNode(nod.value);
  91. if(!push(next)) {
  92. delete next;
  93. }
  94. }
  95.  
  96. void visit(struct sinNode & nod) {
  97. auto next = new sinNode;
  98. if(push(next)) {
  99. openList.push_back(next);
  100. nod.child->accept(*this);
  101. openList.pop_back();
  102. }
  103. else {
  104. delete next;
  105. }
  106. };
  107. };
  108.  
  109. int main(int argc, const char * argv[]) {
  110.  
  111. sinNode s;
  112. auto pi = new realConstantNode(3.141);
  113. s.add_child(pi); // s.child now owns pi
  114.  
  115. // These three versions of calling the copyCreator are possible!
  116. copyCreator<sinNode> cpy0;
  117. s.accept(cpy0);
  118.  
  119. copyCreator<sinNode> cpy1;
  120. cpy1.visit(s);
  121.  
  122. copyCreator<sinNode> cpy2(&s);
  123.  
  124. // If we visit pi directly, we cannot create a copy of a sinNode!
  125. copyCreator<sinNode> cpy3(pi);
  126. return 0;
  127. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement