Re: Announcing Xrtti - Extended Runtime Type Information for C++
On May 2, 5:20 am, ali <albrecht.fritzs...@gmx.net> wrote:
Hm, now I am curious - how can you, say, create a function which calls
on
every class (of your program) all functions starting with "test_" via /
compile time
reflection/? Including calling it with the correct parameters?
Using the Xrtti API, you could do this:
using namespace Xrtti;
void CallAllTest_Methods()
{
// Look at each context, picking out the classes ...
U32 contextCount = GetContextCount();
for (U32 i = 0; i < contextCount; i++) {
const Context &context = GetContext(i);
// Skip it if it's not a class
if (context.GetType() != Context::Type_Class) {
continue;
}
// OK, we have a class. Look at each method to find methods
whose
// names begin with test_
const Class &classRef = (const Class &) context;
void *pInstance = NULL;
U32 methodCount = classRef.GetMethodCount();
for (U32 i = 0; i < methodCount; i++) {
const Method &method = classRef.GetMethod(i);
// Does the method's name begin with "test_"? If so, it's
// one we may want to call
if (strncmp(method.GetName(), "test_", 5)) {
// Doesn't begin with test_, skip it
continue;
}
// Now we would have to have some logic here to detect the
// argument types of this test_ method, and come up with
suitable
// arguments. This would be policy that you would have to
define
// for your own test_ methods; this would be by far the
hardest
// part of coming up with a general test framework, and
I'm sorry
// but I can't solve this problem in this short example.
Suffice
// it to say, the Xrtti API would let you look at the
argument
// number and types, and return type, of this method, to
allow
// this kind of automated argument building
// For this example, to gloss over the above problem,
we'll just
// skip anything that returns non-void or has arguments.
if ((method.GetSignature().GetReturnType().GetBaseType() !
=
Type::BaseType_Void) ||
(method.GetSignature().GetArgumentCount() != 0)) {
// It either has a return type, or takes arguments.
Skip it.
continue;
}
// Now that we have a method to call, we'll need an
instance to
// call it on
if (pInstance == NULL) {
// Note that this call will result in the actual
default
// constructor of the given class being called, and
the
// resulting constructed object being returned as a
void *
void *pInstance = classRef.Create();
// This can actually return NULL if the class is not
// constructable, i.e. is an abstract class, so skip
it
if (pInstance == NULL) {
continue;
}
}
// OK, this is a method with signature void test_xxx();
Invoke it.
// We always have to supply a place to put the return
value, even
// though this method returns no value.
Value returnValue;
method.Invoke(pInstance, returnValue, NULL);
}
// Now delete the constructed instance, if there was one
if (pInstance != NULL) {
classRef.Delete(pInstance);
}
}
}
I haven't tested this code, I just wrote it out quickly, and there are
probably bugs and typos. But it illustrates the general technique you
would use to do this. The hardest part by far is having an algorithm
to "make up" test method arguments. I would expect that this would be
something you'd have to supply some kind of configuration file for.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]