fork(1) download
  1. #include <list>
  2. #include <typeinfo>
  3. #include <type_traits>
  4. #include <set>
  5. #include <utility>
  6.  
  7. #include <iostream>
  8.  
  9. //Warning, C++11 code ahead
  10. typedef std::set<std::string> _cendent_list;
  11.  
  12. // You can also extend this to include a list of non-family members
  13. // if you want to catch those.
  14. template <class Origin, class Relative>
  15. void find_relationship_helper3(_cendent_list&, _cendent_list& des, std::true_type)
  16. {
  17. des.insert(typeid(Relative).name());
  18. }
  19.  
  20. template <class Origin, class Relative>
  21. void find_relationship_helper3(_cendent_list&, _cendent_list&, std::false_type)
  22. {}
  23.  
  24. template <class Origin, class Relative>
  25. void find_relationship_helper2(_cendent_list& ante, _cendent_list&, std::true_type)
  26. {
  27. ante.insert(typeid(Relative).name());
  28. }
  29.  
  30. template <class Origin, class Relative>
  31. void find_relationship_helper2(_cendent_list& ante, _cendent_list& des, std::false_type)
  32. {
  33. find_relationship_helper3<Origin, Relative>
  34. (ante, des, typename std::is_base_of<Origin, Relative>::type());
  35. }
  36.  
  37. template <class Origin, class Relative>
  38. void find_relationship_helper(_cendent_list& ante, _cendent_list& des)
  39. {
  40. find_relationship_helper2<Origin, Relative>
  41. (ante, des, typename std::is_base_of<Relative, Origin>::type());
  42. }
  43.  
  44. template <class Origin, class Relative, class Relative2, class... FamilyPack>
  45. void find_relationship_helper(_cendent_list& ante, _cendent_list& des)
  46. {
  47. find_relationship_helper<Origin, Relative>(ante, des);
  48. find_relationship_helper<Origin, Relative2, FamilyPack...>(ante, des);
  49. }
  50.  
  51.  
  52. //Important function here
  53. template <class Origin, class... FamilyPack>
  54. std::pair<_cendent_list, _cendent_list> find_relationship()
  55. {
  56. _cendent_list ante, des;
  57. find_relationship_helper<Origin, FamilyPack...>(ante, des);
  58. return std::make_pair(ante, des);
  59. }
  60.  
  61. struct Parent{};
  62. struct Child : Parent{};
  63. struct Grandchild : Child{};
  64.  
  65. int main(){
  66. auto Parent_list = find_relationship<Parent, Child, Grandchild>();
  67. auto Child_list = find_relationship<Child, Parent, Grandchild>();
  68. auto Grandchild_list = find_relationship<Grandchild, Parent, Child>();
  69.  
  70. std::cout << "Parent:\n"
  71. << "\tAntecendents:\n";
  72. for(const auto& t : Parent_list.first)
  73. std::cout << "\t\t- " << t<< '\n';
  74. std::cout << "\tDescendents:\n";
  75. for(const auto& t : Parent_list.second)
  76. std::cout << "\t\t- " << t<< '\n';
  77. std::cout << std::endl;
  78.  
  79. std::cout << "Child:\n"
  80. << "\tAntecendents:\n";
  81. for(const auto& t : Child_list.first)
  82. std::cout << "\t\t- " << t<< '\n';
  83. std::cout << "\tDescendents:\n";
  84. for(const auto& t : Child_list.second)
  85. std::cout << "\t\t- " << t<< '\n';
  86. std::cout << std::endl;
  87.  
  88. std::cout << "Grandchild:\n"
  89. << "\tAntecendents:\n";
  90. for(const auto& t : Grandchild_list.first)
  91. std::cout << "\t\t- " << t<< '\n';
  92. std::cout << "\tDescendents:\n";
  93. for(const auto& t : Grandchild_list.second)
  94. std::cout << "\t\t- " << t << '\n';
  95.  
  96. return 0;
  97. }
  98.  
Success #stdin #stdout 0s 3436KB
stdin
Standard input is empty
stdout
Parent:
	Antecendents:
	Descendents:
		- 10Grandchild
		- 5Child

Child:
	Antecendents:
		- 6Parent
	Descendents:
		- 10Grandchild

Grandchild:
	Antecendents:
		- 5Child
		- 6Parent
	Descendents: