Listing 11

class PrintRecord
{
    std::ostream& stream_;
    ObjectPath path_;
public:
    PrintRecord(std::ostream& out):stream_(out){}
    template<class ReflectedClass> void 
    print(const ReflectedClass& PrintThis)
    {
        path_.reset();
        path_.increaseDimension("");
        depthFirstForeachIncBaseClasses(PrintThis,*this);
        path_.decreaseDimension();
        stream_ << std::endl;
    }
    // useful for printing base classes
    template<class ReflectedClass> void 
    operator()(const ReflectedClass& PrintThis)
    {        
        stream_ << ReflectedClass::getClassName() << ":\t";
    }
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType& value,NameTag,const Scope*)
    {
        stream_ << path_ << ": " << value << ";\t";
    }
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType&, NameTag,EnterAttributeTag,const Scope*)
    {
        path_.prepareNext(Scope::getAttributeName(NameTag()));
    }
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType&, NameTag,LeaveAttributeTag,const Scope*)
    {/* no op*/}
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType&,NameTag , EnterReflectedClassTag, 
                    const Scope*)
    {
        path_.increaseDimension("");
    }
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType&,NameTag , LeaveReflectedClassTag , 
                    const Scope*)
    {
        path_.decreaseDimension();
    }
    template<class CollectionType, class NameTag,class Scope> 
    void operator()(const CollectionType&, NameTag ,
                    EnterCollectionTag, const Scope*)
    {
        path_.increaseDimension();
    }
    template<class CollectionType, class NameTag,class Scope> 
    void operator()(const CollectionType&, NameTag, 
                    LeaveCollectionTag, const Scope*)
    {
        path_.decreaseDimension();
    }
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType& value,
                NameTag attributeTag, EnterCollItemTag,
                const Scope* scope)
    { /* no op*/        }
    template<class ValueType, class NameTag,class Scope> 
    void operator()(const ValueType& value,NameTag attributeTag,
                    LeaveCollItemTag, const Scope* scope)
    {
        path_.prepareNext();
    }
};