Re: CTFE & template predicates
template startsNotWith(string s,char c){ enum startsNotWith = s.length == 0 || s[0] != c; } Better still: enum startsNotWith(string s, char c) = { return s.length == 0 || s[0] != c; }
Re: CTFE & template predicates
On 5/05/2015 6:24 a.m., Robert M. Münch wrote: On 2015-05-04 03:52:21 +, Rikki Cattermole said: Have you looked at my book? https://leanpub.com/ctfe I bought it. Will it be updated? It's very generic with respect the concept and I'm missing code examples for all the user-cases. Especially the generator part is IMO very interesting. It's due for an update. Basically I just need to be told what people want. Otherwise I'll be doing it blind!
Re: CTFE & template predicates
On 2015-05-04 03:52:21 +, Rikki Cattermole said: Have you looked at my book? https://leanpub.com/ctfe I bought it. Will it be updated? It's very generic with respect the concept and I'm missing code examples for all the user-cases. Especially the generator part is IMO very interesting. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: CTFE & template predicates
On Monday, 4 May 2015 at 11:41:23 UTC, Robert M. Münch wrote: Hi, I have one more questions: Is it possible to write something like this? alias rules = StaticFilter!(startsNotWith(?, 'p'), org_rules); The ? should be used for every memember of org_rules. No, we don't have template literals.
Re: CTFE & template predicates
On Monday, 4 May 2015 at 11:22:16 UTC, Robert M. Münch wrote: Hi, ok, just to better understand this (I have a C++ background (even quite old)): When I want to use some functions I need to specify the type? It's not possible to use T.length() which would compile if T is a string? I thought that it's just generic and I can throw in T. In template parameter lists, a solitary identifier is a type parameter. You can only pass types in those. In function (pointer) declarations, a solitary identifier is the type of the parameter. In function/delegate literals, a solitary identifier is the name of the parameter and the type is inferred. I guess this is what you were thinking of. void main() { template t(T) {} /* T is a template type parameter. */ alias i = t!int; /* It can be instantiated with the type int, for example, */ static assert(!__traits(compiles, t!123)); /* but not with a value. */ void function(int) fp; /* int is the type of the parameter. */ fp = (x) {}; /* x is the name of the parameter whose type is inferred from above. */ }
Re: CTFE & template predicates
On 4/05/2015 11:15 p.m., Robert M. Münch wrote: On 2015-05-04 03:52:21 +, Rikki Cattermole said: Have you looked at my book? https://leanpub.com/ctfe No, thanks for the hint. You will have one more reader ;-) I'm currently live streaming, feel free to jump on and ask any questions! https://www.livecoding.tv/alphaglosined/
Re: CTFE & template predicates
On 2015-05-03 23:28:00 +, anonymous said: 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); Hi, I have one more questions: Is it possible to write something like this? alias rules = StaticFilter!(startsNotWith(?, 'p'), org_rules); The ? should be used for every memember of org_rules. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: CTFE & template predicates
On 2015-05-03 23:28:00 +, anonymous said: 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; } Hi, ok, just to better understand this (I have a C++ background (even quite old)): When I want to use some functions I need to specify the type? It's not possible to use T.length() which would compile if T is a string? I thought that it's just generic and I can throw in T. 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. Well, and often it's obvious that it's not 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. Ok, that helps to better understand how this works. Thanks for the feedback. -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: CTFE & template predicates
On 2015-05-04 03:52:21 +, Rikki Cattermole said: Have you looked at my book? https://leanpub.com/ctfe No, thanks for the hint. You will have one more reader ;-) -- Robert M. Münch http://www.saphirion.com smarter | better | faster
Re: CTFE & template predicates
On 4/05/2015 9:46 a.m., 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; } } 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 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. 2. "enum startsNotwith = false" So this is the return syntax for a CTFE for "return(true)" ? 3. TupleType is a very missleading name when you are learning these things, because the tuple can hold values as well. Or is there a more extensive explanation for the name I don't get? 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. Thanks a lot. Have you looked at my book? https://leanpub.com/ctfe
Re: CTFE & template predicates
On Sunday, 3 May 2015 at 21:46:11 UTC, Robert M. Münch wrote: 3. TupleType is a very missleading name when you are learning these things, because the tuple can hold values as well. Or is there a more extensive explanation for the name I don't get? Legacy we are trying to get rid of. See also: https://github.com/D-Programming-Language/phobos/pull/3128 https://github.com/D-Programming-Language/dlang.org/pull/986
Re: CTFE & template predicates
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.