CTFE & template predicates

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun May 3 16:28:00 PDT 2015


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.


More information about the Digitalmars-d-learn mailing list