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_