// -*- mode:C++ -*- #ifndef SMART_GRAPH_H #define SMART_GRAPH_H #include #include struct _Invalid {} Invalid; namespace hugo { class SmartGraph { // static const int INVALID=-1; // static const int INVALID_NODE=INT_MAX; struct NodeT { int first_in,first_out; NodeT() : first_in(-1), first_out(-1) {} }; struct EdgeT { int head, tail, next_in, next_out; //FIXME: is this necessary? EdgeT() : next_in(-1), next_out(-1) {} }; std::vector nodes; std::vector edges; template class DynMapBase { protected: SmartGraph* G; public: virtual void add(const Key k) = NULL; virtual void erase(const Key k) = NULL; DynMapBase(const SmartGraph &_G) : G(&_G) {} virtual ~DynMapBase() {} friend class SmartGraph; }; public: template class DynEdgeMap; template class DynEdgeMap; class NodeIt; class EdgeIt; protected: mutable std::vector * > dyn_node_maps; mutable std::vector * > dyn_edge_maps; public: class EachNodeIt; class EachEdgeIt; class OutEdgeIt; class InEdgeIt; // class NodeIt { int n; }; // class EachNodeIt : public NodeIt { }; // class EdgeIt { int n; }; // class EachEdgeIt : public EdgeIt {}; // class OutEdgeIt : public EdgeIt {}; // class InEdgeIt : public EdgeIt {}; // class SymEdgeIt; template class NodeMap; template class EdgeMap; public: /* default constructor */ 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? int maxNodeId() const { return nodes.size(); } //FIXME: What is this? int maxEdgeId() const { return edges.size(); } //FIXME: What is this? NodeIt tail(EdgeIt e) const { return edges[e.n].tail; } NodeIt head(EdgeIt e) const { return edges[e.n].head; } // NodeIt aNode(const OutEdgeIt& e) const { return tail(e); } // NodeIt aNode(const InEdgeIt& e) const { return head(e); } // //NodeIt aNode(const SymEdgeIt& e) const { return e.aNode(); } // NodeIt bNode(const OutEdgeIt& e) const { return head(e); } // NodeIt bNode(const InEdgeIt& e) const { return tail(e); } // //NodeIt bNode(const SymEdgeIt& e) const { return e.bNode(); } EachNodeIt& getFirst(EachNodeIt& v) const { v=EachNodeIt(*this); return v; } EachEdgeIt& getFirst(EachEdgeIt& e) const { e=EachEdgeIt(*this); return e; } OutEdgeIt& getFirst(OutEdgeIt& e, const NodeIt v) const { e=OutEdgeIt(*this,v); return e; } InEdgeIt& getFirst(InEdgeIt& e, const NodeIt v) const { e=InEdgeIt(*this,v); return e; } template< typename It > It first() const { It e; getFirst(e); return e; } template< typename It > It first(NodeIt v) const { It e; getFirst(e, v); return e; } bool valid(EdgeIt e) const { return e.n!=-1; } // bool valid(EachEdgeIt e) const { return e.n It getNext(It it) const { It tmp(it); return next(tmp); } //{ It tmp; tmp.n=it.n+1; return tmp; } NodeIt& next(NodeIt& it) const { it.n=(it.n+2)%nodes.size()-1; return it; } OutEdgeIt& next(OutEdgeIt& it) const { it.n=edges[it.n].next_out; return it; } InEdgeIt& next(InEdgeIt& it) const { it.n=edges[it.n].next_in; return it; } EachEdgeIt& next(EachEdgeIt& it) const { --it.n; return it; } int id(NodeIt v) const { return v.n; } int id(EdgeIt e) const { return e.n; } NodeIt addNode() { NodeIt 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.n); return n; } EdgeIt addEdge(NodeIt u, NodeIt v) { EdgeIt e; e.n=edges.size(); edges.push_back(EdgeT()); //FIXME: Hmmm... edges[e.n].tail=u.n; edges[e.n].head=v.n; edges[e.n].next_out=nodes[u.n].first_out; 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); return e; } void clear() {nodes.clear();edges.clear();} class NodeIt { friend class SmartGraph; template friend class NodeMap; template friend class DynNodeMap; friend class EdgeIt; friend class OutEdgeIt; friend class InEdgeIt; friend class SymEdgeIt; protected: int n; friend int SmartGraph::id(NodeIt v) const; NodeIt(int nn) {n=nn;} public: NodeIt() {} NodeIt (_Invalid i) { n=-1; } bool operator==(const NodeIt i) const {return n==i.n;} bool operator!=(const NodeIt i) const {return n!=i.n;} bool operator<(const NodeIt i) const {return n friend class EdgeMap; template friend class DynEdgeMap; friend class NodeIt; friend class EachNodeIt; protected: int n; friend int SmartGraph::id(EdgeIt e) const; EdgeIt(int nn) {n=nn;} public: EdgeIt() { } EdgeIt (_Invalid i) { n=-1; } bool operator==(const EdgeIt i) const {return n==i.n;} bool operator!=(const EdgeIt i) const {return n!=i.n;} bool operator<(const EdgeIt i) const {return n class NodeMap { const SmartGraph& G; std::vector container; public: typedef T ValueType; typedef NodeIt KeyType; NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { } NodeMap(const SmartGraph& _G, T a) : G(_G), container(G.maxNodeId(), a) { } void set(NodeIt n, T a) { container[n.n]=a; } T get(NodeIt n) const { return container[n.n]; } T& operator[](NodeIt n) { return container[n.n]; } const T& operator[](NodeIt n) const { return container[n.n]; } void update() { container.resize(G.maxNodeId()); } void update(T a) { container.resize(G.maxNodeId(), a); } }; template class EdgeMap { const SmartGraph& G; std::vector container; public: typedef T ValueType; typedef EdgeIt KeyType; EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { } EdgeMap(const SmartGraph& _G, T a) : G(_G), container(G.maxEdgeId(), a) { } void set(EdgeIt e, T a) { container[e.n]=a; } T get(EdgeIt e) const { return container[e.n]; } T& operator[](EdgeIt e) { return container[e.n]; } const T& operator[](EdgeIt e) const { return container[e.n]; } void update() { container.resize(G.maxEdgeId()); } void update(T a) { container.resize(G.maxEdgeId(), a); } }; template class DynNodeMap : public DynMapBase { std::vector container; public: typedef T ValueType; typedef NodeIt KeyType; DynNodeMap(const SmartGraph &_G) : DynMapBase(_G), container(_G.maxNodeId()) { //FIXME: What if there are empty Id's? //FIXME: Can I use 'this' in a constructor? G->dyn_node_maps.push_back(this); } ~DynNodeMap() { 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 NodeIt k) { if(k.n>=container.size()) container.resize(k.n+1); } // void erase(const NodeIt k) // { // //FIXME: Please implement me. // } // void erase(const EdgeIt k) // { // //FIXME: Please implement me. // } void set(NodeIt n, T a) { container[n.n]=a; } T get(NodeIt n) const { return container[n.n]; } T& operator[](NodeIt n) { return container[n.n]; } const T& operator[](NodeIt n) const { return container[n.n]; } void update() {} //Useless for DynMaps void update(T a) {} //Useless for DynMaps }; template class DynEdgeMap : public DynMapBase { std::vector container; public: typedef T ValueType; typedef EdgeIt KeyType; DynEdgeMap(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); } ~DynEdgeMap() { 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 EdgeIt k) { if(k.n>=int(container.size())) container.resize(k.n+1); } void erase(const EdgeIt k) { //FIXME: Please implement me. } void set(EdgeIt n, T a) { container[n.n]=a; } T get(EdgeIt n) const { return container[n.n]; } T& operator[](EdgeIt n) { return container[n.n]; } const T& operator[](EdgeIt n) const { return container[n.n]; } void update() {} //Useless for DynMaps void update(T a) {} //Useless for DynMaps }; }; } //namespace hugo #endif //SMART_GRAPH_H