On Sunday, 3 May 2015 at 21:46:11 UTC, Robert M. Münch wrote:
Hi, I have now played a around couple of hours (reading everything I could find) to get something to work, but I think I'm missing some basic concepts/understanding. Maybe someone can enlighten me how these things work. I thought that some code from David Nadlinger is what I'm searching for but don't know how to exactly make use of it.

Here is the code: I want to filter out some of the "allMembers" and use them in my code for a switch/final to check that call cases that were not filtered are covered. Trying to build the enum for the switch/final statement.

auto org_rules = TypeTuple!(__traits(allMembers,BolSource));
static assert(!isTypeTuple!(org_rules));

template startsNotWith(T,char C){
   static if (T[0] != C){
       enum startsNotWith = true;
   } else {
       enum startsNotWith = false;
   }
}

Here T would have to be a type. But you want to accept a string. So:
----
template startsNotWith(string s,char c){
    enum startsNotWith = s.length == 0 || s[0] != c;
}
----

template StaticFilter(alias pred, T...) {
 static if (T.length == 0) {
   alias TypeTuple!() StaticFilter;
 } else static if (pred!(T[0])) {
alias TypeTuple!(T[0], StaticFilter!(pred, T[1 .. $])) StaticFilter;
 } else {
   alias StaticFilter!(pred, T[1 .. $]) StaticFilter;
 }
}

alias startsNotWithp = startsNotWith!(T,"p"); // doesn't compile: Error: undefined identifier T

You need to turn T into a parameter, so that StaticFilter can set it. (And it's really a string again, so I'm renaming to s.)

----
template startsNotWithp(string s)
{
    enum startsNotWithp = startsNotWith!(s, 'p');
}
/* Shorthand syntax: enum startsNotWithp(string s) = startsNotWith!(s, 'p'); */
----

alias rules = StaticFilter!(startsNotWithp, org_rules);


While playing with this a couple of questions came up:

1. How do predicates get their argument(s)? I saw code where only the predicate was mentioned but no arguments. So, I assume there is some behind-the-curtain-magic going on. I read about things like "a == b" where I can reference 'a and 'b in a string.

Predicates are called/instantiated by the thing to which you pass them. StaticFilter instantiates pred for each element of the T tuple it's given. If some documentation doesn't say how the predicate will be called/instantiated, then it's probably assumed to be obvious.

String predicates are turned into functions behind the curtains. The thing you instantiate with "a == b" turns it into `(a, b) {return a == b;}` and uses that. I think we don't do string predicates for templates like StaticFilter, though.

2. "enum startsNotwith = false" So this is the return syntax for a CTFE for "return(true)" ?

It's the template syntax for "return false". CTFE does normal functions at compile time, so there it's just "return false".

----
/* Template: */
template t() {enum t = false;}
enum x = t!();
/* CTFE: */
bool f() {return false;}
enum y = f();
----

3. TupleType is a very missleading name when you are learning these things, because the tuple can hold values as well.

Yup. And std.traits.isTypeTuple only adds to the confusion.

Or is there a more extensive explanation for the name I don't get?

Not that I'm aware of.

4. Are there any tutorials about CTFE? This seems to be a very powerful but not so easy to use feature of D, but documentation is quite limited.

CTFE is rather simple. It just allows you to use certain functions in a static (i.e. compile time) context.

Templates are more tricky. If you mean templates, maybe having the right name helps.

Reply via email to