1 static string func(int) { return ""; } 2 auto funcPtr = &func; 3 4 static assert( is(ToFunctionType!(SymbolType!func) == SymbolType!func)); 5 static assert( is(ToFunctionType!(SymbolType!funcPtr) == SymbolType!func)); 6 static assert(!is(SymbolType!funcPtr == function)); 7 static assert( is(ToFunctionType!(SymbolType!funcPtr) == function)); 8 9 int var; 10 int funcWithContext(string) { return var; } 11 auto funcDel = &funcWithContext; 12 13 static assert( is(ToFunctionType!(SymbolType!funcWithContext) == 14 SymbolType!funcWithContext)); 15 static assert( is(ToFunctionType!(SymbolType!funcDel) == 16 SymbolType!funcWithContext)); 17 static assert( is(SymbolType!funcWithContext == function)); 18 static assert(!is(SymbolType!funcDel == function)); 19 static assert( is(SymbolType!funcDel == delegate)); 20 static assert( is(ToFunctionType!(SymbolType!funcDel) == function)); 21 22 static @property int prop() { return 0; } 23 static assert( is(SymbolType!prop == function)); 24 static assert(!is(SymbolType!prop == delegate)); 25 static assert( is(SymbolType!prop == return)); 26 static assert( is(SymbolType!prop == 27 ToFunctionType!(int function() @property @safe pure 28 nothrow @nogc))); 29 static assert( is(ToFunctionType!(SymbolType!prop) == SymbolType!prop)); 30 31 // This is an example of why SymbolType should be used rather than typeof 32 // when using ToFunctionType (or getting the type of any symbol which might 33 // be a function when you want the actual type of the symbol and don't want 34 // to end up with its return type instead). 35 static assert( is(typeof(prop) == int)); 36 static assert(!is(typeof(prop) == function)); 37 static assert(!__traits(compiles, ToFunctionType!(typeof(prop)))); 38 39 auto propPtr = ∝ 40 static assert(!is(typeof(propPtr) == function)); 41 static assert(!is(SymbolType!propPtr == function)); 42 static assert( isFunctionPointer!(typeof(propPtr))); 43 static assert( is(ToFunctionType!(SymbolType!propPtr) == function)); 44 45 static assert( is(SymbolType!propPtr == 46 int function() @property @safe pure nothrow @nogc)); 47 static assert(!is(ToFunctionType!(SymbolType!propPtr) == 48 int function() @property @safe pure nothrow @nogc)); 49 static assert( is(ToFunctionType!(SymbolType!propPtr) == 50 ToFunctionType!(int function() @property @safe pure 51 nothrow @nogc))); 52 53 @property void propWithContext(int i) { var += i; } 54 static assert( is(SymbolType!propWithContext == function)); 55 static assert( is(SymbolType!propWithContext == 56 ToFunctionType!(void function(int) @property @safe pure 57 nothrow @nogc))); 58 static assert( is(ToFunctionType!(SymbolType!propWithContext) == 59 SymbolType!propWithContext)); 60 61 // typeof fails to compile with setter properties, complaining about there 62 // not being enough arguments, because it's treating the function as an 63 // expression - and since such an expression would call the function, the 64 // expression isn't valid if there aren't enough function arguments. 65 static assert(!__traits(compiles, typeof(propWithContext))); 66 67 auto propDel = &propWithContext; 68 static assert(!is(SymbolType!propDel == function)); 69 static assert( is(SymbolType!propDel == delegate)); 70 static assert( is(SymbolType!propDel == return)); 71 static assert( is(ToFunctionType!(SymbolType!propDel) == function)); 72 static assert( is(ToFunctionType!(SymbolType!propDel) == 73 SymbolType!propWithContext)); 74 75 static assert( is(SymbolType!propDel == 76 void delegate(int) @property @safe pure nothrow @nogc)); 77 static assert(!is(ToFunctionType!(SymbolType!propDel) == 78 void delegate(int) @property @safe pure nothrow @nogc)); 79 static assert(!is(ToFunctionType!(SymbolType!propDel) == 80 void function(int) @property @safe pure nothrow @nogc)); 81 static assert( is(ToFunctionType!(SymbolType!propDel) == 82 ToFunctionType!(void function(int) @property @safe pure 83 nothrow @nogc))); 84 85 // Delegates have a funcptr property and a ptr property (which can only be 86 // used in @system code) which give the pointer to the function and the 87 // pointer to the context respectively. 88 static assert( is(ToFunctionType!(SymbolType!propDel) == 89 typeof(*SymbolType!propDel.funcptr))); 90 static assert( is(typeof(SymbolType!propDel.ptr) == void*)); 91 92 static struct S 93 { 94 string foo(int); 95 string bar(int, int); 96 @property void prop(string); 97 } 98 99 static assert( is(ToFunctionType!(SymbolType!(S.foo)) == 100 ToFunctionType!(string function(int)))); 101 static assert( is(ToFunctionType!(SymbolType!(S.bar)) == 102 ToFunctionType!(string function(int, int)))); 103 static assert( is(ToFunctionType!(SymbolType!(S.prop)) == 104 ToFunctionType!(void function(string) @property)));
Converts a function type, function pointer type, or delegate type to the corresponding function type.
For a function, the result is the same as the given type.
For a function pointer or delegate, the result is the same as it would be for a function with the same return type, the same set of parameters, and the same set of attributes.
Another way to look at it would be that it's the type that comes from dereferencing the function pointer. And while it's not technically possible to dereference a delegate, it's conceptually the same thing, since a delegate is essentially a fat pointer to a function in the sense that it contains a pointer to a function and a pointer to the function's context. The result of ToFunctionType is the type of that function.
Note that code which has a symbol which is a function should use SymbolType rather than $(K_TYPEOF) to get the type of the function in order to avoid issues with regards to $(K_PROPERTY) (see the documentation for SymbolType for details).