#include <list>
#include <typeinfo>
#include <type_traits>
#include <set>
#include <utility>
#include <iostream>
//Warning, C++11 code ahead
typedef std::set<std::string> _cendent_list;
// You can also extend this to include a list of non-family members
// if you want to catch those.
template <class Origin, class Relative>
void find_relationship_helper3(_cendent_list&, _cendent_list& des, std::true_type)
{
des.insert(typeid(Relative).name());
}
template <class Origin, class Relative>
void find_relationship_helper3(_cendent_list&, _cendent_list&, std::false_type)
{}
template <class Origin, class Relative>
void find_relationship_helper2(_cendent_list& ante, _cendent_list&, std::true_type)
{
ante.insert(typeid(Relative).name());
}
template <class Origin, class Relative>
void find_relationship_helper2(_cendent_list& ante, _cendent_list& des, std::false_type)
{
find_relationship_helper3<Origin, Relative>
(ante, des, typename std::is_base_of<Origin, Relative>::type());
}
template <class Origin, class Relative>
void find_relationship_helper(_cendent_list& ante, _cendent_list& des)
{
find_relationship_helper2<Origin, Relative>
(ante, des, typename std::is_base_of<Relative, Origin>::type());
}
template <class Origin, class Relative, class Relative2, class... FamilyPack>
void find_relationship_helper(_cendent_list& ante, _cendent_list& des)
{
find_relationship_helper<Origin, Relative>(ante, des);
find_relationship_helper<Origin, Relative2, FamilyPack...>(ante, des);
}
//Important function here
template <class Origin, class... FamilyPack>
std::pair<_cendent_list, _cendent_list> find_relationship()
{
_cendent_list ante, des;
find_relationship_helper<Origin, FamilyPack...>(ante, des);
return std::make_pair(ante, des);
}
struct Parent{};
struct Child : Parent{};
struct Grandchild : Child{};
int main(){
auto Parent_list = find_relationship<Parent, Child, Grandchild>();
auto Child_list = find_relationship<Child, Parent, Grandchild>();
auto Grandchild_list = find_relationship<Grandchild, Parent, Child>();
std::cout << "Parent:\n"
<< "\tAntecendents:\n";
for(const auto& t : Parent_list.first)
std::cout << "\t\t- " << t<< '\n';
std::cout << "\tDescendents:\n";
for(const auto& t : Parent_list.second)
std::cout << "\t\t- " << t<< '\n';
std::cout << std::endl;
std::cout << "Child:\n"
<< "\tAntecendents:\n";
for(const auto& t : Child_list.first)
std::cout << "\t\t- " << t<< '\n';
std::cout << "\tDescendents:\n";
for(const auto& t : Child_list.second)
std::cout << "\t\t- " << t<< '\n';
std::cout << std::endl;
std::cout << "Grandchild:\n"
<< "\tAntecendents:\n";
for(const auto& t : Grandchild_list.first)
std::cout << "\t\t- " << t<< '\n';
std::cout << "\tDescendents:\n";
for(const auto& t : Grandchild_list.second)
std::cout << "\t\t- " << t << '\n';
return 0;
}
I2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx0eXBlaW5mbz4KI2luY2x1ZGUgPHR5cGVfdHJhaXRzPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8dXRpbGl0eT4KCiNpbmNsdWRlIDxpb3N0cmVhbT4KCi8vV2FybmluZywgQysrMTEgY29kZSBhaGVhZAp0eXBlZGVmIHN0ZDo6c2V0PHN0ZDo6c3RyaW5nPiBfY2VuZGVudF9saXN0OwoKLy8gWW91IGNhbiBhbHNvIGV4dGVuZCB0aGlzIHRvIGluY2x1ZGUgYSBsaXN0IG9mIG5vbi1mYW1pbHkgbWVtYmVycwovLyAgICAgaWYgeW91IHdhbnQgdG8gY2F0Y2ggdGhvc2UuCnRlbXBsYXRlIDxjbGFzcyBPcmlnaW4sIGNsYXNzIFJlbGF0aXZlPgp2b2lkIGZpbmRfcmVsYXRpb25zaGlwX2hlbHBlcjMoX2NlbmRlbnRfbGlzdCYsIF9jZW5kZW50X2xpc3QmIGRlcywgc3RkOjp0cnVlX3R5cGUpCnsKICAgIGRlcy5pbnNlcnQodHlwZWlkKFJlbGF0aXZlKS5uYW1lKCkpOwp9Cgp0ZW1wbGF0ZSA8Y2xhc3MgT3JpZ2luLCBjbGFzcyBSZWxhdGl2ZT4Kdm9pZCBmaW5kX3JlbGF0aW9uc2hpcF9oZWxwZXIzKF9jZW5kZW50X2xpc3QmLCBfY2VuZGVudF9saXN0Jiwgc3RkOjpmYWxzZV90eXBlKQp7fQoKdGVtcGxhdGUgPGNsYXNzIE9yaWdpbiwgY2xhc3MgUmVsYXRpdmU+CnZvaWQgZmluZF9yZWxhdGlvbnNoaXBfaGVscGVyMihfY2VuZGVudF9saXN0JiBhbnRlLCBfY2VuZGVudF9saXN0Jiwgc3RkOjp0cnVlX3R5cGUpCnsKICAgIGFudGUuaW5zZXJ0KHR5cGVpZChSZWxhdGl2ZSkubmFtZSgpKTsKfQoKdGVtcGxhdGUgPGNsYXNzIE9yaWdpbiwgY2xhc3MgUmVsYXRpdmU+CnZvaWQgZmluZF9yZWxhdGlvbnNoaXBfaGVscGVyMihfY2VuZGVudF9saXN0JiBhbnRlLCBfY2VuZGVudF9saXN0JiBkZXMsIHN0ZDo6ZmFsc2VfdHlwZSkKewogICAgZmluZF9yZWxhdGlvbnNoaXBfaGVscGVyMzxPcmlnaW4sIFJlbGF0aXZlPgogICAgICAgIChhbnRlLCBkZXMsIHR5cGVuYW1lIHN0ZDo6aXNfYmFzZV9vZjxPcmlnaW4sIFJlbGF0aXZlPjo6dHlwZSgpKTsKfQoKdGVtcGxhdGUgPGNsYXNzIE9yaWdpbiwgY2xhc3MgUmVsYXRpdmU+CnZvaWQgZmluZF9yZWxhdGlvbnNoaXBfaGVscGVyKF9jZW5kZW50X2xpc3QmIGFudGUsIF9jZW5kZW50X2xpc3QmIGRlcykKewogICAgZmluZF9yZWxhdGlvbnNoaXBfaGVscGVyMjxPcmlnaW4sIFJlbGF0aXZlPgogICAgICAgIChhbnRlLCBkZXMsIHR5cGVuYW1lIHN0ZDo6aXNfYmFzZV9vZjxSZWxhdGl2ZSwgT3JpZ2luPjo6dHlwZSgpKTsKfQoKdGVtcGxhdGUgPGNsYXNzIE9yaWdpbiwgY2xhc3MgUmVsYXRpdmUsIGNsYXNzIFJlbGF0aXZlMiwgY2xhc3MuLi4gRmFtaWx5UGFjaz4Kdm9pZCBmaW5kX3JlbGF0aW9uc2hpcF9oZWxwZXIoX2NlbmRlbnRfbGlzdCYgYW50ZSwgX2NlbmRlbnRfbGlzdCYgZGVzKQp7CiAgICBmaW5kX3JlbGF0aW9uc2hpcF9oZWxwZXI8T3JpZ2luLCBSZWxhdGl2ZT4oYW50ZSwgZGVzKTsKICAgIGZpbmRfcmVsYXRpb25zaGlwX2hlbHBlcjxPcmlnaW4sIFJlbGF0aXZlMiwgRmFtaWx5UGFjay4uLj4oYW50ZSwgZGVzKTsKfQoKCi8vSW1wb3J0YW50IGZ1bmN0aW9uIGhlcmUKdGVtcGxhdGUgPGNsYXNzIE9yaWdpbiwgY2xhc3MuLi4gRmFtaWx5UGFjaz4Kc3RkOjpwYWlyPF9jZW5kZW50X2xpc3QsIF9jZW5kZW50X2xpc3Q+IGZpbmRfcmVsYXRpb25zaGlwKCkKewogICAgX2NlbmRlbnRfbGlzdCBhbnRlLCBkZXM7CiAgICBmaW5kX3JlbGF0aW9uc2hpcF9oZWxwZXI8T3JpZ2luLCBGYW1pbHlQYWNrLi4uPihhbnRlLCBkZXMpOwogICAgcmV0dXJuIHN0ZDo6bWFrZV9wYWlyKGFudGUsIGRlcyk7Cn0KCnN0cnVjdCBQYXJlbnR7fTsKc3RydWN0IENoaWxkIDogUGFyZW50e307CnN0cnVjdCBHcmFuZGNoaWxkIDogQ2hpbGR7fTsKCmludCBtYWluKCl7CglhdXRvIFBhcmVudF9saXN0ID0gZmluZF9yZWxhdGlvbnNoaXA8UGFyZW50LCBDaGlsZCwgR3JhbmRjaGlsZD4oKTsKCWF1dG8gQ2hpbGRfbGlzdCA9IGZpbmRfcmVsYXRpb25zaGlwPENoaWxkLCBQYXJlbnQsIEdyYW5kY2hpbGQ+KCk7CglhdXRvIEdyYW5kY2hpbGRfbGlzdCA9IGZpbmRfcmVsYXRpb25zaGlwPEdyYW5kY2hpbGQsIFBhcmVudCwgQ2hpbGQ+KCk7CgkKCXN0ZDo6Y291dCA8PCAiUGFyZW50OlxuIgoJCTw8ICJcdEFudGVjZW5kZW50czpcbiI7Cglmb3IoY29uc3QgYXV0byYgdCA6IFBhcmVudF9saXN0LmZpcnN0KQoJICAgIHN0ZDo6Y291dCA8PCAiXHRcdC0gIiA8PCB0PDwgJ1xuJzsKICAgIHN0ZDo6Y291dCA8PCAiXHREZXNjZW5kZW50czpcbiI7Cglmb3IoY29uc3QgYXV0byYgdCA6IFBhcmVudF9saXN0LnNlY29uZCkKCSAgICBzdGQ6OmNvdXQgPDwgIlx0XHQtICIgPDwgdDw8ICdcbic7CiAgICBzdGQ6OmNvdXQgPDwgc3RkOjplbmRsOwoJICAgIAoJc3RkOjpjb3V0IDw8ICJDaGlsZDpcbiIKCQk8PCAiXHRBbnRlY2VuZGVudHM6XG4iOwoJZm9yKGNvbnN0IGF1dG8mIHQgOiBDaGlsZF9saXN0LmZpcnN0KQoJICAgIHN0ZDo6Y291dCA8PCAiXHRcdC0gIiA8PCB0PDwgJ1xuJzsKICAgIHN0ZDo6Y291dCA8PCAiXHREZXNjZW5kZW50czpcbiI7Cglmb3IoY29uc3QgYXV0byYgdCA6IENoaWxkX2xpc3Quc2Vjb25kKQoJICAgIHN0ZDo6Y291dCA8PCAiXHRcdC0gIiA8PCB0PDwgJ1xuJzsKICAgIHN0ZDo6Y291dCA8PCBzdGQ6OmVuZGw7CgkgICAgCglzdGQ6OmNvdXQgPDwgIkdyYW5kY2hpbGQ6XG4iCgkJPDwgIlx0QW50ZWNlbmRlbnRzOlxuIjsKCWZvcihjb25zdCBhdXRvJiB0IDogR3JhbmRjaGlsZF9saXN0LmZpcnN0KQoJICAgIHN0ZDo6Y291dCA8PCAiXHRcdC0gIiA8PCB0PDwgJ1xuJzsKICAgIHN0ZDo6Y291dCA8PCAiXHREZXNjZW5kZW50czpcbiI7Cglmb3IoY29uc3QgYXV0byYgdCA6IEdyYW5kY2hpbGRfbGlzdC5zZWNvbmQpCgkgICAgc3RkOjpjb3V0IDw8ICJcdFx0LSAiIDw8IHQgPDwgJ1xuJzsKCQoJcmV0dXJuIDA7Cn0K