ifndef Rice__detail__Caster__hpp_ define Rice__detail__Caster__hpp_
include “../Module.hpp” include <stdexcept>
namespace Rice {
namespace detail {
class Abstract_Caster { public:
virtual void * cast_to_base(void * derived, Module type) const = 0;
virtual ~Abstract_Caster() { }
};
template<typename Derived_T, typename Base_T> class Caster
: public Abstract_Caster
{ public:
Caster(Abstract_Caster * base_caster, Module type)
: base_caster_(base_caster)
, type_(type)
{
}
protected:
virtual void * cast_to_base(void * derived, Module type) const
{
if(type.value() == type_.value())
{
Derived_T * d(static_cast<Derived_T *>(derived));
return static_cast<Base_T *>(d);
}
else
{
if(base_caster_)
{
return base_caster_->cast_to_base(derived, type);
}
else
{
std::string s = "bad cast. No caster found for ";
s += type_.name().str();
throw std::runtime_error(s);
}
}
}
private:
Abstract_Caster * base_caster_; Module type_;
};
template<typename To_T, typename From_T> class Implicit_Caster
: public Abstract_Caster
{ public:
Implicit_Caster(Abstract_Caster * base_caster, Module type)
: base_caster_(base_caster)
, type_(type)
{
}
protected:
virtual void * cast_to_base(void * derived, Module type) const
{
if(type.value() == type_.value())
{
return new To_T( *static_cast<From_T*>(derived) );
}
else
{
if(base_caster_)
{
return base_caster_->cast_to_base(derived, type);
}
else
{
std::string s = "bad cast. No implicit caster found for ";
s += type_.name().str();
throw std::runtime_error(s);
}
}
}
private:
Abstract_Caster * base_caster_; Module type_;
};
} // detail
} // Rice
endif //Rice__detail__Caster__hpp_