Is using function() in templates possible at all?

2018-04-11 Thread Sjoerd Nijboer via Digitalmars-d-learn

I am trying to do a binary insert into my sorted array.
To sort classes and structs I would like to give a delegate `(t) 
=> t.myValue` to sort on that value whitout having to implement 
an interface or specifically declare opCmp for every class I want 
to have sorted.
After all, I might want one group of objects of a given class 
sorted in one way and another group of objects sorted on another 
way depending on the usecase.
In C# this is done by passing on a lambda in for instance a LinQ 
expression to sort such list after insertion, and is also usefull 
in other circumstances.


But is it possible in D to do something simular but then pass on 
this Function() during compile time?


something like
`
void main() { SortedList!(Vector3, (v) => v.y) list; }

struct Vector3 { float x, y, z; }

class SortedList(T, int function(T) comparer)
{
T[] array;

int foo(T t)
{
for(int i = 0; i < array.lenght; i++)
{
if(comparer(this.otherT) <=  comparer(t))
{
//do stuff
array[i] = t;
}
}
}
}
`



Re: Is using function() in templates possible at all?

2018-04-11 Thread Alex via Digitalmars-d-learn

On Wednesday, 11 April 2018 at 21:07:03 UTC, Sjoerd Nijboer wrote:


class SortedList(T, int function(T) comparer)


I would say, alias template parameter is your friend.
https://dlang.org/spec/template.html#TemplateAliasParameter

´´´
import std.stdio;
import std.range;

void main()
{
auto list = new SortedList!(Vector3, v => v.y)();

assert(list.array.empty);
list.foo(Vector3.init);
}

struct Vector3 { float x, y, z; }

class SortedList(T, alias comparer)
{
T[] array;

auto foo(T t)
{
for(int i = 0; i < array.length; i++)
{
if(comparer(this.array[i]) <=  comparer(t))
{
//do stuff
array[i] = t;
}
}
}
}
´´´


Re: Is using function() in templates possible at all?

2018-04-11 Thread Sjoerd Nijboer via Digitalmars-d-learn

On Wednesday, 11 April 2018 at 21:29:27 UTC, Alex wrote:

I would say, alias template parameter is your friend.
https://dlang.org/spec/template.html#TemplateAliasParameter

class SortedList(T, alias comparer)


It works, thank you!
But just to be shure, there's no way to have this more strongly 
typed in D so I can enforce that `comparer`is a funciton or 
delegate with a specific defenition?
Right now i'm relying on the template to error on some different 
place which might not give such a readable error message to the 
user.


Re: Is using function() in templates possible at all?

2018-04-11 Thread Nicholas Wilson via Digitalmars-d-learn

On Wednesday, 11 April 2018 at 22:13:33 UTC, Sjoerd Nijboer wrote:

On Wednesday, 11 April 2018 at 21:29:27 UTC, Alex wrote:

I would say, alias template parameter is your friend.
https://dlang.org/spec/template.html#TemplateAliasParameter

class SortedList(T, alias comparer)


It works, thank you!
But just to be shure, there's no way to have this more strongly 
typed in D so I can enforce that `comparer`is a funciton or 
delegate with a specific definition?



There is, with template constraints:

class SortedList(T, alias comparer) if(is(typeof(comparer(T.init) 
: int))

{
//...
}


Re: Is using function() in templates possible at all?

2018-04-12 Thread Laurent Tréguier via Digitalmars-d-learn

On Thursday, 12 April 2018 at 00:05:26 UTC, Nicholas Wilson wrote:

There is, with template constraints:

class SortedList(T, alias comparer)
if(is(typeof(comparer(T.init) : int))
{
//...
}


If the function is declared with explicit parameter types:
```
auto list = new SortedList!(Vector3, (Vector3 v) => v.y)();
```

Then the template guard can even have a full type definition:
```
class SortedList(T, alias comparer)
if (is(typeof(comparer) :  int function(T)))
{
//...
}
```


Re: Is using function() in templates possible at all?

2018-04-12 Thread Alex via Digitalmars-d-learn
On Thursday, 12 April 2018 at 11:17:01 UTC, Laurent Tréguier 
wrote:

If the function is declared with explicit parameter types:


There are cool things possible, if the param type is explicitly 
typed :)


´´´
import std.traits;

void main()
{
auto list = new SortedList!((Vector3 v) => v.y)();
list.foo(Vector3.init);
}

struct Vector3 { float x, y, z; }

class SortedList(alias comparer) if(is(ReturnType!comparer : 
float))

{
alias T = Parameters!comparer[0];

T[] array;

auto foo(T t)
{
// do stuff
}
}
´´´


Re: Is using function() in templates possible at all?

2018-04-12 Thread Laurent Tréguier via Digitalmars-d-learn

On Thursday, 12 April 2018 at 11:53:21 UTC, Alex wrote:
On Thursday, 12 April 2018 at 11:17:01 UTC, Laurent Tréguier 
wrote:

If the function is declared with explicit parameter types:


There are cool things possible, if the param type is explicitly 
typed :)


´´´
import std.traits;

void main()
{
auto list = new SortedList!((Vector3 v) => v.y)();
list.foo(Vector3.init);
}

struct Vector3 { float x, y, z; }

class SortedList(alias comparer) if(is(ReturnType!comparer : 
float))

{
alias T = Parameters!comparer[0];

T[] array;

auto foo(T t)
{
// do stuff
}
}
´´´


Getting rid of redundancy. Now that's nice !