Skip to content

Instantly share code, notes, and snippets.

@Leedehai
Last active June 12, 2019 17:39
Show Gist options
  • Save Leedehai/535a73e19c1cdb2b684279d377d2da52 to your computer and use it in GitHub Desktop.
Save Leedehai/535a73e19c1cdb2b684279d377d2da52 to your computer and use it in GitHub Desktop.
Play with manual C++ RTTI (inspired by LLVM/Clang)
#include <iostream>
using namespace std; // yeah I know it's better to use "ns::foo" instead of declaring "using namespace ns" at the top...
// but this file is just a toy, right. Live a little.
enum Kind_t { KA, KB, KC, KD };
class A {
Kind_t kind;
public:
A(Kind_t kind = KA) : kind(kind) {}
virtual ~A() = default;
static bool classof(const A *p) { cout << "A::classof(A*) - "; return true; }
virtual Kind_t getID() const { return kind; }
};
class B : public A {
public:
B(Kind_t kind = KB) : A(kind) {}
static bool classof(const B *p) { cout << "B::classof(B*) - "; return true; }
static bool classof(const A *p) { cout << "B::classof(A*) - "; return p->getID() == KB || p->getID() == KC; }
};
class C : public B {
public:
C(Kind_t kind = KC) : B(kind) {}
static bool classof(const C *p) { cout << "C::classof(C*) - "; return true; }
static bool classof(const A *p) { cout << "C::classof(A*) - "; return p->getID() == KC; }
};
class D : public A {
public:
D(Kind_t kind = KD) : A(kind) {}
static bool classof(const D *p) { cout << "D::classof(D*) - "; return true; }
static bool classof(const A *p) { cout << "D::classof(A*) - "; return p->getID() == KD; }
};
template <typename To, typename From>
bool isa(From * const &p) { cout << "isa(From * const &p) "; return To::classof(p); }
template <typename To, typename From>
bool isa(const From * const &p) { cout << "isa(const From * const &p) "; return To::classof(p); }
template <typename To, typename From>
To *dyn_cast(From * const &p) {
cout << "dyn_cast(From * const &p) ";
return isa<To>(p) ? reinterpret_cast<To *>(p) : nullptr;
}
template <typename To, typename From>
const To *dyn_cast(const From * const &p) {
cout << "dyn_cast(const From * const &p) ";
return isa<const To>(p) ? reinterpret_cast<const To *>(p) : nullptr;
}
void testA(); void testB();
int main() {
cout << " A <- B <- C\n"
<< " <- D\n" << endl;
testA();
testB();
}
void testA() {
cout << "const A *pa = new A, *const pb = new B, *pc = new C, *pd = new D;" << endl;
const A *pa = new A, *const pb = new B, *pc = new C, *pd = new D;
cout << "\nisa<A>(pa) - true : " << endl;
cout << (isa<A>(pa) ? "true" : "false") << "\n" << (dyn_cast<A>(pa) ? 1 : 0) << endl;
cout << "\nisa<A>(pb) - true : " << endl;
cout << (isa<A>(pb) ? "true" : "false") << "\n" << (dyn_cast<A>(pb) ? 1 : 0) << endl;
cout << "\nisa<A>(pc) - true : " << endl;
cout << (isa<A>(pc) ? "true" : "false") << "\n" << (dyn_cast<A>(pc) ? 1 : 0) << endl;
cout << "\nisa<A>(pd) - true : " << endl;
cout << (isa<A>(pd) ? "true" : "false") << "\n" << (dyn_cast<A>(pd) ? 1 : 0) << endl;
cout << "\nisa<B>(pa) - false: " << endl;
cout << (isa<B>(pa) ? "true" : "false") << "\n" << (dyn_cast<B>(pa) ? 1 : 0) << endl;
cout << "\nisa<B>(pb) - true : " << endl;
cout << (isa<B>(pb) ? "true" : "false") << "\n" << (dyn_cast<B>(pb) ? 1 : 0) << endl;
cout << "\nisa<B>(pc) - true : " << endl;
cout << (isa<B>(pc) ? "true" : "false") << "\n" << (dyn_cast<B>(pc) ? 1 : 0) << endl;
cout << "\nisa<B>(pd) - false: " << endl;
cout << (isa<B>(pd) ? "true" : "false") << "\n" << (dyn_cast<B>(pd) ? 1 : 0) << endl;
cout << "\nisa<C>(pd) - false: " << endl;
cout << (isa<C>(pd) ? "true" : "false") << "\n" << (dyn_cast<C>(pd) ? 1 : 0) << endl;
}
void testB() {
cout << "B *pb = new B, *const pc = new C; D *pd = new D;" << endl;
B *pb = new B, *const pc = new C; D *pd = new D;
cout << "\nisa<B>(pb) - true : " << endl;
cout << (isa<B>(pb) ? "true" : "false") << "\n" << (dyn_cast<B>(pb) ? 1 : 0) << endl;
cout << "\nisa<B>(pc) - true : " << endl;
cout << (isa<B>(pc) ? "true" : "false") << "\n" << (dyn_cast<B>(pc) ? 1 : 0) << endl;
cout << "\nisa<B>(pd) - false: " << endl;
cout << (isa<B>(pd) ? "true" : "false") << "\n" << (dyn_cast<B>(pd) ? 1 : 0) << endl;
cout << "\nisa<C>(pd) - false: " << endl;
cout << (isa<C>(pd) ? "true" : "false") << "\n" << (dyn_cast<C>(pd) ? 1 : 0) << endl;
}
/* printout
A <- B <- C
<- D
const A *pa = new A, *const pb = new B, *pc = new C, *pd = new D;
isa<A>(pa) - true :
isa(const From * const &p) A::classof(A*) - true
dyn_cast(const From * const &p) isa(const From * const &p) A::classof(A*) - 1
isa<A>(pb) - true :
isa(const From * const &p) A::classof(A*) - true
dyn_cast(const From * const &p) isa(const From * const &p) A::classof(A*) - 1
isa<A>(pc) - true :
isa(const From * const &p) A::classof(A*) - true
dyn_cast(const From * const &p) isa(const From * const &p) A::classof(A*) - 1
isa<A>(pd) - true :
isa(const From * const &p) A::classof(A*) - true
dyn_cast(const From * const &p) isa(const From * const &p) A::classof(A*) - 1
isa<B>(pa) - false:
isa(const From * const &p) B::classof(A*) - false
dyn_cast(const From * const &p) isa(const From * const &p) B::classof(A*) - 0
isa<B>(pb) - true :
isa(const From * const &p) B::classof(A*) - true
dyn_cast(const From * const &p) isa(const From * const &p) B::classof(A*) - 1
isa<B>(pc) - true :
isa(const From * const &p) B::classof(A*) - true
dyn_cast(const From * const &p) isa(const From * const &p) B::classof(A*) - 1
isa<B>(pd) - false:
isa(const From * const &p) B::classof(A*) - false
dyn_cast(const From * const &p) isa(const From * const &p) B::classof(A*) - 0
isa<C>(pd) - false:
isa(const From * const &p) C::classof(A*) - false
dyn_cast(const From * const &p) isa(const From * const &p) C::classof(A*) - 0
B *pb = new B, *const pc = new C; D *pd = new D;
isa<B>(pb) - true :
isa(From * const &p) B::classof(B*) - true
dyn_cast(From * const &p) isa(From * const &p) B::classof(B*) - 1
isa<B>(pc) - true :
isa(From * const &p) B::classof(B*) - true
dyn_cast(From * const &p) isa(From * const &p) B::classof(B*) - 1
isa<B>(pd) - false:
isa(From * const &p) B::classof(A*) - false
dyn_cast(From * const &p) isa(From * const &p) B::classof(A*) - 0
isa<C>(pd) - false:
isa(From * const &p) C::classof(A*) - false
dyn_cast(From * const &p) isa(From * const &p) C::classof(A*) - 0
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment