isCallable

Detect whether T is a callable object, which can be called with the function call operator $(LPAREN)...$(RPAREN).

template isCallable (
alias callable
) {
static if(is(typeof(&callable.opCall) == delegate))
enum bool isCallable;
static if(!(is(typeof(&callable.opCall) == delegate)))
static if(is(typeof(&callable.opCall) V : V*) && is(V == function))
enum bool isCallable;
static if(!(is(typeof(&callable.opCall) == delegate)))
static if(!(is(typeof(&callable.opCall) V : V*) && is(V == function)))
static if(is(typeof(&callable.opCall!()) TemplateInstanceType))
enum bool isCallable;
static if(!(is(typeof(&callable.opCall) == delegate)))
static if(!(is(typeof(&callable.opCall) V : V*) && is(V == function)))
static if(!(is(typeof(&callable.opCall!()) TemplateInstanceType)))
static if(is(typeof(&callable!()) TemplateInstanceType))
enum bool isCallable;
static if(!(is(typeof(&callable.opCall) == delegate)))
static if(!(is(typeof(&callable.opCall) V : V*) && is(V == function)))
static if(!(is(typeof(&callable.opCall!()) TemplateInstanceType)))
static if(!(is(typeof(&callable!()) TemplateInstanceType)))
enum bool isCallable;
}

Examples

Functions, lambdas, and aggregate types with (static) opCall.

void f() { }
int g(int x) { return x; }

static assert( isCallable!f);
static assert( isCallable!g);

class C { int opCall(int) { return 0; } }
auto c = new C;
struct S { static int opCall(int) { return 0; } }
interface I { real value() @property; }

static assert( isCallable!c);
static assert( isCallable!(c.opCall));
static assert( isCallable!S);
static assert( isCallable!(I.value));
static assert( isCallable!((int a) { return a; }));

static assert(!isCallable!I);

Templates

void f()() { }
T g(T = int)(T x) { return x; }
struct S1 { static void opCall()() { } }
struct S2 { static T opCall(T = int)(T x) {return x; } }

static assert( isCallable!f);
static assert( isCallable!g);
static assert( isCallable!S1);
static assert( isCallable!S2);

Overloaded functions and function templates.

static struct Wrapper
{
    void f() { }
    int f(int x) { return x; }

    void g()() { }
    T g(T = int)(T x) { return x; }
}

static assert(isCallable!(Wrapper.f));
static assert(isCallable!(Wrapper.g));

Meta