// file : XSCRT/Traversal.tpp // author : Boris Kolpackov // cvs-id : $Id: Traversal.tpp 95833 2012-06-06 14:53:45Z johnnyw $ namespace XSCRT { namespace Traversal { // TraverserBase // // template TraverserBase:: ~TraverserBase () { } // DispatcherBase // // template DispatcherBase:: ~DispatcherBase () { } //@@ merge after dropping VC6 // // template void DispatcherBase:: dispatch (B& n) { LevelMap levels; //@@ VC6 ExtendedTypeInfo const& ti = extended_type_info (n); unsigned long max = compute_levels (ti, 0, levels); //wcerr << "starting dispatch process for " // << typeid (n).name () << " with " // << max << " levels" << endl; for (unsigned long l = 0; l < max + 1; ++l) { TypeInfoSet dispatched; for (typename LevelMap::const_iterator i (levels.begin ()), e (levels.end ()); i != e; ++i) { if (i->second == l) { typename TraversalMap::const_iterator v ( traversal_map_.find (i->first.type_id ())); if (v != traversal_map_.end ()) { //wcerr << "dispatching traversers for " // << typeid (n).name () << " as " // << i->first.type_id ().name () << endl; //@@ VC6 Traversers const& traversers = v->second; for (typename Traversers::const_iterator ti (traversers.begin ()), te (traversers.end ()); ti != te; ++ti) { (*ti)->trampoline (n); } flatten_tree (i->first, dispatched); } } } // Remove traversed types from the level map. // //@@ VC6 { for (typename TypeInfoSet::const_iterator i = dispatched.begin (); i != dispatched.end (); ++i) { levels.erase (*i); } } } } template void DispatcherBase:: dispatch (B const& n) { LevelMap levels; //@@ VC6 ExtendedTypeInfo const& ti = extended_type_info (n); unsigned long max = compute_levels (ti, 0, levels); //wcerr << "starting dispatch process for " // << typeid (n).name () << " with " // << max << " levels" << endl; //wcerr << "using " << &traversal_map_ << " traversal map" << endl; for (unsigned long l = 0; l < max + 1; ++l) { TypeInfoSet dispatched; for (typename LevelMap::const_iterator i (levels.begin ()), e (levels.end ()); i != e; ++i) { if (i->second == l) { typename TraversalMap::const_iterator v ( traversal_map_.find (i->first.type_id ())); if (v != traversal_map_.end ()) { //wcerr << "dispatching traversers for " // << typeid (n).name () << " as " // << i->first.type_id ().name () << endl; //@@ VC6 Traversers const& traversers = v->second; for (typename Traversers::const_iterator ti (traversers.begin ()), te (traversers.end ()); ti != te; ++ti) { (*ti)->trampoline (n); } flatten_tree (i->first, dispatched); } } } // Remove traversed types from the level map. // //@@ VC6 { for (typename TypeInfoSet::const_iterator i = dispatched.begin (); i != dispatched.end (); ++i) { levels.erase (*i); } } } } template unsigned long DispatcherBase:: compute_levels (ExtendedTypeInfo const& ti, unsigned long cur, LevelMap& map) { unsigned long ret = cur; if (map.find (ti) == map.end () || map[ti] < cur) map[ti] = cur; for (ExtendedTypeInfo::BaseIterator i = ti.begin_base (); i != ti.end_base (); i++) { unsigned long t = compute_levels (i->type_info (), cur + 1, map); if (t > ret) ret = t; } return ret; } template void DispatcherBase:: flatten_tree (ExtendedTypeInfo const& ti, TypeInfoSet& set) { set.insert (ti); for (ExtendedTypeInfo::BaseIterator i = ti.begin_base (); i != ti.end_base (); i++) { flatten_tree (i->type_info (), set); } } } }