digitalmars.D.learn - How do you call an eponymous template that has a secondary template
- aliak (25/25) Mar 11 2018 Eg:
- Basile B. (27/52) Mar 11 2018 The first version works here:
- aliak (21/47) Mar 11 2018 I can see that my description was a little confusing, sorry about
- Simen =?UTF-8?B?S2rDpnLDpXM=?= (10/14) Mar 11 2018 Yeah, that's a little hole in the grammar, but there are ways:
- aliak (11/20) Mar 12 2018 Noice! Did not know about instantiate.
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
Mar 11 2018
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"));
```
Mar 11 2018
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!string<how do I pass argument to inner template?>); 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.
Mar 11 2018
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 'isAliasOfYeah, 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
Mar 11 2018
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)); -- SimenNoice! 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 }
Mar 12 2018









aliak <something something.com> 