// file : XSCRT/Traversal.hpp // author : Boris Kolpackov #ifndef XSCRT_TRAVERSAL_HPP #define XSCRT_TRAVERSAL_HPP #include #include #include #include "ace/XML_Utils/XSCRT/ExtendedTypeInfo.hpp" namespace XSCRT { namespace Traversal { // // // template class TraverserBase { protected: virtual ~TraverserBase (); //@@ VC6 public: virtual void trampoline (B& n) = 0; virtual void trampoline (B const& n) = 0; }; // // // template class DispatcherBase { public: virtual ~DispatcherBase (); virtual void dispatch (B& n); virtual void dispatch (B const& n); void map (TypeId id, TraverserBase& t) { //wcerr << "map for " << id.name () << " to " << &t // << " in " << &traversal_map_ << endl; //@@ VC6 Traversers& traversers = traversal_map_[id]; traversers.push_back (&t); } public: typedef std::vector*> Traversers; typedef std::map TraversalMap; typedef typename TraversalMap::const_iterator Iterator; Iterator begin () const { return traversal_map_.begin (); } Iterator end () const { return traversal_map_.end (); } private: struct TypeInfoComparator { bool operator () (ExtendedTypeInfo const& x, ExtendedTypeInfo const& y) const { return x.type_id () < y.type_id (); } }; typedef std::map LevelMap; typedef std::set TypeInfoSet; static unsigned long compute_levels (ExtendedTypeInfo const& ti, unsigned long cur, LevelMap& map); static void flatten_tree (ExtendedTypeInfo const& ti, TypeInfoSet& set); private: TraversalMap traversal_map_; }; // // // template class Dispatcher : public virtual DispatcherBase { public: Dispatcher () : merge_ (true) { } void traverser (DispatcherBase& d) { for (typename DispatcherBase::Iterator i (d.begin ()), end (d.end ()); i != end; ++i) { for (typename DispatcherBase::Traversers::const_iterator t (i->second.begin ()), end (i->second.end ()); t != end; ++t) { dispatcher_.map (i->first, **t); } } } public: virtual void dispatch (B& n) { merge (); dispatcher_.dispatch (n); } virtual void dispatch (B const& n) { merge (); dispatcher_.dispatch (n); } using DispatcherBase::begin; using DispatcherBase::end; private: void merge () { if (merge_) { for (typename DispatcherBase::Iterator i (begin ()), e (end ()); i != e; ++i) { for (typename DispatcherBase::Traversers::const_iterator t (i->second.begin ()), e (i->second.end ()); t != e; ++t) { dispatcher_.map (i->first, **t); } } merge_ = false; } } protected: // DispatcherBase& // traverser () // { // return dispatcher_; // } template void iterate_and_dispatch (I begin, I end, X& x, void (X::*next)(A&), A& a) { for (; begin != end;) { dispatch (*begin); if (++begin != end) (x.*next) (a); } } private: bool merge_; DispatcherBase dispatcher_; }; // // // template struct Traverser : TraverserBase, virtual Dispatcher { typedef T Type; Traverser () { DispatcherBase::map (typeid (Type), *this); } virtual void traverse (Type&) { abort (); } virtual void traverse (Type const&) { abort (); } protected: virtual void trampoline (B& n) { //wcerr << "trampoline for " << &n << " to type " // << typeid (Type).name () << endl; traverse (dynamic_cast (n)); } virtual void trampoline (B const& n) { //wcerr << "trampoline for " << &n << " to type " // << typeid (Type).name () << endl; traverse (dynamic_cast (n)); } }; } } #include #endif // XSCRT_TRAVERSAL_HPP