Factoring out looping structure
BCS
ao at pathlink.com
Mon Apr 6 13:40:27 PDT 2009
Reply to Doctor,
> 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!
>
void Go(T)()
{
T.state_t state ;
for (int i = 0 ; i < imax ; ++i)
{
T.compute_i(state, i);
for (int j = 0 ; j < jmax ; ++j)
{
T.compute_j(state,i,j);
for (int k = 0 ; k < kmax ; ++k)
{
T.compute_k(state,i,j,k);
for (int m = 0 ; m < mmax ; ++m)
{
compute_m(state,i,j,k,m);
}
T.finish_k(state,i,j,k);
}
T.finish_j(state,i,j);
}
}
}
struct T_a
{
static struct state_t { ... } // or alias
static void compute_i(state_t, int i){ ... }
static void compute_j(state_t, int i, int j){ ... }
static void compute_k(state_t, int i, int j, int k){ ... }
static void compute_l(state_t, int i, int j, int k, int l){ ... }
}
Go!(T_a)();
struct T_b
{
static struct state_t { ... } // or alias
static void compute_i(state_t, int i){ ... }
static void compute_j(state_t, int i, int j){ ... }
static void compute_k(state_t, int i, int j, int k){ ... }
static void compute_l(state_t, int i, int j, int k, int l){ ... }
}
Go!(T_b)();
untested but you get the idea
A similar approach can be done replacing (T) with (alias T) and using 'template
T_a()' in places of the structs
More information about the Digitalmars-d-learn
mailing list