#include "adt/rtti_util.h" #include enum builtin_type { NO_BUILTIN, CHAR, SCHAR, UCHAR, SSHORT, USHORT, SINT, UINT, SLONG, ULONG, FLOAT, DOUBLE }; static builtin_type classify_builtin (std::type_info const &ti) { if (ti == typeid ( char)) return CHAR; if (ti == typeid ( signed char)) return SCHAR; if (ti == typeid (unsigned char)) return UCHAR; if (ti == typeid ( signed short)) return SSHORT; if (ti == typeid (unsigned short)) return USHORT; if (ti == typeid ( signed int)) return SINT; if (ti == typeid (unsigned int)) return UINT; if (ti == typeid ( signed long)) return SLONG; if (ti == typeid (unsigned long)) return ULONG; if (ti == typeid ( float)) return FLOAT; if (ti == typeid ( double)) return DOUBLE; return NO_BUILTIN; } bool is_integral (std::type_info const &ti) { switch (classify_builtin (ti)) { case CHAR : case SCHAR : case UCHAR : case SSHORT: case USHORT: case SINT : case UINT : case SLONG : case ULONG : return true; case FLOAT : case DOUBLE: case NO_BUILTIN: return false; } } bool is_signed (std::type_info const &ti) { switch (classify_builtin (ti)) { case CHAR : return true; // FIXME: maybe not case UCHAR : case USHORT: case UINT : case ULONG : return false; case SCHAR : case SSHORT: case SINT : case SLONG : return true; case FLOAT : case DOUBLE: case NO_BUILTIN: return false; } } bool is_floating_point (std::type_info const &ti) { switch (classify_builtin (ti)) { case CHAR : case SCHAR : case UCHAR : case SSHORT: case USHORT: case SINT : case UINT : case SLONG : case ULONG : return false; case FLOAT : case DOUBLE: return true; case NO_BUILTIN: return false; } } template T runtime_cast (void const *ptr, std::type_info const &ti) { switch (classify_builtin (ti)) { case CHAR : return *( char const *)ptr; case SCHAR : return *( signed char const *)ptr; case UCHAR : return *(unsigned char const *)ptr; case SSHORT: return *( signed short const *)ptr; case USHORT: return *(unsigned short const *)ptr; case SINT : return *( signed int const *)ptr; case UINT : return *(unsigned int const *)ptr; case SLONG : return *( signed long const *)ptr; case ULONG : return *(unsigned long const *)ptr; case FLOAT : return *( float const *)ptr; case DOUBLE: return *( double const *)ptr; case NO_BUILTIN: break; } throw std::runtime_error ("impossible cast"); } template double runtime_cast (void const *ptr, std::type_info const &ti); template signed long runtime_cast (void const *ptr, std::type_info const &ti); template unsigned long runtime_cast (void const *ptr, std::type_info const &ti);