Listing 3
(a)
class Link
{
protected:
virtual void *v_traverse(void *) = 0;
public:
virtual Link *clone(void) const = 0;
virtual size_t get_size(void) const { return 1; }
};
template<class Src, class Dst>
class Typed_Link : public Link
{
protected:
void *v_traverse(void *src)
{
return (void *)&traverse(*(Src *)src);
}
public:
Dst &traverse(Src &) = 0;
};
(b)
template<class Src, class Dst>
class Chain : private std::list<Link *>, public Typed_Link<Src, Dst>
{
public:
// special constructors
template<class Mid>
Chain(const Typed_Link<Src,Mid> &a, const Typed_Link<Mid,Dst> &b);
// etc.
size_t get_size(void) const
{
size_t ret = 0;
for (const_iterator i = begin(); i != end(); ++i) {
ret += (*i)->get_size();
}
return ret;
}
Dst &traverse(Src &s)
{
void *tmp = &s;
iterator i;
try {
for (i = begin(); i != end(); ++i) {
tmp = (*i)->v_traverse(tmp);
}
}
// (exception handlers here)
// ...
return *(Dst *)tmp;
}
};
// spc: this simplifies the object definitions
template<class Src, class Mid, class Dst>
class Chain<Src, Dst>
operator+(const Typed_Link<Src, Mid> &a,
const Typed_Link<Mid, Dst> &b)
{
return Chain<Src, Dst>(a, b);
}