// -*- mode:C++ -*- #ifndef SMART_GRAPH_H #define SMART_GRAPH_H #include #include #include namespace hugo { class SmartGraph { 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 Node; class Edge; protected: mutable std::vector * > dyn_node_maps; mutable std::vector * > dyn_edge_maps; public: class NodeIt; class EdgeIt; class OutEdgeIt; class InEdgeIt; // class Node { int n; }; // class NodeIt : public Node { }; // class Edge { int n; }; // class EdgeIt : public Edge {}; // class OutEdgeIt : public Edge {}; // class InEdgeIt : public Edge {}; // class SymEdge; 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? Node tail(Edge e) const { return edges[e.n].tail; } Node head(Edge e) const { return edges[e.n].head; } // Marci Node aNode(OutEdgeIt e) const { return edges[e.n].tail; } Node aNode(InEdgeIt e) const { return edges[e.n].head; } // //Node aNode(const SymEdge& e) const { return e.aNode(); } // Marci Node bNode(OutEdgeIt e) const { return edges[e.n].head; } Node bNode(InEdgeIt e) const { return edges[e.n].tail; } // //Node bNode(const SymEdge& e) const { return e.bNode(); } NodeIt& first(NodeIt& v) const { v=NodeIt(*this); return v; } EdgeIt& first(EdgeIt& e) const { e=EdgeIt(*this); return e; } OutEdgeIt& first(OutEdgeIt& e, const Node v) const { e=OutEdgeIt(*this,v); return e; } InEdgeIt& first(InEdgeIt& e, const Node v) const { e=InEdgeIt(*this,v); return e; } template< typename It > It first() const { It e; first(e); return e; } template< typename It > It first(Node v) const { It e; first(e,v); return e; } bool valid(Edge e) const { return e.n!=-1; } bool valid(Node n) const { return n.n!=-1; } void setInvalid(Edge &e) { e.n=-1; } void setInvalid(Node &n) { n.n=-1; } template It getNext(It it) const { It tmp(it); return next(tmp); } NodeIt& next(NodeIt& it) const { it.n=(it.n+2)%(nodes.size()+1)-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; } EdgeIt& next(EdgeIt& it) const { --it.n; return it; } int id(Node v) const { return v.n; } int id(Edge e) const { return e.n; } Node addNode() { 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.n); return n; } Edge addEdge(Node u, Node v) { Edge 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 Node { friend class SmartGraph; template friend class NodeMap; template friend class DynNodeMap; friend class Edge; friend class OutEdgeIt; friend class InEdgeIt; friend class SymEdge; protected: int n; friend int SmartGraph::id(Node v) const; Node(int nn) {n=nn;} public: Node() {} Node (Invalid i) { n=-1; } bool operator==(const Node i) const {return n==i.n;} bool operator!=(const Node i) const {return n!=i.n;} bool operator<(const Node i) const {return n friend class EdgeMap; template friend class DynEdgeMap; friend class Node; friend class NodeIt; protected: int n; friend int SmartGraph::id(Edge e) const; Edge(int nn) {n=nn;} public: Edge() { } Edge (Invalid) { n=-1; } bool operator==(const Edge i) const {return n==i.n;} bool operator!=(const Edge i) const {return n!=i.n;} bool operator<(const Edge i) const {return n class NodeMap { const SmartGraph& G; std::vector container; public: typedef T ValueType; typedef Node KeyType; NodeMap(const SmartGraph& _G) : G(_G), container(G.maxNodeId()) { } NodeMap(const SmartGraph& _G, T a) : G(_G), container(G.maxNodeId(), a) { } void set(Node n, T a) { container[n.n]=a; } T get(Node n) const { return container[n.n]; } T& operator[](Node n) { return container[n.n]; } const T& operator[](Node 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 Edge KeyType; EdgeMap(const SmartGraph& _G) : G(_G), container(G.maxEdgeId()) { } EdgeMap(const SmartGraph& _G, T a) : G(_G), container(G.maxEdgeId(), a) { } void set(Edge e, T a) { container[e.n]=a; } T get(Edge e) const { return container[e.n]; } T& operator[](Edge e) { return container[e.n]; } const T& operator[](Edge 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 Node 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 Node k) { if(k.n>=container.size()) container.resize(k.n+1); } // void erase(const Node k) // { // //FIXME: Please implement me. // } // void erase(const Edge k) // { // //FIXME: Please implement me. // } void set(Node n, T a) { container[n.n]=a; } T get(Node n) const { return container[n.n]; } T& operator[](Node n) { return container[n.n]; } const T& operator[](Node 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 Edge 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 Edge k) { if(k.n>=int(container.size())) container.resize(k.n+1); } void erase(const Edge k) { //FIXME: Please implement me. } void set(Edge n, T a) { container[n.n]=a; } T get(Edge n) const { return container[n.n]; } T& operator[](Edge n) { return container[n.n]; } const T& operator[](Edge n) const { return container[n.n]; } void update() {} //Useless for DynMaps void update(T a) {} //Useless for DynMaps }; }; } //namespace hugo #endif //SMART_GRAPH_H