On 10-04-19 01:31 AM, BCS wrote:
Hello Justin Spahr-Summers,

On Mon, 19 Apr 2010 00:12:28 +0000 (UTC), Graham Fawcett
<fawc...@uwindsor.ca> wrote:

Hi folks,

I'd like to wrap a family of C functions that look like this:

gboolean fooXXX(arg1, ..., argN, GError** err)

Their signatures and arities vary, but they all have a GError** as
their last argument. If a function returns false, then 'err' will be
set to a relevant Error struct.

I would like to write a wrapper that would let me call these
functions sort of like this:

check!(fooXXX(arg1, ..., argN))

where the 'check' expression would be equivalent to:

GError* err;
bool ok = fooXXX(arg1, ..., argN, &err);
if (!ok)
throw new Exception((*err).message);
Does D (2.0) offer a metaprogramming technique I could use to
accomplish this -- particularly, to inject that 'err' argument into
the tail of the fooXXX call?

Thanks,
Graham
You can use some expression tuple magic to accomplish something like
that:

bool check(alias func, EL ...)() {
GError* err;
bool ok = func(EL, &err);
if (!ok)
throw new Exception((*err).message);
return ok;
}
// used like:
check!(fooXXX, arg1, ..., argN);

IIRC that should be:

check!(fooXXX, argType1, ..., argTypeN)(arg1, ..., argN);

See http://digitalmars.com/d/2.0/template.html#TemplateTupleParameter


Or you can mangel that a bit:

template check(alias func) {
bool check(EL ...)() {
GError* err;
bool ok = func(EL, &err);
if (!ok)
throw new Exception((*err).message);
return ok;
}
}

that should allow you to call it like:

check!(fooXXX)(arg1, ..., argN);


Remarkable! Thank you to everyone who responded. I can't wait to give
these a try tonight. :)

Cheers,
Graham

Reply via email to