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