1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
std::map<std::pair<int, int>, int> cast_map;
template <typename T>
struct get_type_id{};
template <>
struct get_type_id<S>{
static const int value = 1;
};
template <>
struct get_type_id<A>{
static const int value = 2;
};
template <>
struct get_type_id<B>{
static const int value = 3;
};
template <>
struct get_type_id<C>{
static const int value = 4;
};
template <typename src, typename dst>
void set_cast(){
static_assert(std::is_base_of<dst, src>::value, "src must be a subclass of dst");
const auto k = std::numeric_limits<intptr_t>::max() / 4;
auto key = std::make_pair(get_type_id<src>::value, get_type_id<dst>::value);
cast_map[key] = (int)((intptr_t)static_cast<dst *>((src *)k) - k);
}
void initialize_cast_map(){
set_cast<S, S>();
set_cast<A, S>();
set_cast<A, A>();
set_cast<B, S>();
set_cast<B, B>();
set_cast<C, S>();
set_cast<C, A>();
set_cast<C, B>();
set_cast<C, C>();
}
void *dynamic_static_cast(void *src, int src_type, int dst_type){
auto it = cast_map.find(std::make_pair(src_type, dst_type));
if (it == cast_map.end())
throw std::bad_cast();
return (char *)src + it->second;
}
| |