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