@@ -7611,6 +7611,8 @@ enum bool isSomeFunction(alias T) =
76117611/**
76127612Detect whether `T` is a callable object, which can be called with the
76137613function call operator `$(LPAREN)...$(RPAREN)`.
7614+
7615+ $(NOTE Implicit Function Template Instantiation is *not* attempted - see below.)
76147616 */
76157617template isCallable (alias callable)
76167618{
@@ -7634,7 +7636,7 @@ template isCallable(alias callable)
76347636 }
76357637}
76367638
7637- // / Functions, lambdas, and aggregate types with (static) opCall .
7639+ // / Functions, function pointers, delegates, lambdas .
76387640@safe unittest
76397641{
76407642 void f () { }
@@ -7643,6 +7645,17 @@ template isCallable(alias callable)
76437645 static assert ( isCallable! f);
76447646 static assert ( isCallable! g);
76457647
7648+ auto fp = &f;
7649+ static assert ( isCallable! fp);
7650+ static assert ( isCallable! ((int x) {}));
7651+
7652+ int x;
7653+ static assert (! isCallable! x);
7654+ }
7655+
7656+ // / Aggregate types with (static) opCall.
7657+ @safe unittest
7658+ {
76467659 class C { int opCall (int ) { return 0 ; } }
76477660 auto c = new C;
76487661 struct S { static int opCall (int ) { return 0 ; } }
@@ -7657,7 +7670,7 @@ template isCallable(alias callable)
76577670 static assert (! isCallable! I);
76587671}
76597672
7660- // / Templates
7673+ // / Template functions are only detected if they are instantiable with `!()`.
76617674@safe unittest
76627675{
76637676 void f ()() { }
@@ -7669,9 +7682,11 @@ template isCallable(alias callable)
76697682 static assert ( isCallable! g);
76707683 static assert ( isCallable! S1 );
76717684 static assert ( isCallable! S2 );
7685+
7686+ static assert (! isCallable! ((x) {}));
76727687}
76737688
7674- // / Overloaded functions and function templates.
7689+ // / Overloaded functions and function templates instantiable with `!()` .
76757690@safe unittest
76767691{
76777692 static struct Wrapper
0 commit comments