Re: Constraining template with function signature

2016-06-12 Thread Carl Vogel via Digitalmars-d-learn

On Thursday, 9 June 2016 at 19:08:52 UTC, cy wrote:
But it's probably clearer to use that is(typeof({ how this 
function will be called })) trick.


A very delayed thanks to both of you. It does seem like it would 
be useful to have something like a hasSignature!(Fun, Ret, 
Args...) defined in std.traits. But Steven's solution is pretty 
good.


Thanks again!


Re: Constraining template with function signature

2016-06-09 Thread cy via Digitalmars-d-learn

The other way is better, but since you asked...

On Wednesday, 8 June 2016 at 01:42:55 UTC, Carl Vogel wrote:
Now, I can use something like isCallable std.traits to make 
sure the predicate is a Callable, and there are various 
function traits in the module that I could combine with `is` 
clauses to enforce the signature it seems, but that seems very 
clunky.  Is there a better way?


You could put all that stuff into one single template like this:

template isCompatibleCallable(alias Src, alias Dest) {
 static assert(isSomeFunction!Src || isCallable!Src,
   "Source is not callable");
 static assert(isSomeFunction!Dest || isCallable!Dest,
   "Destination is not callable");

  static assert(is(ParameterTypeTuple!Src == 
ParameterTypeTuple!Dest),

"Type Tuples differ");
  pragma(msg,ParameterStorageClassTuple!Src ==
ParameterStorageClassTuple!Dest);
  static assert(ParameterStorageClassTuple!Src ==
ParameterStorageClassTuple!Dest,
"Storage classes differ");
  static assert(is(ReturnType!Src == ReturnType!Dest),
"Return type differs");
  immutable bool isCompatibleFunction = true;
}

That works if you have a "default action" when the callable isn't 
specified, because you can match the Callable to the default one. 
So like...


bool default_less(T)(T a, T b) { return a < b; }

T[] sortArray(alias less = default_less!T, T)(T[] arr) 
if(isCompatibleCallable(less,default_less!T) { ... }


But it's probably clearer to use that is(typeof({ how this 
function will be called })) trick.


Re: Constraining template with function signature

2016-06-07 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/7/16 9:42 PM, Carl Vogel wrote:

Hi,

What's the best way, when using a Callable as a template parameter, to
constrain it by signature?

For example, if you have a function that sorts an array like so:

T[] sortArray(alias less, T)(T[] arr) { ... }

Then you know that you'd want `less` to have signature (T, T) -> bool.

Now, I can use something like isCallable std.traits to make sure the
predicate is a Callable, and there are various function traits in the
module that I could combine with `is` clauses to enforce the signature
it seems, but that seems very clunky.  Is there a better way?

I note that I don't find many examples of this in phobos, so I'm
wondering if there actually is a good solution...


The de-facto way to do this is to write a lambda, and check that you can 
call the function inside the lambda, then check to see if that compiles.


e.g.:

if(is(typeof( { bool b = less(T.init, T.init)); } )))

The is(typeof( construct means "does this have a valid type". Should 
only work if the call is sound.


You can also use __traits(compiles, but for some reason Phobos writers 
prefer the is(typeof( mechanism (I remember someone saying there is a 
difference, but I don't know what it is).


-Steve


Constraining template with function signature

2016-06-07 Thread Carl Vogel via Digitalmars-d-learn

Hi,

What's the best way, when using a Callable as a template 
parameter, to constrain it by signature?


For example, if you have a function that sorts an array like so:

T[] sortArray(alias less, T)(T[] arr) { ... }

Then you know that you'd want `less` to have signature (T, T) -> 
bool.


Now, I can use something like isCallable std.traits to make sure 
the predicate is a Callable, and there are various function 
traits in the module that I could combine with `is` clauses to 
enforce the signature it seems, but that seems very clunky.  Is 
there a better way?


I note that I don't find many examples of this in phobos, so I'm 
wondering if there actually is a good solution...


Thanks,
-c.