Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
March 11, 2018 How do you call an eponymous template that has a secondary template arg? | ||||
---|---|---|---|---|
| ||||
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 |
March 11, 2018 Re: How do you call an eponymous template that has a secondary template arg? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | 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"));
```
|
March 11, 2018 Re: How do you call an eponymous template that has a secondary template arg? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Basile B. | 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. |
March 12, 2018 Re: How do you call an eponymous template that has a secondary template arg? | ||||
---|---|---|---|---|
| ||||
Posted in reply to aliak | 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 |
March 12, 2018 Re: How do you call an eponymous template that has a secondary template arg? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | 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 } |
Copyright © 1999-2021 by the D Language Foundation