Good suggestion but I dislike the syntax for mixin template for this use case. It looks like:
bool every(string file = __FILE__, int line = __LINE__)(int time) { static int counter; if(++counter > time) counter -= time; return counter == 1; } works just fine. Hmmm! On Tue, May 10, 2011 at 9:52 PM, Jonathan M Davis <jmdavisp...@gmx.com> wrote: > On 2011-05-10 17:32, Jose Armando Garcia wrote: >> Hey guys, >> >> I am trying to create a function that return true or executes >> "something" the n-th time it is called from a specific call site. How >> would you do that in D? In C we can do that with the help of >> pre-processor macros. E.g.: >> >> --- >> #include <assert.h> >> >> #define EVERY(N, ACTION) { static int counter = 0; if(++counter > (N)) >> counter -= (N); if(counter == 1) (ACTION); } >> >> int main() >> { >> int i = 0; >> int j = 0; >> while(i < 10) >> { >> EVERY(10, ++j); >> EVERY(2, ++i); >> } >> assert(j == 2); >> assert(i == 10); >> } >> --- >> >> In D, I hacked the following implementation. I don't like this >> implementation for a log of reason... Am I missing some D feature? Can >> someone do better? >> >> --- >> int[string] map; >> >> bool every(string file = __FILE__, int line = __LINE__)(int time) >> { >> // assume file ~ "+" ~ to!string(line) is unique >> // assumption could be removed by using a struct >> string key = file ~ "+" ~ to!string(line); >> >> map[key] += 1; >> if(map[key] > time) map[key] -= time; >> >> return map[key] == 1; >> } >> >> unittest >> { >> auto i = 0; >> auto j = 0; >> while(i < 10) >> { >> if(every(10)) ++j; >> if(every(2)) ++i; >> } >> assert(j == 2); >> assert(i == 10); >> } >> >> void main() {} >> --- > > My suggestion would be to use a string mixin. It would do essentially the same > thing that the macro does. > > - Jonathan M Davis >