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 - AliThe 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