#include <stdio.h>
#include "exception.h"
#include "typeinfo.h"

class Base
{
  public:

    Base();
    ~Base();

    RTTI_SCAFFOLDING_DECL
};

Base::Base() {}
Base::~Base() {}

RTTI_SCAFFOLDING_DEFN_0(Base)


class Derived : public Base
{
  public:

    Derived();
    ~Derived();

    RTTI_SCAFFOLDING_DECL
};

Derived::Derived() {}
Derived::~Derived() {}

RTTI_SCAFFOLDING_DEFN_1(Derived, Base)


int main()
{
  Base base;
  Derived derived;

  printf("Base:    %s\n", TYPE_typeid(Base).name());
  printf("Derived: %s\n", TYPE_typeid(Derived).name());

  Base* p_base = &base;
  Base* p_derived = &derived;

  char const* can_cast = "can cast";
  char const* cant_cast = "can't cast";

  printf("Base* -> Base        %s\n", (PTR_dynamic_cast(Base, p_base) == 0 ? cant_cast : can_cast));
  printf("Base* -> Derived     %s\n", (PTR_dynamic_cast(Derived, p_base) == 0 ? cant_cast : can_cast));
  printf("Derived* -> Base     %s\n", (PTR_dynamic_cast(Base, p_derived) == 0 ? cant_cast : can_cast));
  printf("Derived* -> Derived  %s\n", (PTR_dynamic_cast(Derived, p_derived) == 0 ? cant_cast : can_cast));

  try
  {
    printf("Base& rb1 = REF_dynamic_cast(Base, base)");
    Base& rb1 = REF_dynamic_cast(Base, base);
    printf(" ... OK\n");

    printf("Base& rb2 = REF_dynamic_cast(Base, derived)");
    Base& rb2 = REF_dynamic_cast(Base, derived);
    printf(" ... OK\n");

    printf("Derived& rd2 = REF_dynamic_cast(Derived, derived)");
    Derived& rd2 = REF_dynamic_cast(Derived, derived);
    printf(" ... OK\n");

    printf("Derived& rd1 = REF_dynamic_cast(Derived, base)");
    Derived& rd1 = REF_dynamic_cast(Derived, base);
    printf(" ... OK\n");
  }
  BEGIN_HANDLERS
  catch(bad_cast, ex)
  {
    printf(" ... exception (%s)\n", ex.what());
  }
  catch_DOTS
  {
    printf(" ... caught wrong exception !!!\n");
  }
  END_HANDLERS

  printf("\n");
}
