Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.40 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <memory>
  4. #include <cassert>
  5.  
  6. struct Visitor;
  7.  
  8. struct Common
  9. {
  10. virtual void apply(const Visitor&) = 0;
  11. virtual void apply(const Visitor&) const = 0;
  12. virtual void apply(Visitor&) = 0;
  13. virtual void apply(Visitor&) const = 0;
  14. virtual ~Common() = default;
  15. };
  16.  
  17. struct Left : Common
  18. {
  19. virtual void doLeft() const = 0;
  20. };
  21.  
  22. struct Right : Common
  23. {
  24. virtual void doRight() const = 0;
  25. };
  26.  
  27. struct A : Left, Right
  28. {
  29. void apply(const Visitor& v) override;
  30. void apply(const Visitor& v) const override;
  31. void apply(Visitor& v) override;
  32. void apply(Visitor& v) const override;
  33.  
  34. void doLeft() const override
  35. {
  36. std::cout << "A::doLeft" << std::endl;
  37. }
  38. void doRight() const override
  39. {
  40. std::cout << "A::doRight" << std::endl;
  41. }
  42.  
  43. std::string inAonly() const { return "class A"; }
  44. };
  45.  
  46. struct B : Left
  47. {
  48. void apply(const Visitor& v) override;
  49. void apply(const Visitor& v) const override;
  50. void apply(Visitor& v) override;
  51. void apply(Visitor& v) const override;
  52.  
  53. void doLeft() const override
  54. {
  55. std::cout << "B::doLeft" << std::endl;
  56. }
  57.  
  58. std::string inBonly() const { return "class B"; }
  59. };
  60.  
  61. struct C : Right, Left
  62. {
  63. void apply(const Visitor& v) override;
  64. void apply(const Visitor& v) const override;
  65. void apply(Visitor& v) override;
  66. void apply(Visitor& v) const override;
  67.  
  68. void doLeft() const override
  69. {
  70. std::cout << "C::doLeft" << std::endl;
  71. }
  72. void doRight() const override
  73. {
  74. std::cout << "C::doRight" << std::endl;
  75. }
  76.  
  77. std::string inConly() const { return "class C"; }
  78. };
  79.  
  80. struct D : Right
  81. {
  82. void apply(const Visitor& v) override;
  83. void apply(const Visitor& v) const override;
  84. void apply(Visitor& v) override;
  85. void apply(Visitor& v) const override;
  86.  
  87. void doRight() const override
  88. {
  89. std::cout << "D::doRight" << std::endl;
  90. }
  91.  
  92. std::string inDonly() const { return "class D"; }
  93. };
  94.  
  95. struct Visitor
  96. {
  97. virtual void visit(const Left&) const
  98. {
  99. assert(!"If the method is called it means it had to be overrided");
  100. }
  101. virtual void visit(Left& o) const
  102. {
  103. visit(static_cast<const Left&>(o));
  104. }
  105.  
  106. virtual void visit(const Right&) const
  107. {
  108. assert(!"If the method is called it means it had to be overrided");
  109. }
  110. virtual void visit(Right& o) const
  111. {
  112. visit(static_cast<const Right&>(o));
  113. }
  114.  
  115. // Left siblings
  116. virtual void visit(const A& o) const
  117. {
  118. visit(static_cast<const Left&>(o));
  119. }
  120. virtual void visit(A& o) const
  121. {
  122. visit(static_cast<Left&>(o));
  123. }
  124. virtual void visit(const B& o) const
  125. {
  126. visit(static_cast<const Left&>(o));
  127. }
  128. virtual void visit(B& o) const
  129. {
  130. visit(static_cast<Left&>(o));
  131. }
  132.  
  133. // Right siblings
  134. virtual void visit(const C& o) const
  135. {
  136. visit(static_cast<const Right&>(o));
  137. }
  138. virtual void visit(C& o) const
  139. {
  140. visit(static_cast<Right&>(o));
  141. }
  142. virtual void visit(const D& o) const
  143. {
  144. visit(static_cast<const Right&>(o));
  145. }
  146. virtual void visit(D& o) const
  147. {
  148. visit(static_cast<Right&>(o));
  149. }
  150.  
  151. virtual ~Visitor() = 0;
  152. };
  153.  
  154. // impl
  155. inline Visitor::~Visitor() = default;
  156.  
  157. void A::apply(const Visitor& v)
  158. {
  159. v.visit(*this);
  160. }
  161. void A::apply(const Visitor& v) const
  162. {
  163. v.visit(*this);
  164. }
  165. void A::apply(Visitor& v)
  166. {
  167. v.visit(*this);
  168. }
  169. void A::apply(Visitor& v) const
  170. {
  171. v.visit(*this);
  172. }
  173. void B::apply(const Visitor& v)
  174. {
  175. v.visit(*this);
  176. }
  177. void B::apply(const Visitor& v) const
  178. {
  179. v.visit(*this);
  180. }
  181. void B::apply(Visitor& v)
  182. {
  183. v.visit(*this);
  184. }
  185. void B::apply(Visitor& v) const
  186. {
  187. v.visit(*this);
  188. }
  189. void C::apply(const Visitor& v)
  190. {
  191. v.visit(*this);
  192. }
  193. void C::apply(const Visitor& v) const
  194. {
  195. v.visit(*this);
  196. }
  197. void C::apply(Visitor& v)
  198. {
  199. v.visit(*this);
  200. }
  201. void C::apply(Visitor& v) const
  202. {
  203. v.visit(*this);
  204. }
  205. void D::apply(const Visitor& v)
  206. {
  207. v.visit(*this);
  208. }
  209. void D::apply(const Visitor& v) const
  210. {
  211. v.visit(*this);
  212. }
  213. void D::apply(Visitor& v)
  214. {
  215. v.visit(*this);
  216. }
  217. void D::apply(Visitor& v) const
  218. {
  219. v.visit(*this);
  220. }
  221.  
  222. struct MyVisitor : Visitor
  223. {
  224. /// @todo const specific class references don't have priority
  225. void visit(A& o) const override
  226. {
  227. std::cout << o.inAonly() << std::endl;
  228. }
  229. void visit(B& o) const override
  230. {
  231. std::cout << o.inBonly() << std::endl;
  232. }
  233. void visit(C& o) const override
  234. {
  235. std::cout << o.inConly() << std::endl;
  236. }
  237. void visit(D& o) const override
  238. {
  239. std::cout << o.inDonly() << std::endl;
  240. }
  241. };
  242.  
  243. int main(int argc, char* argv[])
  244. {
  245. using namespace std;
  246.  
  247. vector<shared_ptr<Left>> lvec;
  248. vector<shared_ptr<Right>> rvec;
  249.  
  250. // somewhere in depth of factory
  251. {
  252. {
  253. auto p = make_shared<A>();
  254. lvec.push_back(p);
  255. rvec.push_back(p);
  256. }
  257.  
  258. {
  259. auto p = make_shared<B>();
  260. lvec.push_back(p);
  261. }
  262.  
  263. {
  264. auto p = make_shared<C>();
  265. lvec.push_back(p);
  266. rvec.push_back(p);
  267. }
  268.  
  269. {
  270. auto p = make_shared<D>();
  271. rvec.push_back(p);
  272. }
  273. }
  274.  
  275. MyVisitor v;
  276.  
  277. for (auto& p : lvec)
  278. {
  279. assert(p);
  280. p->doLeft();
  281. p->apply(v);
  282. }
  283.  
  284. for (auto& p : rvec)
  285. {
  286. assert(p);
  287. p->doRight();
  288. p->apply(v);
  289. }
  290.  
  291. return 0;
  292. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement