diff -r d4d182ab75bd -r df2e45e09652 src/hugo/smart_graph.h --- a/src/hugo/smart_graph.h Wed Sep 01 15:37:36 2004 +0000 +++ b/src/hugo/smart_graph.h Thu Sep 02 10:07:30 2004 +0000 @@ -8,15 +8,21 @@ ///\brief SmartGraph and SymSmartGraph classes. #include -#include +#include #include +#include +#include +#include + +#include + namespace hugo { /// \addtogroup graphs /// @{ - class SymSmartGraph; +// class SymSmartGraph; ///A smart graph class. @@ -53,61 +59,27 @@ std::vector edges; - protected: - - template class DynMapBase - { - protected: - const SmartGraph* G; - public: - virtual void add(const Key k) = 0; - virtual void erase(const Key k) = 0; - DynMapBase(const SmartGraph &_G) : G(&_G) {} - virtual ~DynMapBase() {} - friend class SmartGraph; - }; public: - template class EdgeMap; - template class NodeMap; + + typedef SmartGraph Graph; class Node; class Edge; - // protected: - // HELPME: - protected: - ///\bug It must be public because of SymEdgeMap. - /// - mutable std::vector * > dyn_node_maps; - ///\bug It must be public because of SymEdgeMap. - /// - mutable std::vector * > dyn_edge_maps; - - public: - - class NodeIt; class EdgeIt; class OutEdgeIt; class InEdgeIt; - template class NodeMap; - template class EdgeMap; + CREATE_MAP_REGISTRIES; + CREATE_MAPS(ArrayMapFactory); public: SmartGraph() : nodes(), edges() { } SmartGraph(const SmartGraph &_g) : nodes(_g.nodes), edges(_g.edges) { } - ~SmartGraph() - { - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).G=NULL; - for(std::vector * >::iterator i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).G=NULL; - } - int nodeNum() const { return nodes.size(); } //FIXME: What is this? int edgeNum() const { return edges.size(); } //FIXME: What is this? @@ -137,9 +109,8 @@ Node n; n.n=nodes.size(); nodes.push_back(NodeT()); //FIXME: Hmmm... - for(std::vector * >::iterator i=dyn_node_maps.begin(); - i!=dyn_node_maps.end(); ++i) (**i).add(n); - + + node_maps.add(n); return n; } @@ -150,8 +121,7 @@ edges[e.n].next_in=nodes[v.n].first_in; nodes[u.n].first_out=nodes[v.n].first_in=e.n; - for(std::vector * >::iterator i=dyn_edge_maps.begin(); - i!=dyn_edge_maps.end(); ++i) (**i).add(e); + edge_maps.add(e); return e; } @@ -172,7 +142,12 @@ return prev; } - void clear() {nodes.clear();edges.clear();} + void clear() { + edge_maps.clear(); + edges.clear(); + node_maps.clear(); + nodes.clear(); + } class Node { friend class SmartGraph; @@ -290,184 +265,6 @@ // operator bool() { return Edge::operator bool(); } }; - template class NodeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Node KeyType; - - NodeMap(const SmartGraph &_G) : - DynMapBase(_G), container(_G.maxNodeId()) - { - G->dyn_node_maps.push_back(this); - } - NodeMap(const SmartGraph &_G,const T &t) : - DynMapBase(_G), container(_G.maxNodeId(),t) - { - G->dyn_node_maps.push_back(this); - } - - NodeMap(const NodeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_node_maps.push_back(this); - } - - template friend class NodeMap; - - ///\todo It can copy between different types. - ///\todo We could use 'copy' - template NodeMap(const NodeMap &m) : - DynMapBase(*m.G), container(m.container.size()) - { - G->dyn_node_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - ~NodeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=G->dyn_node_maps.begin(); - i!=G->dyn_node_maps.end() && *i!=this; ++i) ; - //if(*i==this) G->dyn_node_maps.erase(i); //FIXME: Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=G->dyn_node_maps.back(); - G->dyn_node_maps.pop_back(); - } - } - } - - void add(const Node k) - { - if(k.n>=int(container.size())) container.resize(k.n+1); - } - - void erase(const Node) { } - - void set(Node n, T a) { container[n.n]=a; } - //'T& operator[](Node n)' would be wrong here - typename std::vector::reference - operator[](Node n) { return container[n.n]; } - //'const T& operator[](Node n)' would be wrong here - typename std::vector::const_reference - operator[](Node n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const NodeMap& operator=(const NodeMap &m) - { - container = m.container; - return *this; - } - template - const NodeMap& operator=(const NodeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for Dynamic Maps - void update(T a) {} //Useless for Dynamic Maps - }; - - template class EdgeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Edge KeyType; - - EdgeMap(const SmartGraph &_G) : - DynMapBase(_G), container(_G.maxEdgeId()) - { - //FIXME: What if there are empty Id's? - //FIXME: Can I use 'this' in a constructor? - G->dyn_edge_maps.push_back(this); - } - EdgeMap(const SmartGraph &_G,const T &t) : - DynMapBase(_G), container(_G.maxEdgeId(),t) - { - G->dyn_edge_maps.push_back(this); - } - EdgeMap(const EdgeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_edge_maps.push_back(this); - } - - template friend class EdgeMap; - - ///\todo It can copy between different types. - template EdgeMap(const EdgeMap &m) - : DynMapBase(*m.G), container(m.container.size()) - { - G->dyn_edge_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - ~EdgeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=G->dyn_edge_maps.begin(); - i!=G->dyn_edge_maps.end() && *i!=this; ++i) ; - //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=G->dyn_edge_maps.back(); - G->dyn_edge_maps.pop_back(); - } - } - } - - void add(const Edge k) - { - if(k.n>=int(container.size())) container.resize(k.n+1); - } - void erase(const Edge) { } - - void set(Edge n, T a) { container[n.n]=a; } - //T get(Edge n) const { return container[n.n]; } - typename std::vector::reference - operator[](Edge n) { return container[n.n]; } - typename std::vector::const_reference - operator[](Edge n) const { return container[n.n]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const EdgeMap& operator=(const EdgeMap &m) - { - container = m.container; - return *this; - } - template - const EdgeMap& operator=(const EdgeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for DynMaps - void update(T a) {} //Useless for DynMaps - }; - }; ///Graph for bidirectional edges. @@ -493,8 +290,14 @@ class SymSmartGraph : public SmartGraph { public: - template class SymEdgeMap; - template friend class SymEdgeMap; + typedef SymSmartGraph Graph; + + KEEP_NODE_MAP(SmartGraph); + KEEP_EDGE_MAP(SmartGraph); + + CREATE_SYM_EDGE_MAP_REGISTRY; + CREATE_SYM_EDGE_MAP_FACTORY(ArrayMapFactory); + IMPORT_SYM_EDGE_MAP(SymEdgeMapFactory); SymSmartGraph() : SmartGraph() { } SymSmartGraph(const SmartGraph &_g) : SmartGraph(_g) { } @@ -517,107 +320,10 @@ return f; } - ///Common data storage for the edge pairs. - - ///This map makes it possible to store data shared by the oppositely - ///directed pairs of edges. - template class SymEdgeMap : public DynMapBase - { - std::vector container; - - public: - typedef T ValueType; - typedef Edge KeyType; - - SymEdgeMap(const SymSmartGraph &_G) : - DynMapBase(_G), container(_G.maxEdgeId()/2) - { - static_cast(G)->dyn_edge_maps.push_back(this); - } - SymEdgeMap(const SymSmartGraph &_G,const T &t) : - DynMapBase(_G), container(_G.maxEdgeId()/2,t) - { - G->dyn_edge_maps.push_back(this); - } - - SymEdgeMap(const SymEdgeMap &m) : - DynMapBase(*m.G), container(m.container) - { - G->dyn_node_maps.push_back(this); - } - - // template friend class SymEdgeMap; - - ///\todo It can copy between different types. - /// - - template SymEdgeMap(const SymEdgeMap &m) - : DynMapBase(*m.G), container(m.container.size()) - { - G->dyn_node_maps.push_back(this); - typename std::vector::const_iterator i; - for(typename std::vector::const_iterator i=m.container.begin(); - i!=m.container.end(); - i++) - container.push_back(*i); - } - - ~SymEdgeMap() - { - if(G) { - std::vector* >::iterator i; - for(i=static_cast(G)->dyn_edge_maps.begin(); - i!=static_cast(G)->dyn_edge_maps.end() - && *i!=this; ++i) ; - //if(*i==this) G->dyn_edge_maps.erase(i); //Way too slow... - //A better way to do that: (Is this really important?) - if(*i==this) { - *i=static_cast(G)->dyn_edge_maps.back(); - static_cast(G)->dyn_edge_maps.pop_back(); - } - } - } - - void add(const Edge k) - { - if(!k.idref()%2&&k.idref()/2>=int(container.size())) - container.resize(k.idref()/2+1); - } - void erase(const Edge k) { } - - void set(Edge n, T a) { container[n.idref()/2]=a; } - //T get(Edge n) const { return container[n.idref()/2]; } - typename std::vector::reference - operator[](Edge n) { return container[n.idref()/2]; } - typename std::vector::const_reference - operator[](Edge n) const { return container[n.idref()/2]; } - - ///\warning There is no safety check at all! - ///Using operator = between maps attached to different graph may - ///cause serious problem. - ///\todo Is this really so? - ///\todo It can copy between different types. - const SymEdgeMap& operator=(const SymEdgeMap &m) - { - container = m.container; - return *this; - } - template - const SymEdgeMap& operator=(const SymEdgeMap &m) - { - std::copy(m.container.begin(), m.container.end(), container.begin()); - return *this; - } - - void update() {} //Useless for DynMaps - void update(T a) {} //Useless for DynMaps - - }; }; /// @} - } //namespace hugo