// file : xsd-frontend/traversal/elements.hxx // author : Boris Kolpackov // copyright : Copyright (c) 2005-2010 Code Synthesis Tools CC // license : GNU GPL v2 + exceptions; see accompanying LICENSE file #ifndef XSD_FRONTEND_TRAVERSAL_ELEMENTS_HXX #define XSD_FRONTEND_TRAVERSAL_ELEMENTS_HXX #include #include #include namespace XSDFrontend { namespace Traversal { using namespace Cult::Types; namespace Bits { using FrontendElements::Traversal::TraverserBase; using FrontendElements::Traversal::Traverser; using FrontendElements::Traversal::DispatcherBase; using FrontendElements::Traversal::Dispatcher; } typedef Bits::DispatcherBase NodeDispatcherBase; typedef Bits::DispatcherBase EdgeDispatcherBase; // // struct NodeBase : virtual Bits::Dispatcher, virtual Bits::Dispatcher { Void edge_traverser (EdgeDispatcherBase& d) { Bits::Dispatcher::traverser (d); } EdgeDispatcherBase& edge_traverser () { return *this; } public: using Bits::Dispatcher::dispatch; using Bits::Dispatcher::dispatch; using Bits::Dispatcher::map; using Bits::Dispatcher::iterate_and_dispatch; }; // // template struct Node : Bits::TraverserBase, virtual NodeBase { typedef T Type; Node () { map (typeid (Type), *this); } virtual Void traverse (Type&) = 0; virtual Void trampoline (SemanticGraph::Node& i) { traverse (dynamic_cast (i)); } virtual Void trampoline (SemanticGraph::Node const&) { abort (); } }; // // struct EdgeBase : virtual Bits::Dispatcher, virtual Bits::Dispatcher { Void node_traverser (NodeDispatcherBase& d) { Bits::Dispatcher::traverser (d); } NodeDispatcherBase& node_traverser () { return *this; } public: using Bits::Dispatcher::dispatch; using Bits::Dispatcher::dispatch; using Bits::Dispatcher::map; using Bits::Dispatcher::iterate_and_dispatch; }; template struct Edge : Bits::TraverserBase, virtual EdgeBase { typedef T Type; Edge () { map (typeid (Type), *this); } virtual Void traverse (Type&) = 0; virtual Void trampoline (SemanticGraph::Edge& i) { traverse (dynamic_cast (i)); } virtual Void trampoline (SemanticGraph::Edge const&) { abort (); } }; inline EdgeBase& operator>> (NodeBase& n, EdgeBase& e) { n.edge_traverser (e); return e; } inline NodeBase& operator>> (EdgeBase& e, NodeBase& n) { e.node_traverser (n); return n; } // Edges // // // struct Names : Edge { Names () { } Names (NodeBase& n) { node_traverser (n); } virtual Void traverse (Type& e) { dispatch (e.named ()); } }; // // struct Belongs : Edge { Belongs () { } Belongs (NodeBase& n) { node_traverser (n); } virtual Void traverse (Type& e) { dispatch (e.type ()); } }; // Nodes // // // struct Nameable : Node { }; // // template struct ScopeTemplate : Node { public: virtual Void traverse (T& s) { names (s); } template Void names (T& s, EdgeDispatcherBase& d, Void (X::*pre_) (T&) = (Void (ScopeTemplate::*)(T&)) (0), Void (X::*post_) (T&) = (Void (ScopeTemplate::*)(T&)) (0), Void (X::*none_) (T&) = (Void (ScopeTemplate::*)(T&)) (0), Void (X::*next_) (T&) = (Void (ScopeTemplate::*)(T&)) (0)) { X* this_ (dynamic_cast (this)); typename T::NamesIterator b (s.names_begin ()), e (s.names_end ()); if (b != e) { if (pre_) (this_->*pre_) (s); //iterate_and_dispatch (b, e, d, *this_, next_, s); for (; b != s.names_end ();) { d.dispatch (*b); if (++b != s.names_end () && next_ != 0) (this_->*next_) (s); } if (post_) (this_->*post_) (s); } else { if (none_) (this_->*none_) (s); } } virtual Void names (T& s, EdgeDispatcherBase& d) { names > (s, d); } virtual Void names (T& s) { names (s, *this, &ScopeTemplate::names_pre, &ScopeTemplate::names_post, &ScopeTemplate::names_none, &ScopeTemplate::names_next); } virtual Void names_pre (T&) { } virtual Void names_next (T&) { } virtual Void names_post (T&) { } virtual Void names_none (T&) { } }; // // typedef ScopeTemplate Scope; // // struct Type : Node { virtual Void traverse (SemanticGraph::Type&) = 0; }; // // struct Instance : Node { virtual Void traverse (Type&); virtual Void pre (Type&); virtual Void belongs (Type&, EdgeDispatcherBase&); virtual Void belongs (Type&); virtual Void post (Type&); }; // // struct Member : Node { virtual Void traverse (Type&); virtual Void pre (Type&); virtual Void belongs (Type&, EdgeDispatcherBase&); virtual Void belongs (Type&); virtual Void post (Type&); }; // // struct Inherits : Edge { Inherits () { } Inherits (NodeBase& n) { node_traverser (n); } virtual Void traverse (Type& e) { dispatch (e.base ()); } }; // // struct Extends : Edge { Extends () { } Extends (NodeBase& n) { node_traverser (n); } virtual Void traverse (Type& e) { dispatch (e.base ()); } }; // // struct Restricts : Edge { Restricts () { } Restricts (NodeBase& n) { node_traverser (n); } virtual Void traverse (Type& e) { dispatch (e.base ()); } }; // // struct Argumented : Edge { Argumented () { } Argumented (NodeBase& n) { node_traverser (n); } virtual Void traverse (Type& a) { dispatch (a.type ()); } }; /* // // struct Contains : Edge { virtual Void traverse (Type& e) { dispatch (e.element ()); } }; */ // // typedef Node AnyType; // // typedef Node AnySimpleType; } } #include #endif // XSD_FRONTEND_TRAVERSAL_ELEMENTS_HXX