Hi,

I have a problem with extending some existing code. In a simplified

form, the problem looks like this:

I have four types, A, B, C, and D. Each A refers to zero, one, or more

B's and each B can be child to zero, one, or more A's. I just call that

"A is a parent of B", and "B is a child of A". The same goes for B and

C and for C and D. So A is only a parent, B and C are both parents and

children, and D is only a child.

I have many algorithms dealing with these. Most them are templates and

work on either all types, or all parent types, or all child types (and

some even only work on grandparent types). For this to work, the types

look somewhat like this:

// Beware, uncompiled code ahead!

struct tmp_nil {};

template<bool b> struct tmp_bool { enum {result=b}; };

class A;

class B;

class C;

class D;

class A {

public:

typedef tmp_bool<false> is_child;

typedef tmp_bool<true > is_parent;

typedef B child_t;

};

class B {

public:

typedef tmp_bool<true > is_child;

typedef tmp_bool<true > is_parent;

typedef A parent_t;

typedef C child_t;

};

class C {

public:

typedef tmp_bool<true > is_child;

typedef tmp_bool<true > is_parent;

typedef B parent_t;

typedef D child_t;

};

class D {

public:

typedef tmp_bool<true > is_child;

typedef tmp_bool<false> is_parent;

typedef C parent_t;

};

For example, if some algorithm needs to work on a type and recursivly

on all children and grandchildren, what the code does is this:

class some_class {

public:

//...

// this is called by users and does the recursive downstepping

template<class T> void some_algorithm(const T& obj)

{

// do some real work with 'obj'

detail::some_algorithm_(obj,typename T::is_parent()); // recurse

}

//...

private:

//...

// some_algorithm()'s implementation for parents

template<class T> void some_algorithm_(const T& obj, tmp_bool<true > /*is_parent*/)

{

for( <all children refered to by 'obj'> ) {

typename T::child_t& child = /*...*/;

some_algorithm(child);

}

}

// some_algorithm()'s implementation for childless types

template<class T> void some_algorithm_(const T& obj, tmp_bool<false> /*is_parent*/)

{

// no children, so nothing to do here

}

//...

};

This worked all very well for years. However, now my task is to introduce

some type B2, that's also a child to A (but not a parent to C):

class B2 {

public:

typedef tmp_bool<true > is_child;

typedef tmp_bool<false> is_parent;

typedef A parent_t;

};

Now, I suppose parents would need to change like this:

template<typename Head, class Tail> struct tmp_list {};

class A {

public:

typedef tmp_bool<false> is_child;

typedef tmp_bool<true > is_parent;

typedef tmp_list< B, tmp_list<C,tmp_nil> >

child_list;

};

I know how to deal with such recursive type lists. However, I only know

how to do this with _class_ templates. But it's _functon_ templates that

I have as algorithms, and they are stuck in some class (the 'some_class'

in the example above above) that provides all the necessary functionality

(retrieve objects etc.) for them. (And they also need to be members of it

because 'some_class', in reality being a friend to A, B, C, and D, is the

only thing that can actually get at the relevant information -- which is

not needed by users of A, B, C, and D.)

So given

template<class T> void some_class::some_algorithm_(const T&,tmp_bool<true>)

how can I make it call

template<class T> void some_class::some_algorithm(const T&)

for _all_ children in the child list of (the new version of) A?

As for the constraints I'm working under: The code is "mine". I am free

to change it as I need as long as the public interface doesn't change

more than ansolutely necessary. It is, however, quite a lot of code,

with many algorithms that have been maintained and fixed for years. And,

as always, the deadline is a rather tight one.

That's why I want to "implant" B2 with as little changes as necessary.

Right now it seems it's just a syntactic problem.

TIA,

Schobi

--

Sp******@gmx.de is never read

I'm Schobi at suespammers dot org

"The sarcasm is mightier than the sword."

Eric Jarvis