On Thursday, 29 October 2015 at 06:02:05 UTC, qsdf wrote:
On Thursday, 29 October 2015 at 02:43:59 UTC, Shammah
Chancellor wrote:
....
I agree with you on an aspect: writing code with __traits()
often leads to a cascade of "unfriendly", "cryptic",
"undigest", static if and loops.
However your examples are discutables:
1/ The symbol is not always a type, so to test it there is
`if(is()){}`:
---
import std.stdio;
enum hack(A...) = A;
int main() {
foreach(member; __traits(allMembers, std.stdio)) {
pragma(msg, member);
static if (is(member))
alias sym = hack!(__traits(getMember, std.stdio,
member))[0];
}
}
---
The point is that you cannot use is() without first using
getMember, but using __traits(getMember) before
__traits(compiles) generates an error. In your example you're
trying to use `is` on a string, which does not work.
2/ with only one way to define the alias it works, whatever is
the function type (property or not)
---
import std.traits, std.stdio, std.typetuple;
private template MemberType(C, string memberName)
{
alias member = TypeTuple!(__traits (getMember, C,
memberName))[0];
static if (isSomeFunction!(typeof(&member)))
alias MemberType = typeof(&member);
else static assert(0, "not handled here !");
}
struct Hop
{
void foo(uint a){}
@property uint bar(){return 0;}
uint baz(){return 0;}
@property void bla(uint h){}
}
void main()
{
MemberType!(Hop, "foo").stringof.writeln;
MemberType!(Hop, "bar").stringof.writeln;
MemberType!(Hop, "baz").stringof.writeln;
MemberType!(Hop, "bla").stringof.writeln;
}
---
And you snipped out important sections of code for dealing with
fields. The following code now will not compile:
getType.d(7): Error: need 'this' for address of bob
getType.d(27): Error: template instance getType.MemberType!(Hop,
"bob") error instantiating
```
struct Hop
{
int bob;
}
void main()
{
MemberType!(Hop, "bob").stringof.writeln;
}
```
3/ Your example doesn't compile
Sorry, try this:
```
import std.stdio : writeln;
import std.typetuple;
// This won't work:
/+
private template stuff(Args...) {
/+ static +/ foreach(Arg; Args) {
...
}
}
+/
// Must do this instead:
private template expand(Args...)
{
static if (Args.length > 0)
{
static if (Args.length > 1)
{
enum expand = AliasSeq!(repeat!(Args[0], Args.length),
expand!(Args[1..$]));
}
else static if (Args.length == 1)
{
enum expand = AliasSeq!(repeat!(Args[0], Args.length));
}
}
}
private template repeat(alias T, int times) {
static if ( times > 1 ) {
enum repeat = AliasSeq!(T, repeat!(T, times-1));
} else static if (times == 1) {
enum repeat = AliasSeq!(T);
}
}
enum things = expand!("A","B","C");
void main() {
pragma(msg, things);
writeln("Hello World");
}
```