fork download
  1. #include <iostream>
  2.  
  3. class Base {
  4. public:
  5. template <typename To>
  6. bool isa() const {
  7. return this->match(To::GetID());
  8. }
  9.  
  10. protected:
  11. typedef size_t ID;
  12.  
  13. static ID NextID() { static ID id = 0; return id++; }
  14.  
  15. virtual bool match(ID) const { return false; }
  16. };
  17.  
  18. class Derived: public Base {
  19. public:
  20. static ID GetID() { static ID id = NextID(); return id; }
  21.  
  22. protected:
  23. virtual bool match(ID id) const { return id == GetID() || Base::match(id); }
  24. };
  25.  
  26. class MostDerived: public Derived {
  27. public:
  28. static ID GetID() { static ID id = NextID(); return id; }
  29.  
  30. protected:
  31. virtual bool match(ID id) const { return id == GetID() || Derived::match(id); }
  32. };
  33.  
  34. template <typename To, typename From>
  35. To const* dyn_cast(From const* f) {
  36. if (f and f->template isa<To>()) { return static_cast<To const*>(f); }
  37. return 0;
  38. }
  39.  
  40. template <typename To, typename From>
  41. To* dyn_cast(From* f) { return const_cast<To*>(dyn_cast<To>((From const*)f)); }
  42.  
  43. int main() {
  44. Derived derived; MostDerived mostDerived;
  45. Base* d = &derived, * md = &mostDerived;
  46.  
  47. if (dyn_cast<Derived>(d)) { std::cout << "Derived -> Derived: ok\n"; }
  48. else { std::cout << "Derived -> Derived: ko\n"; }
  49.  
  50. if (dyn_cast<MostDerived>(md)) { std::cout << "MostDerived -> MostDerived : ok\n"; }
  51. else { std::cout << "MostDerived -> MostDerived : ko\n"; }
  52.  
  53. if (dyn_cast<Derived>(md)) { std::cout << "MostDerived -> Derived : ok\n"; }
  54. else { std::cout << "MostDerived -> Derived : ko\n"; }
  55.  
  56. if (dyn_cast<MostDerived>(d)) { std::cout << "Derived -> MostDerived: ko\n"; }
  57. else { std::cout << "Derived -> MostDerived: ok\n"; }
  58. }
Success #stdin #stdout 0.02s 2724KB
stdin
Standard input is empty
stdout
Derived -> Derived: ok
MostDerived -> MostDerived : ok
MostDerived -> Derived : ok
Derived -> MostDerived: ok