fork(1) download
  1. #include <tuple>
  2. #include <string>
  3.  
  4. template <typename... Ts>
  5. class Relations;
  6.  
  7. namespace std
  8. {
  9. template <std::size_t I, typename... Ts>
  10. auto get(Relations<Ts...>& r)
  11. -> typename std::tuple_element<I, std::tuple<Ts...>>::type&;
  12. }
  13.  
  14. template <typename A1, typename A2, size_t ind1, size_t ind2>
  15. class Association
  16. {
  17. public:
  18. virtual ~Association()
  19. {
  20. if (!this->empty())
  21. {
  22. this->clear_associations();
  23. }
  24. }
  25.  
  26. void associate(A2* ref)
  27. {
  28. if (!this->empty() && _ref == ref)
  29. {
  30. return;
  31. }
  32.  
  33. if (_ref)
  34. {
  35. std::get<ind2>(*_ref).reset_association();
  36. }
  37.  
  38. _ref = ref;
  39. std::get<ind2>(*ref).associate(static_cast<A1*>(this));
  40. };
  41.  
  42. void associate(A2& ref)
  43. {
  44. this->associate(&ref);
  45. };
  46.  
  47. bool empty() const
  48. {
  49. if (!_ref)
  50. return true;
  51. else
  52. return false;
  53. }
  54.  
  55. void remove_association(A2* ref)
  56. {
  57. if (_ref == ref)
  58. {
  59. this->reset_association();
  60. std::get<ind2>(*ref).remove_association(static_cast<A1*>(this));
  61. }
  62. }
  63.  
  64. void remove_association(A2& ref)
  65. {
  66. this->remove_association(&ref);
  67. }
  68.  
  69. void reset_association()
  70. {
  71. _ref = 0;
  72. }
  73.  
  74. void clear_associations()
  75. {
  76. if (_ref)
  77. {
  78. std::get<ind2>(*_ref).remove_association(static_cast<A1*>(this));
  79. }
  80. this->reset_association();
  81. }
  82.  
  83. A2* get_association() const
  84. {
  85. return _ref;
  86. }
  87.  
  88. private:
  89. A2* _ref=0;
  90. };
  91.  
  92. template <typename... Ts>
  93. class Relations : public Ts...
  94. {
  95. public:
  96. Relations() {}
  97. virtual ~Relations() {}
  98. };
  99.  
  100. namespace std
  101. {
  102. template <std::size_t I, typename... Ts>
  103. auto get(Relations<Ts...>& r)
  104. -> typename std::tuple_element<I, std::tuple<Ts...>>::type&
  105. {
  106. return static_cast<typename std::tuple_element<I, std::tuple<Ts...>>::type&>(r);
  107. }
  108. }
  109.  
  110. class J;
  111. class K;
  112.  
  113. class I : public Relations<Association<I, J, 0, 0>, Association<I, K, 1, 0>>
  114. {
  115. public:
  116. std::string type="I";
  117. };
  118.  
  119. class J : public Relations<Association<J, I, 0, 0>>
  120. {
  121. public:
  122. std::string type="J";
  123. };
  124.  
  125. class K : public Relations<Association<K, I, 0, 1>>
  126. {
  127. public:
  128. std::string type="K";
  129. };
  130.  
  131. int main()
  132. {
  133. I i;
  134. J j;
  135. K k;
  136. std::get<0>(i).associate(j);
  137.  
  138. return 0;
  139. }
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
Standard output is empty