Generic method that takes in either delegate or function
Jonathan M Davis
jmdavisProg at gmx.com
Wed Jan 12 00:47:16 PST 2011
On Wednesday 12 January 2011 00:21:54 %u wrote:
> Hi,
>
> Is there any way to specify a parameter as "something that can be called
> with parameter types A, B, C and that returns a value of type D", without
> caring whether it's a delegate, a function, or an object that overloads
> opCall? (This might require the use of templates, but I still can't figure
> it out...)
>
> Thank you!
Take this example from my proposed std.unittests which is currently under
review:
void assertPred(alias pred, string msg = null, string file = __FILE__, size_t
line = __LINE__, T...)
(T args)
if(isCallable!pred &&
is(ReturnType!pred == bool) &&
__traits(compiles, pred(args)) &&
isPrintable!T)
{
immutable result = pred(args);
if(!result)
{
string argsStr;
if(args.length > 0)
{
foreach(value; args)
argsStr ~= format("[%s], ", to!string(value));
argsStr.popBackN(", ".length);
}
else
argsStr = "none";
if(msg.empty)
throw new AssertError(format("assertPred failed: arguments: %s.",
argsStr), file, line);
else
throw new AssertError(format("assertPred failed: arguments: %s: %s",
argsStr, msg), file, line);
}
}
The combination of alias, isCallable, ReturnType, and __traits(compiles) does
the trick. isCallable guarantees that pred is callable, but it doesn't care how.
ReturnType guarantees that the return type is bool. And __traits(compiles,
pred(args)) guarantees that pred can be called with the given arguments.
- Jonathan M Davis
More information about the Digitalmars-d-learn
mailing list