Proposal: RTTI¶
Note
Feature awaiting further design consideration.
This is a proposal to add run-time type information to Loci.
is_a¶
This supports checking whether the actual type (which is known only at run-time, unless A is a class type) of a reference or pointer conforms to a given target type (B in this example).
void f(A& object) {
if (is_a<B&>(object)) {
//...
}
}
The performance for each case (depending on types of A and B) is:
- If A is a class type, and B is a class type, then the ‘is_a’ statement is resolved at compile-time (hence no run-time overhead).
- If A is a class type, and B is an interface type, then the compiler can again resolve it at compile-time.
- If A is an interface type, but B is a class type, the implementation for this is just a single comparison, so this is a very efficient way to check the type of an interface reference/pointer.
- If A is an interface type, and B is an interface type, then this call involves a number of comparisons proportional to the number of methods in the larger interface, unless it can be determined at compile-time that there is a valid static cast from A to B.
dynamic_cast¶
This operates just like C++:
int f(A& object) {
B& castObject = dynamic_cast<B&>(object);
return castObject.method();
}
This is effectively just the equivalent of calling is_a to assert the types are compatible, and then either treating the reference to A as a reference to B.
typeid¶
This allows access to information about a type from a reference or pointer to an instance of it:
void f(T& a, T& b) {
rtti::type_info typeInfo = typeid(a);
// type_info structures can be compared,
// but is_a is likely to be more efficient.
if (typeInfo == typeid(b)) {
//...
}
// Get the type's name.
string typeName = typeInfo.name;
// Get the type's virtual table.
void * vtable = typeInfo.vtable;
// Get the type's size.
size_t typeSize = typeInfo.size;
for (const auto i: range<size_t>(0, typeInfo.methods.size())) {
rtti::method_info methodInfo = typeInfo.methods[i];
// Get method name.
string methodName = methodInfo.name;
// etc.
}
}