www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Function signature testing with is expression.

reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
Hi,

Have someone tried to test a function against a signature using 
is expression?

Suppose:
--------
struct F {
     static void foo(T)(T i, int o) {}
}

enum bool check(T) = is(F.foo!T == void function(Z, int), Z);

enum correct = check!int;
--------

Upon running it will return false, though, by logic is expression 
could deduce that F.foo is conformat to function signature in 
check test.

It is interesting that it will not work with global functions as 
well:

--------
void foo(int i, double d) {};
enum bool check = is(typeof(foo) == void function(int, double));
--------

It will be as well evaluated to false.

So, the question is, is it I'm doing something wrong, that it 
doesn't work, or is it not implemented?
If not implemented, what simple and short alternatives are 
available?

Thanks.
Dec 17 2017
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 12/17/2017 06:44 AM, Alexandru Ermicioi wrote:

 It is interesting that it will not work with global functions as well:

 --------
 void foo(int i, double d) {};
 enum bool check = is(typeof(foo) == void function(int, double));
 --------
There, the address-of operator is missing. This works: void foo(int i, double d) {}; static assert(is(typeof(&foo) == void function(int, double))); Ali
Dec 17 2017
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On Sunday, 17 December 2017 at 14:44:15 UTC, Alexandru Ermicioi 
wrote:
 Suppose:
 --------
 struct F {
     static void foo(T)(T i, int o) {}
 }

 enum bool check(T) = is(F.foo!T == void function(Z, int), Z);

 enum correct = check!int;
 --------

 Upon running it will return false, though, by logic is 
 expression could deduce that F.foo is conformat to function 
 signature in check test.
Here, `F.foo!T` is the function itself, not its type. You forgot `typeof`.
 It is interesting that it will not work with global functions 
 as well:

 --------
 void foo(int i, double d) {};
 enum bool check = is(typeof(foo) == void function(int, double));
 --------

 It will be as well evaluated to false.
Write `typeof(&foo)` to make it work. There are two kinds of function types in D: 1) "Proper" function types, e.g. `typeof(foo)` which gets printed as "void(int i, double d)", and 2) function pointer types, e.g. `typeof(&foo)` which gets printed as "void function(int i, double d)". As you see, the second kind is the one you're comparing against. I don't think you can use the first kind directly in an IsExpression. The first kind is really rather useless, as far as I know. Argubaly, the language would be nicer without it.
Dec 17 2017
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Sunday, 17 December 2017 at 16:19:00 UTC, ag0aep6g wrote:
 On Sunday, 17 December 2017 at 14:44:15 UTC, Alexandru Ermicioi 
 wrote:
 Suppose:
 --------
 struct F {
     static void foo(T)(T i, int o) {}
 }

 enum bool check(T) = is(F.foo!T == void function(Z, int), Z);

 enum correct = check!int;
 --------

 Upon running it will return false, though, by logic is 
 expression could deduce that F.foo is conformat to function 
 signature in check test.
Here, `F.foo!T` is the function itself, not its type. You forgot `typeof`.
 It is interesting that it will not work with global functions 
 as well:

 --------
 void foo(int i, double d) {};
 enum bool check = is(typeof(foo) == void function(int, 
 double));
 --------

 It will be as well evaluated to false.
Write `typeof(&foo)` to make it work. There are two kinds of function types in D: 1) "Proper" function types, e.g. `typeof(foo)` which gets printed as "void(int i, double d)", and 2) function pointer types, e.g. `typeof(&foo)` which gets printed as "void function(int i, double d)". As you see, the second kind is the one you're comparing against. I don't think you can use the first kind directly in an IsExpression. The first kind is really rather useless, as far as I know. Argubaly, the language would be nicer without it.
Thanks for help, ag0aep6g and Ali. Now it is more clear why it didn't work. Although I did try to use FunctionTypeOf, which failed, and it seems due to explanation about two kinds of function types. It seems that FunctionTypeOf returns first kind which does not work with is expression, and not second. See the example (first line): ------------------ import std.traits; struct T { static void coo(M)(M e, int i); } void main() { pragma(msg, is(FunctionTypeOf!(&T.coo!int) == void function(Z, int), Z)); pragma(msg, is(FunctionTypeOf!(&T.coo!X) == void function(X, int), X)); pragma(msg, is(typeof(&T.coo!int) == void function(Z, int), Z)); pragma(msg, is(typeof(&T.coo!X) == void function(X, int), X)); } ------------------ If run, first line will return false (even without &). The initial question was related actually to another thing that I've tried to do, which is pattern matching on templated functions. It failed, see line 2, and 4. It seems that now it is impossible to do pattern matching on templates, only on instantiated types. Is there any possibility to check the internals of a template without instantiating it? It would be good for using Policy pattern where you want for example to test passed policy, has a templated function with a desired signature for it.
Dec 17 2017