Skip to content

Instantly share code, notes, and snippets.

@klmr
Created May 16, 2012 14:55
Show Gist options
  • Save klmr/2710960 to your computer and use it in GitHub Desktop.
Save klmr/2710960 to your computer and use it in GitHub Desktop.
Runtime type information registry with C++
#include <typeinfo>
#include <iostream>
#include <vector>
#include <stdexcept>
#include <unordered_map>
struct Type {
std::string name;
std::vector<Type*> parents;
// TODO Extend by fully-qualified name (namespace) etc.
template <typename... T>
Type(std::string&& name, T*... parents)
: name(name), parents{parents...} { }
};
std::ostream& operator <<(std::ostream& out, Type const& type) {
return out << type.name;
}
struct unknown_type_error : std::runtime_error {
unknown_type_error(char const* what)
: std::runtime_error(what) { }
};
struct TypeInfo {
template <typename T>
static Type const& get(T const&) {
return get(typeid(T));
}
template <typename T>
static Type const& get() {
return get(typeid(T));
}
static Type const& get(std::type_info const& info) {
auto i = types.find(info);
if (i == types.end())
throw unknown_type_error(info.name());
return i->second;
}
template <typename T>
static void register_type(Type&& type) {
types.insert(std::make_pair(typeid(T), type));
}
typedef std::unordered_map<std::type_info, Type> type_dir_t;
static type_dir_t types;
};
TypeInfo::type_dir_t TypeInfo::types;
////////////////////////////////////////
struct X { };
struct Y : X { };
TypeInfo::register_type<int>(Type("int"));
TypeInfo::register_type<X>(Type("X"));
TypeInfo::register_type<Y>(Type("Y", &TypeInfo::get<X>()));
int main() {
std::cout << TypeInfo::get<Y>() << "\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment