Your browser doesn't support the features required by impress.js, so you are presented with a simplified version of this presentation.

For the best experience please use the latest Chrome, Safari or Firefox browser.

Type info

without RTTI

C++ RTTI

why even bother to disable it?

Example program

struct message {
    /*typeinfo*/ type;
    void* ptr;
};

void accept_message(const message& m) {
    if (m.type == /* some class */) {
       // do stuff
    } else {
       // do 
    }
}

Type info v1 - template instantiation

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 ??

Type info v1 - summary

Type info v2 - support for type names

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>

Type info v2 - summary

Type info v3 - no atomics

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

Type info v4 - no locks

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));
}

Type info v4 - summary

Type info - summary

Thank you

Use a spacebar or arrow keys to navigate