Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

RTTI

Name: Anonymous 2012-05-17 10:44

discuss

Name: Anonymous 2012-05-18 13:33

>>6
fuck you bitch


#include <vector>
#include <cstdio>
#include <cstring>
#include <cassert>

class typeinfo_t;
typedef std::vector<typeinfo_t*> typelist_t;

typelist_t* types = NULL;

void rtti_init();
size_t rtti_init_r(typeinfo_t* p, size_t n);
void rtti_uninit();
typeinfo_t* rtti_find(const char* classname);

class typeinfo_t
{
public:
    typeinfo_t(const char* classname_, const char* supername_)
        :  classname(classname_), supername(supername_), begin(0), end(0)
    {
        bool inserted = false;

        if(!types)
            types = new typelist_t;

        super = rtti_find(supername);
        if(super)
            super->subs.push_back(this);

        for(auto it = types->begin(); it != types->end(); ++it)
        {
            int c = strcmp(classname, (*it)->classname);
            assert(c);
           
            if((*it)->super == NULL && strcmp((*it)->supername, classname) == 0)
            {
                (*it)->super = this;
                subs.push_back(*it);
            }
           
            if(c < 0)
            {
                it = types->insert(it, this) + 1;
                inserted = true;
            }
        }

        if(!inserted)
            types->push_back(this);
    }

    typeinfo_t* get_super() const
    {
        return super;
    }

    bool is_type(const typeinfo_t& t) const
    {
        if(begin >= t.begin && begin <= t.end)
            return true;

        return false;
    }

    const char* classname;
    const char* supername;
    friend size_t rtti_init_r(typeinfo_t*, size_t);

private:
    size_t begin, end;
    typeinfo_t* super;
    typelist_t subs;
};

size_t rtti_init_r(typeinfo_t* p, size_t n)
{
    p->begin = n;
    p->end += n;
    for(auto s = p->get_super(); s; s = s->get_super())
        s->end++;

    for(auto it = p->subs.begin(); it != p->subs.end(); ++it)
        n = rtti_init_r(*it, n + 1);

    return n;
}

void rtti_init()
{
    assert(types->size());
    typeinfo_t* p = types->at(0);
    while(p->get_super())
        p = p->get_super();

    rtti_init_r(p, 0);
}

void rtti_uninit()
{
    delete types;
}

typeinfo_t* rtti_find(const char* classname)
{
    size_t i = 0, j = types->size();

    while(i < j)
    {
        size_t k = i + ((j - i) / 2);
        int c = strcmp(classname, types->at(k)->classname);

        if(c < 0)
            j = k;
        else if(c > 0)
            i = k + 1;
        else
            return types->at(k);
    }

    return NULL;
}

#define DECLARE_CLASS \
    static typeinfo_t type; \
    virtual typeinfo_t* get_type() const;
   
#define DEFINE_CLASS(classname, supername) \
    typeinfo_t classname::type(#classname, #supername); \
    typeinfo_t* classname::get_type() const { return &classname::type; }

class base_class
{
public:
    DECLARE_CLASS
   
    bool is_type(const typeinfo_t& t) const
    {
        return this->get_type()->is_type(t);
    }

    const char* get_name() const
    {
        return this->get_type()->classname;
    }
};

DEFINE_CLASS(base_class, none)

class A : public base_class
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(A, base_class)

class B : public base_class
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(B, base_class)

class C : public A
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(C, A)

class D : public B
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(D, B)

class E : public C
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(E, C)

class F : public C
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(F, C)

class G : public F
{
public:
    DECLARE_CLASS
};

DEFINE_CLASS(G, F)

const char* boolstr(bool b)
{
    return b ? "true" : "false";
}

void print_test(base_class& c)
{
    printf("Testing class %s\n", c.get_name());
    printf("is_type(A) : %s\n", boolstr(c.is_type(A::type)));
    printf("is_type(B) : %s\n", boolstr(c.is_type(B::type)));
    printf("is_type(C) : %s\n", boolstr(c.is_type(C::type)));
    printf("is_type(D) : %s\n", boolstr(c.is_type(D::type)));
    printf("is_type(E) : %s\n", boolstr(c.is_type(E::type)));
    printf("is_type(F) : %s\n", boolstr(c.is_type(F::type)));
    printf("is_type(G) : %s\n\n", boolstr(c.is_type(G::type)));
}

int main()
{
    rtti_init();
    print_test(A());
    print_test(B());
    print_test(C());
    print_test(D());
    print_test(E());
    print_test(F());
    print_test(G());
    rtti_uninit();
}

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List