struct message { /*typeinfo*/ type; void* ptr; }; void accept_message(const message& m) { if (m.type == /* some class */) { // do stuff } else { // do } }
namespace type { extern std::atomic<uint32_t> type_counter; struct info { uint32_t id; bool operator== (const info& other) const {return id == other.id;} bool operator!= (const info& other) const {return id != other.id;} }; template <class ValueType> const info& get_type() { static info info = {std::atomic_fetch_add(&type_counter, (uint32_t)1)}; return info; }
struct A {}; struct B {}; struct message { const type::info& type; void* ptr; template <class T> message(T* t) : type(type::get_type<T>()), ptr(t) { } }; void accept_message(const message& m) { if (m.type == type::get_type<A>()) { printf("Got A class\n"); } else { printf("Oops, got ??\n"); } }
int main(int argc, char* argv[]) { A a; B b; accept_message(message(&a)); accept_message(message(&b)); }
[maciek@pc type_info]$ ./test Got A class Oops, got ??
namespace type { extern std::atomic<uint32_t> type_counter; struct info { const char* name; uint32_t id; bool operator== (const info& other) const {return id == other.id;} bool operator!= (const info& other) const {return id != other.id;} }; template <class ValueType> const info& get_type(const char* name="<type unnamed>") { static info info = {name, std::atomic_fetch_add(&type_counter, 1)}; return info; }
struct A {}; struct B {}; void accept_message(const message& m) { if (m.type == type::get_type<A>()) { printf("Got A class\n"); } else { printf("Oops, got %s\n", m.type.name); } } const type::info infoA = type::get_type<A>("<A class>"); const type::info infoB = type::get_type<B>("<B class>"); int main(int argc, char* argv[]) { A a; B b; accept_message(message(&a)); accept_message(message(&b)); }
[maciek@pc type_info]$ ./test Got A class Oops, got <B class>
struct info { const char* name; bool operator== (const info& other) const {return this == &other;} bool operator!= (const info& other) const {return this != &other;} }; template <class ValueType> const info& get_type(const char* name="<type unnamed>") { static info info {name}; return info; }
[maciek@pc type_info]$ objdump -tC ./a.out | grep "guard var" | cut -f2-3 guard variable for type::info const& type::get_type<A>(char const*)::info guard variable for type::info const& type::get_type<B>(char const*)::info
struct info { std::string name; info(const char* name) : name(name) {}; info(const info&) = delete; bool operator== (const info& other) const {return this == &other;} bool operator!= (const info& other) const {return this != &other;} };
template <class T> struct info_class { static info type_info; }; template <class T> info info_class<T>::type_info("<type unnamed>");
template <class ValueType> const info& get_type() { return info_class<ValueType>::type_info; } template <class ValueType> const info& get_type(const char* name) { info& i = info_class<ValueType>::type_info; i.name = name; return i; }
struct A {}; struct B {}; void accept_message(const message& m) { if (m.type == type::get_type<A>()) { printf("Got A class\n"); } else { printf("Oops, got %s\n", m.type.name); } } int main(int argc, char* argv[]) { const type::info infoA = type::get_type<A>("<A class>"); const type::info infoB = type::get_type<B>("<B class>"); A a; B b; accept_message(message(&a)); accept_message(message(&b)); }
Use a spacebar or arrow keys to navigate