// file : odb/semantics/relational/elements.hxx // copyright : Copyright (c) 2009-2013 Code Synthesis Tools CC // license : GNU GPL v3; see accompanying LICENSE file #ifndef ODB_SEMANTICS_RELATIONAL_ELEMENTS_HXX #define ODB_SEMANTICS_RELATIONAL_ELEMENTS_HXX #include #include #include #include #include #include #include #include #include namespace semantics { namespace relational { using namespace cutl; using std::string; using container::graph; using container::pointer_iterator; using compiler::context; // // class node; class edge; // // class edge: public context { public: virtual ~edge () {} public: template bool is_a () const { return dynamic_cast (this) != 0; } }; // // class node: public context { public: virtual ~node () {} // Return name of the node. // virtual string kind () const = 0; public: template bool is_a () const { return dynamic_cast (this) != 0; } // Sink functions that allow extensions in the form of one-way // edges. // public: void add_edge_right (edge&) { } }; // // template class scope; template class nameable; // // template class names: public edge { public: typedef N name_type; typedef relational::scope scope_type; typedef relational::nameable nameable_type; name_type const& name () const { return name_; } scope_type& scope () const { return *scope_; } nameable_type& nameable () const { return *nameable_; } public: names (name_type const& name): name_ (name) {} void set_left_node (scope_type& n) { scope_ = &n; } void set_right_node (nameable_type& n) { nameable_ = &n; } protected: name_type name_; scope_type* scope_; nameable_type* nameable_; }; typedef names unames; typedef names qnames; // // template class nameable: public virtual node { public: typedef N name_type; typedef relational::names names_type; typedef relational::scope scope_type; name_type const& name () const { return named_->name (); } scope_type& scope () const { return named ().scope (); } names_type& named () const { return *named_; } public: // Id identifies the C++ node (e.g., a class or a data member) that // this model node corresponds to. The ids are not necessarily unique // (e.g., there can be a foreign key and an index with the same id that // correspond to a container member). However, in any given scope, the // {id,typeid} must be unique. This becomes important when we try to // find correspondance between nodes during model diff'ing. // nameable (string const& id): id_ (id), named_ (0) {} void add_edge_right (names_type& e) { assert (named_ == 0); named_ = &e; } using node::add_edge_right; private: string id_; names_type* named_; }; typedef nameable unameable; typedef nameable qnameable; // // struct duplicate_name { template duplicate_name (relational::scope&, relational::nameable& orig, relational::nameable& dup); node& scope; node& orig; node& dup; string name; }; template class scope: public virtual node { protected: typedef N name_type; typedef relational::names names_type; typedef relational::nameable nameable_type; typedef std::list names_list; typedef std::map names_map; typedef std::map names_iterator_map; public: typedef pointer_iterator names_iterator; typedef pointer_iterator names_const_iterator; public: // Iteration. // names_iterator names_begin () { return names_.begin (); } names_iterator names_end () { return names_.end (); } names_const_iterator names_begin () const { return names_.begin (); } names_const_iterator names_end () const { return names_.end (); } // Find. // names_iterator find (name_type const&); names_const_iterator find (name_type const&) const; names_iterator find (names_type const&); names_const_iterator find (names_type const&) const; public: scope () : first_key_ (names_.end ()) { } void add_edge_left (names_type&); private: names_list names_; names_map names_map_; names_iterator_map iterator_map_; typename names_list::iterator first_key_; }; typedef scope uscope; typedef scope qscope; } } #include #endif // ODB_SEMANTICS_RELATIONAL_ELEMENTS_HXX