Skip to content

Instantly share code, notes, and snippets.

@fowlmouth
Created January 26, 2017 20:24
Show Gist options
  • Save fowlmouth/ea7d36631403e5fdf1d47b84ecae51e0 to your computer and use it in GitHub Desktop.
Save fowlmouth/ea7d36631403e5fdf1d47b84ecae51e0 to your computer and use it in GitHub Desktop.
#pragma once
#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <algorithm>
#include <type_traits>
#include <cstdlib>
#include <cxxabi.h>
namespace fowl
{
std::string demangle(const char* mangled)
{
int status;
std::unique_ptr<char[], void (*)(void*)> result(
abi::__cxa_demangle(mangled, 0, 0, &status), std::free);
return result.get() ? std::string(result.get()) : "error occurred";
}
struct TypeInfo;
struct BaseTypeSet
{
std::string name;
const std::vector<const TypeInfo*>& members;
};
struct TypeInfo
{
std::string name;
const std::type_info& id;
std::vector<BaseTypeSet*> member_of;
};
template<typename T>
static TypeInfo* get_info()
{
static TypeInfo info{ demangle(typeid(T).name()), typeid(T), {} };
return &info;
}
template<typename Tag>
struct TypeSet: BaseTypeSet
{
static TypeSet<Tag> self;
static std::vector<const TypeInfo*> members;
TypeSet()
: BaseTypeSet{ demangle(typeid(TypeSet).name()), TypeSet<Tag>::members }
{}
static const int num_types() { return members.size(); }
private:
template<typename T>
static inline int next_id()
{
TypeInfo* t = get_info<T>();
members.push_back(t);
t->member_of.push_back(&self);
return members.size()-1;
}
public:
template<typename T>
static const int get_id()
{
static const int id = next_id<T>();
return id;
}
static const int get_id(const TypeInfo* type)
{
auto item = std::find( members.begin(), members.end(), type);
if(type != members.end())
return item - members.begin();
return -1;
}
static const TypeInfo* get_type(std::size_t ID)
{
return members.at(ID);
}
};
template<typename Tag> TypeSet<Tag> TypeSet<Tag>::self;
template<typename Tag> std::vector<const TypeInfo*> TypeSet<Tag>::members{};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment