Factoring out looping structure
Denis Koroskin
2korden at gmail.com
Mon Apr 6 13:48:28 PDT 2009
On Tue, 07 Apr 2009 00:33:04 +0400, Doctor J <nobody at nowhere.com> wrote:
> I'm new to template programming and I have a problem for which I think
> it would be a good match, but I'd like to get some advice on how to go
> about it.
>
> I have a family of algorithms with the same looping structure, but
> different particulars:
>
> ------------------------
> state_t state ;
> for (int i = 0 ; i < imax ; ++i)
> {
> compute_i(state, i);
> for (int j = 0 ; j < jmax ; ++j)
> {
> compute_j(state,i,j);
> for (int k = 0 ; k < kmax ; ++k)
> {
> compute_k(state,i,j,k);
> for (int m = 0 ; m < mmax ; ++m)
> {
> compute_m(state,i,j,k,m);
> }
> finish_k(state,i,j,k);
> }
> finish_j(state,i,j);
> }
> }
> --------------------------
>
> I'd like to factor out the particulars from the looping structure, so I
> can write the loops once and then implement a bunch of variants with
> different particulars (the looping structure is in fact more complicated
> than the abstract example given). Obviously I could do this by passing
> in an object implementing an interface with all my functions; however,
> the whole point of this exercise is to avoid the overhead of function
> calls. The code needs to be efficient, and (especially the inner loop)
> functions need to be inlined.
>
> So: what are my options in D? Templates, delegates, mixins...? I'd
> like to avoid string mixins if possible because they're a bit ugly.
>
> Thanks!
>
An obvious way is to do a straight convertion:
template (alias compute_i, alias compute_j, alias compute_k, alias compute_m, alias finish_k, alias finish_j, int imax, int jmax, int kmax, int mmax)
{
void compure(State)(ref State state)
{
for (int i = 0; i < imax; ++i)
{
compute_i(state, i);
for (int j = 0; j < jmax; ++j)
{
compute_j(state,i,j);
for (int k = 0; k < kmax; ++k)
{
compute_k(state,i,j,k);
for (int m = 0; m < mmax; ++m)
{
compute_m(state,i,j,k,m);
}
finish_k(state,i,j,k);
}
finish_j(state,i,j);
}
}
}
}
Usage:
void foo(ref State state, int i) { ... }
void bar(ref State state, int i, int j) { ... }
void baz(ref State state, int i, int j, int k) { ... }
void qux(ref State state, int i, int j, int k, int m) { ... }
void corge(ref State state, int i, int j, int k) { ... }
void grault(ref State state, int i, int j) { ... }
void garply(ref State state, int i) { ... }
struct State
{
// ...
}
State state;
compute!(foo,bar,baz,quz,corge,grault,garply)(state); // state is modified and stores a result (pass nothing if it's not needed)
More information about the Digitalmars-d-learn
mailing list