ToFunctionType

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).

template ToFunctionType (
T
) if (
is(T == return)
) {}

Examples

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)));

See Also

Meta