Re: Template constraint on alias template parameter.

2020-08-06 Thread jmh530 via Digitalmars-d-learn

On Thursday, 6 August 2020 at 18:09:50 UTC, ag0aep6g wrote:

[snip]

`is(...)` only works on types. You're looking for 
`__traits(isSame, T, Foo)`.


For `is(T!U == Foo!U, U)` to work, the compiler would have to 
guess U. If the first guess doesn't work, it would have to 
guess again, and again, and again, until it finds a U that does 
work. Could take forever.


Thanks for the explanation!


Re: Template constraint on alias template parameter.

2020-08-06 Thread ag0aep6g via Digitalmars-d-learn

On Thursday, 6 August 2020 at 16:01:35 UTC, jmh530 wrote:
The code below compiles, but I want to put an additional 
constraint on the `test` function is only called with a Foo 
struct.


I tried things like is(T == Foo) and is(T : Foo), but those 
don't work. However, something like is(T!int : Foo!int) works, 
but is(T!U == Foo!U, U) doesn't. Any idea why is(T!U == Foo!U, 
U) doesn't work?


struct Foo(T)
{
T x;
}

void test(alias T)()
if (__traits(isTemplate, T))
{
import std.stdio: writeln;
writeln("there");
}

void main()
{
test!Foo();
}


`is(...)` only works on types. You're looking for 
`__traits(isSame, T, Foo)`.


For `is(T!U == Foo!U, U)` to work, the compiler would have to 
guess U. If the first guess doesn't work, it would have to guess 
again, and again, and again, until it finds a U that does work. 
Could take forever.


Re: Template constraint on alias template parameter.

2020-08-06 Thread jmh530 via Digitalmars-d-learn

On Thursday, 6 August 2020 at 16:01:35 UTC, jmh530 wrote:

[snip]


It seems as if the T is properly Foo(T) and can only be 
instantiated with actual types. Something like below works and 
might work for me.


template test(alias T)
if (__traits(isTemplate, T))
{
void test(U)(U x)
if (is(T!U : Foo!U))
{
import std.stdio: writeln;
writeln("there");
}
}


Template constraint on alias template parameter.

2020-08-06 Thread jmh530 via Digitalmars-d-learn
The code below compiles, but I want to put an additional 
constraint on the `test` function is only called with a Foo 
struct.


I tried things like is(T == Foo) and is(T : Foo), but those don't 
work. However, something like is(T!int : Foo!int) works, but 
is(T!U == Foo!U, U) doesn't. Any idea why is(T!U == Foo!U, U) 
doesn't work?


struct Foo(T)
{
T x;
}

void test(alias T)()
if (__traits(isTemplate, T))
{
import std.stdio: writeln;
writeln("there");
}

void main()
{
test!Foo();
}



Re: Alias template parameter to a private function

2017-06-29 Thread Sebastien Alaiwan via Digitalmars-d-learn

On Thursday, 29 June 2017 at 20:21:13 UTC, Ali Çehreli wrote:

A workaround is to use a lambda:

  filter!(a => isValid(a))(array)


Thanks! Nice trick, this is definitely going into my company's 
codebase :-)


Such limitations are pretty annoying. There were a number of 
similar issues in recent dmd releases. Please file a bug if 
it's not already there:


Thanks, will do!


Re: Alias template parameter to a private function

2017-06-29 Thread Ali Çehreli via Digitalmars-d-learn

On 06/24/2017 02:04 AM, Sebastien Alaiwan wrote:

> private:
>
> void privateFunction1()
> {
>   auto array = [0, 1, 2, 3, 4, 5];
>   auto result = filter!isValid(array); // error: 'isValid' is private
> }

> bool isValid(int i)
> {
>   return i % 2 == 0;
> }

A workaround is to use a lambda:

  filter!(a => isValid(a))(array)

Such limitations are pretty annoying. There were a number of similar 
issues in recent dmd releases. Please file a bug if it's not already there:


  https://issues.dlang.org/

Ali



Re: Alias template parameter to a private function

2017-06-29 Thread Sebastien Alaiwan via Digitalmars-d-learn

up please!


Alias template parameter to a private function

2017-06-24 Thread Sebastien Alaiwan via Digitalmars-d-learn

Hi,

I'm trying to call std.algorithm.iteration.filter with a private 
function as a predicate.

Here's a reduced example code:

// yo.d
import std.algorithm;

void moduleEntryPoint()
{
  privateFunction1();
  privateFunction2();
}

private:

void privateFunction1()
{
  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is 
private

}

void privateFunction2()
{
  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is 
private

}

bool isValid(int i)
{
  return i % 2 == 0;
}

Here's the compiler output:

/usr/include/dmd/phobos/std/algorithm/iteration.d(1132): Error: 
function yo.isValid is not accessible from module iteration
yo.d(14): Error: template instance 
std.algorithm.iteration.filter!(isValid).filter!(int[]) error 
instantiating


This seems like the compiler, when instanciating the calls to 
'filter', is resolving 'isValid' from std.algorithm.iteration 
scope (however, this isn't actually the case, see below).
I was expecting this identifier to be resolved from yo.d, where 
we have access to the private functions.


Surprisingly, the following works:

void privateFunction2()
{
  static bool isValid(int i)
  {
return i % 2 == 0;
  }

  auto array = [0, 1, 2, 3, 4, 5];
  auto result = filter!isValid(array); // error: 'isValid' is 
private

}

This makes the instanciation of 'filter' "see" 'isValid', 
however, now, the other privateFunctions can't use it.


Am I missing something here?
Thanks!



Re: Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread jkpl via Digitalmars-d-learn

On Thursday, 9 February 2017 at 15:00:21 UTC, angel wrote:

On Thursday, 9 February 2017 at 14:39:41 UTC, angel wrote:

On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote:

I'm looking for a better way to do this, if possible:


Or actually, maybe this will suite your case better:
```
template namedTool(T, alias Variable)
{
enum namedTool = T.stringof ~ " " ~ Variable ~ " = new " ~ 
T.stringof ~ ";" ~

 Variable ~ ".name = \"" ~ Variable ~ "\";";
}

void main()
{
mixin(namedTool!(Tool, "grep"));
assert(grep.name == "grep");
}
```


Thanks for trying. I know that it doesn't make much sense but it 
would have been a cool sugar for the tool class.


Mixins are not good for me because of completion in the IDE.


Re: Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread angel via Digitalmars-d-learn

On Thursday, 9 February 2017 at 14:39:41 UTC, angel wrote:

On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote:

I'm looking for a better way to do this, if possible:

```
class Tool
{
string name;
}

T namedTool(alias Variable, T)()
{
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep,Tool);
assert(grep.name == "grep");
}
```

Ideally this would work like this:

```
Tool grep = namedTool!Tool;
assert(grep.name == "grep");
```

Possible ?


Sorry, but this does not make much sense to me ...
You expect "namedTool!Tool" to know that the name of the Tool 
must be set to "grep".
The expression evaluation proceeds from right to left, so at 
the time of analyzing "namedTool!Tool", the compiler knows 
nothing about "grep".
On the other hand, if you supplied the "grep" variable, the 
compiler could infer its type, like this:

```
...
auto namedTool(alias Variable)()
{
alias T = typeof(Variable);
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep);
assert(grep.name == "grep");
}
```


Or actually, maybe this will suite your case better:
```
template namedTool(T, alias Variable)
{
enum namedTool = T.stringof ~ " " ~ Variable ~ " = new " ~ 
T.stringof ~ ";" ~

 Variable ~ ".name = \"" ~ Variable ~ "\";";
}

void main()
{
mixin(namedTool!(Tool, "grep"));
assert(grep.name == "grep");
}
```


Re: Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread angel via Digitalmars-d-learn

On Thursday, 9 February 2017 at 13:30:07 UTC, jkpl wrote:

I'm looking for a better way to do this, if possible:

```
class Tool
{
string name;
}

T namedTool(alias Variable, T)()
{
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep,Tool);
assert(grep.name == "grep");
}
```

Ideally this would work like this:

```
Tool grep = namedTool!Tool;
assert(grep.name == "grep");
```

Possible ?


Sorry, but this does not make much sense to me ...
You expect "namedTool!Tool" to know that the name of the Tool 
must be set to "grep".
The expression evaluation proceeds from right to left, so at the 
time of analyzing "namedTool!Tool", the compiler knows nothing 
about "grep".
On the other hand, if you supplied the "grep" variable, the 
compiler could infer its type, like this:

```
...
auto namedTool(alias Variable)()
{
alias T = typeof(Variable);
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep);
assert(grep.name == "grep");
}
```


Factory using an alias template parameter to set a member of the new tool ?

2017-02-09 Thread jkpl via Digitalmars-d-learn

I'm looking for a better way to do this, if possible:

```
class Tool
{
string name;
}

T namedTool(alias Variable, T)()
{
T result = new T;
result.name = Variable.stringof;
return result;
}

void main()
{
Tool grep;
grep = namedTool!(grep,Tool);
assert(grep.name == "grep");
}
```

Ideally this would work like this:

```
Tool grep = namedTool!Tool;
assert(grep.name == "grep");
```

Possible ?


Re: alias template parameter

2016-01-24 Thread Marc Schütz via Digitalmars-d-learn

On Friday, 21 June 2013 at 14:08:43 UTC, Sergei Nosov wrote:

If I have a function
auto apply(alias fun, T...)(T args)
{
return fun(args);
}

And then I have
int y = 2;
apply!(x => y)(1);

How in the world does this work? Is the context address known 
at compile-time?


No, but because lambdas are always unique, there will always be a 
dedicated template instance for every time you do this. The 
compiler will then hard-wire that instance to make it able to 
access the context pointer. By the way, you can also pass local 
variables by alias, in which case the same will happen. I guess 
it does so by passing the offset of the variable in the current 
stack frame (unless it's inlined and optimized, of course), but I 
don't know the details. I guess it's up to the compiler.


Re: alias template parameter

2016-01-23 Thread QAston via Digitalmars-d-learn

On Friday, 21 June 2013 at 14:08:43 UTC, Sergei Nosov wrote:

Hi!

I've been thinking about how alias template parameters work and 
I'm really confused =)


It makes perfect sense for literals, names, etc. But what I 
can't get is how does it work for delegates.


If I have a function
auto apply(alias fun, T...)(T args)
{
return fun(args);
}

And then I have
int y = 2;
apply!(x => y)(1);

How in the world does this work? Is the context address known 
at compile-time?


y is allocated on the heap and the pointer is implicitly passed 
to the apply, or is a field of a struct if you use map!(x => y) 
instead.


alias template parameter

2013-06-21 Thread Sergei Nosov

Hi!

I've been thinking about how alias template parameters work and 
I'm really confused =)


It makes perfect sense for literals, names, etc. But what I can't 
get is how does it work for delegates.


If I have a function
auto apply(alias fun, T...)(T args)
{
return fun(args);
}

And then I have
int y = 2;
apply!(x => y)(1);

How in the world does this work? Is the context address known at 
compile-time?