Sign in to follow this  
smart_idiot

Equivalent of dynamic_cast, without knowing the actual types? (C++)

Recommended Posts

Is there any way I can convert a void pointer of some unknown type, to some other unknown type (i.e., figure out the offset to apply to it) using the original pointer, and std::type_info structures of the source and destination types? The information required to do it should exist somewhere since dynamic_cast can do it. I imagine there's probably an abi interface to do this, but I'm not really sure where to start looking.

Share this post


Link to post
Share on other sites
You cannot cast to an unknown type, since you need an appropriately-typed variable to store the result (static typing strikes again). Vtbls and this pointer offsets are implementations details that are outside the scope of the C++ standard.

As for ABIs, who knows... there is no actual standard ABI for C++. Your guesses about compiler extensions are as good as mine.

Share this post


Link to post
Share on other sites
If you know the types you'll be converting between ahead of time, you could build a lookup table.

std::map< std::pair< industry::type , industry::type > , std::ptrdiff_t > lut;

template < typename L , bool empty = is_empty< L >::value >
void add_to_lut( void ) {
add_row_to_lut< typename front< L >::type , L >();
add_to_lut< typename pop_front< L >::type >();
}

template < typename L >
void add_to_lut< L , true >() {}

template < typename T , typename L , bool empty = is_empty< L >::value >
void add_row_to_lut( void ) {
add_row_col_to_lut< T , typename front< L >::type >();
add_row_to_lut< T , typename pop_front< L >::type >();
}

template < typename T , typename L >
void add_row_to_lut< T , L , true >() {}

template < typename T1 , typename T2 >
void add_row_col_to_lut( void ) {
std::ptrdiff_t T1_to_T2 = ((std::ptrdiff_t)(void *)(T2 *)0x10000) - ((std::ptrdiff_t)(void *)(T1 *)0x10000);

lut[ std::make_pair( typeid(T1) , typeid(T2) ) ] = +T1_to_T2;
lut[ std::make_pair( typeid(T2) , typeid(T1) ) ] = -T1_to_T2;
}

add_to_lut< boost::mpl::vector< T1 , T2 ... Tn > >();






(Not sure I got all that right, but you get the idea! Plenty of room for optimization of course, depending on the assumptions you're willing to make (or eliminating half the table))

Share this post


Link to post
Share on other sites
If you really need this kind of behaviour, I think you can afford to just make everything inherit from a top Object class, yeah? After all, that's how languages with built-in 'isinstance' checks do things...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this