Boost logo

Boost :

From: Johan Nilsson (johan.nilsson_at_[hidden])
Date: 2002-12-10 03:26:49


[I've tried posting this to c.l.c++.m, but to no success. Don't know if it's
due to some of the assert code looking like html markup ;-) or whatever.
Anyway, I thought this might also be a good forum.]

Hi,

this is an experiment I just tried out. I've only tried it with VC7, and it
doesn't work with virtual base classes, but I'd be still interested in
hearing your comments.

Sorry about the rather lengthy example.

// Johan

---
main.cpp
---
#include <cassert>
#include <stdexcept>
#include <typeinfo>
using namespace std;
struct Something
{
  virtual const type_info& id() { return typeid(*this); }
};
struct AnotherThing
{
  virtual const type_info& id() { return typeid(*this); }
};
struct YetAnotherThing : public AnotherThing
{
  virtual void useless() {}
};
struct MiThing : public Something, public YetAnotherThing
{
  virtual void worthless() {}
};
template<typename T>
T* dynamic_void_cast(void* pv)
{
  struct rtti_obj__
  {
    virtual ~rtti_obj__() = 0;
  };
  rtti_obj__* pro = static_cast<rtti_obj__*>(pv);
  try
  {
    return dynamic_cast<T*>(pro);
  }
  catch (bad_cast&)
  {
    throw;
  }
  catch (exception& e)
  {
    throw bad_cast(e.what());
  }
}
template<typename T>
void* void_cast(T* pT)
{
  return static_cast<void*>(pT);
}
int main()
{
  //
  // Test successful casts
  //
  Something     something;
  assert(0 != dynamic_void_cast<Something>(void_cast(&something)));
  assert(typeid(something) ==
dynamic_void_cast<Something>(void_cast(&something))->id());
  assert(typeid(something) ==
typeid(*dynamic_void_cast<Something>(void_cast(&something))));
  AnotherThing  another;
  assert(0 != dynamic_void_cast<AnotherThing>(void_cast(&another)));
  assert(typeid(another) ==
dynamic_void_cast<AnotherThing>(void_cast(&another))->id());
  assert(typeid(another) ==
typeid(*dynamic_void_cast<AnotherThing>(void_cast(&another))));
  YetAnotherThing yetAnother;
  assert(0 != dynamic_void_cast<AnotherThing>(void_cast(&yetAnother)));
  assert(0 != dynamic_void_cast<YetAnotherThing>(void_cast(&yetAnother)));
  assert(typeid(yetAnother) ==
dynamic_void_cast<AnotherThing>(void_cast(&yetAnother))->id());
  assert(typeid(yetAnother) ==
typeid(*dynamic_void_cast<AnotherThing>(void_cast(&yetAnother))));
  MiThing mi;
  assert(0 != dynamic_void_cast<MiThing>(void_cast(&mi)));
  assert(0 != dynamic_void_cast<Something>(void_cast(&mi)));
  assert(0 != dynamic_void_cast<AnotherThing>(void_cast(&mi)));
  assert(0 != dynamic_void_cast<YetAnotherThing>(void_cast(&mi)));
  assert(typeid(mi) ==
dynamic_void_cast<AnotherThing>(void_cast(&mi))->id());
  assert(typeid(mi) ==
typeid(*dynamic_void_cast<AnotherThing>(void_cast(&mi))));
  //
  // Test expected failures
  //
  assert(0 == dynamic_void_cast<Something>(&another));
  assert(0 == dynamic_void_cast<AnotherThing>(&something));
   //
  // Test 'sub-object' pointers differ
  //
  Something* pSome = dynamic_void_cast<Something>(void_cast(&mi));
  AnotherThing* pAnother = dynamic_void_cast<AnotherThing>(void_cast(&mi));
  assert(void_cast(pSome) != void_cast(pAnother));
  return 0;
}
---

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk