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