Do we really want mallocs for EVERY single multiple-dispatch function call in
PETSc? I suggest not having MatQueryOp() but calling directly
PetscOpFListFind() (with the MatOpFList argument) and changing
PetscOpFListAdd/Find() to use variable args directly.
Finally do we really want string comparisons at all here? Or do we want
XXXRegister() (for example, MatRegister()) to compute an integer type id to go
with each char *type_name and do the search off the integer type id instead of
strings? Thus making PetscOpFListFind() super light weight?
Barry
PetscErrorCode MatQueryOp(MPI_Comm comm, PetscVoidFunction* function, const
char op[], PetscInt numArgs, ...)
{
PetscErrorCode ierr;
va_list ap;
PetscInt i;
const char *argType;
char **argTypes = PETSC_NULL;
PetscFunctionBegin;
va_start(ap,numArgs);
if (numArgs) {
ierr = PetscMalloc(sizeof(char*)*numArgs, &argTypes);CHKERRQ(ierr);
}
for (i = 0; i < numArgs; ++i) {
argType = va_arg(ap,const char*);
ierr = PetscStrallocpy(argType, argTypes+i);CHKERRQ(ierr);
}
va_end(ap);
ierr = PetscOpFListFind(comm, MatOpList, function, op, numArgs,
argTypes);CHKERRQ(ierr);
for (i = 0; i < numArgs; ++i) {
ierr = PetscFree(argTypes[i]);CHKERRQ(ierr);
}
ierr = PetscFree(argTypes);CHKERRQ(ierr);
PetscFunctionReturn(0);
}