Re: How do you call an eponymous template that has a secondary template arg?

2018-03-12 Thread aliak via Digitalmars-d-learn

On Monday, 12 March 2018 at 04:15:23 UTC, Simen Kjærås wrote:

Yeah, that's a little hole in the grammar, but there are ways:

// Declare an alias:
alias aliasOfInt = aliasOf!int;

// And use that:
assert(!aliasOfInt!string);


Or use std.meta.Instantiate:

assert(!Instantiate!(aliasOf!int, string));

--
  Simen


Noice! Did not know about instantiate.

Btw: I just tried this and it worked, to my surprise!:

template aliasOf(T) {
auto aliasOf(U)(U) { return is(U == T); }
enum aliasOf(alias a) = aliasOf!int(a);
}

void main() {
writeln(aliasOf!int(3)); // works
writeln(allSatisfy!(aliasOf!int, 3)); // works
}




Re: How do you call an eponymous template that has a secondary template arg?

2018-03-11 Thread Simen Kjærås via Digitalmars-d-learn

On Sunday, 11 March 2018 at 12:05:56 UTC, aliak wrote:

* aliasOf!int!"string" // multiple ! arguments are not allowed
* (aliasOf!int)!"string" // error c-style cast
* aliasOf!int.aliasOf!"string" // template isAliasOf(alias a) 
does not have property 'isAliasOf


Yeah, that's a little hole in the grammar, but there are ways:

// Declare an alias:
alias aliasOfInt = aliasOf!int;

// And use that:
assert(!aliasOfInt!string);


Or use std.meta.Instantiate:

assert(!Instantiate!(aliasOf!int, string));

--
  Simen


Re: How do you call an eponymous template that has a secondary template arg?

2018-03-11 Thread aliak via Digitalmars-d-learn

On Sunday, 11 March 2018 at 13:44:38 UTC, Basile B. wrote:


The first version works here:

```
template aliasOf(T) {
enum aliasOf(alias a) = is(typeof(a) == T);
}

string s;

pragma(msg, allSatisfy!(aliasOf!string, s, "string"));
```



I can see that my description was a little confusing, sorry about 
that, I meant to ask how would you call that without using the 
allSatisfy meta template. If I were to call it as a stand alone, 
ie:


writeln(aliasOf!stringtemplate?>);


I hope that makes it clearer.


Now on the fact that what is done is correct is another story.
If the literal passed is supposed to be a type then it's 
clearly wrong.

You'd have to mix it:

```
template aliasOf(T)
{
template aliasOf(alias a)
{
mixin("alias A = " ~ a ~ ";");
enum aliasOf = is(A == T);
}
}

alias myString1 = string;
alias myString2 = string;

pragma(msg, allSatisfy!(aliasOf!string, "myString1", 
"myString2"));

```


Aye, I see what you mean, but it is supposed to be a literal of a 
specific type. I.e. 3, "some string", SomeType(), etc.


So aliasOf!int.aliasOf!3 // true

Also, if I define it like this:

template aliasOf(T) {
auto aliasOf(U)(U) { return is(U == T); }
}

Then at least I can call it like:

writeln(aliasOf!int(3)); // prints true

But then I can't do:

allSatisfy!(aliasOf!int, 3)

I guess because it's a function now and not a template anymore so 
can't be used by allSatisfy.








Re: How do you call an eponymous template that has a secondary template arg?

2018-03-11 Thread Basile B. via Digitalmars-d-learn

On Sunday, 11 March 2018 at 12:05:56 UTC, aliak wrote:

Eg:

template aliasOf(T) {
enum aliasOf(alias a) = is(typeof(a) == T);
}

The use case for this is for std.meta.allSatisfy for variadic 
args, i.e.


template T(values...) if (allSatisfy!(aliasOf!string, values) { 
... }


But how do you call that template otherwise?

I've tries:

* aliasOf!int!"string" // multiple ! arguments are not allowed
* (aliasOf!int)!"string" // error c-style cast
* aliasOf!int.aliasOf!"string" // template isAliasOf(alias a) 
does not have property 'isAliasOf


I can work around this by:

template typeOf(T) {
enum isAliasedBy(alias a) = is(typeof(a) == T);
}

and then do:

template T(values...) if 
(allSatisfy!(typeOf!string.isAliasedBy, values) { ... }


But I like the readability of the former better if there's a 
way to achieve it?


Cheers
- Ali


The first version works here:

```
template aliasOf(T) {
enum aliasOf(alias a) = is(typeof(a) == T);
}

string s;

pragma(msg, allSatisfy!(aliasOf!string, s, "string"));
```

Now on the fact that what is done is correct is another story.
If the literal passed is supposed to be a type then it's clearly 
wrong.

You'd have to mix it:

```
template aliasOf(T)
{
template aliasOf(alias a)
{
mixin("alias A = " ~ a ~ ";");
enum aliasOf = is(A == T);
}
}

alias myString1 = string;
alias myString2 = string;

pragma(msg, allSatisfy!(aliasOf!string, "myString1", 
"myString2"));

```