| [642] | 1 | // -*- c++ -*- | 
|---|
| [921] | 2 | #ifndef LEMON_SAGE_GRAPH_H | 
|---|
|  | 3 | #define LEMON_SAGE_GRAPH_H | 
|---|
| [642] | 4 |  | 
|---|
|  | 5 | #include <iostream> | 
|---|
|  | 6 | #include <vector> | 
|---|
|  | 7 |  | 
|---|
| [921] | 8 | #include <lemon/invalid.h> | 
|---|
| [642] | 9 |  | 
|---|
| [921] | 10 | namespace lemon { | 
|---|
| [642] | 11 |  | 
|---|
| [774] | 12 | //   template <typename It> | 
|---|
|  | 13 | //   int count(It it) { | 
|---|
|  | 14 | //     int i=0; | 
|---|
|  | 15 | //     for( ; it.valid(); ++it) { ++i; } | 
|---|
|  | 16 | //     return i; | 
|---|
|  | 17 | //   } | 
|---|
| [642] | 18 |  | 
|---|
|  | 19 | class SageGraph { | 
|---|
|  | 20 | struct node_item; | 
|---|
|  | 21 | struct edge_item; | 
|---|
|  | 22 | public: | 
|---|
|  | 23 | class Node; | 
|---|
|  | 24 | class NodeIt; | 
|---|
|  | 25 | class Edge; | 
|---|
|  | 26 | class EdgeIt; | 
|---|
|  | 27 | class OutEdgeIt; | 
|---|
|  | 28 | class InEdgeIt; | 
|---|
|  | 29 | class SymEdgeIt; | 
|---|
|  | 30 | template <typename T> class NodeMap; | 
|---|
|  | 31 | template <typename T> class EdgeMap; | 
|---|
|  | 32 | //  private: | 
|---|
|  | 33 | template <typename T> friend class NodeMap; | 
|---|
|  | 34 | template <typename T> friend class EdgeMap; | 
|---|
|  | 35 |  | 
|---|
|  | 36 | template <typename T> | 
|---|
|  | 37 | class NodeMap { | 
|---|
|  | 38 | const SageGraph& G; | 
|---|
|  | 39 | std::vector<T> container; | 
|---|
|  | 40 | public: | 
|---|
| [987] | 41 | typedef T Value; | 
|---|
|  | 42 | typedef Node Key; | 
|---|
| [642] | 43 | NodeMap(const SageGraph& _G) : G(_G), container(G.node_id) { } | 
|---|
|  | 44 | NodeMap(const SageGraph& _G, T a) : | 
|---|
|  | 45 | G(_G), container(G.node_id, a) { } | 
|---|
|  | 46 | void set(Node n, T a) { container[/*G.id(n)*/n.node->id]=a; } | 
|---|
|  | 47 | //      T get(Node n) const { return container[/*G.id(n)*/n.node->id]; } | 
|---|
|  | 48 | typename std::vector<T>::reference operator[](Node n) { | 
|---|
|  | 49 | return container[/*G.id(n)*/n.node->id]; } | 
|---|
|  | 50 | typename std::vector<T>::const_reference operator[](Node n) const { | 
|---|
|  | 51 | return container[/*G.id(n)*/n.node->id]; | 
|---|
|  | 52 | } | 
|---|
|  | 53 | void update() { container.resize(G.node_id); } | 
|---|
|  | 54 | void update(T a) { container.resize(G.node_id, a); } | 
|---|
|  | 55 | }; | 
|---|
|  | 56 |  | 
|---|
|  | 57 | template <typename T> | 
|---|
|  | 58 | class EdgeMap { | 
|---|
|  | 59 | const SageGraph& G; | 
|---|
|  | 60 | std::vector<T> container; | 
|---|
|  | 61 | public: | 
|---|
| [987] | 62 | typedef T Value; | 
|---|
|  | 63 | typedef Edge Key; | 
|---|
| [642] | 64 | EdgeMap(const SageGraph& _G) : G(_G), container(G.edge_id) { } | 
|---|
|  | 65 | EdgeMap(const SageGraph& _G, T a) : | 
|---|
|  | 66 | G(_G), container(G.edge_id, a) { } | 
|---|
|  | 67 | void set(Edge e, T a) { container[/*G.id(e)*/e.edge->id]=a; } | 
|---|
|  | 68 | //      T get(Edge e) const { return container[/*G.id(e)*/e.edge->id]; } | 
|---|
|  | 69 | typename std::vector<T>::reference operator[](Edge e) { | 
|---|
|  | 70 | return container[/*G.id(e)*/e.edge->id]; } | 
|---|
|  | 71 | typename std::vector<T>::const_reference operator[](Edge e) const { | 
|---|
|  | 72 | return container[/*G.id(e)*/e.edge->id]; | 
|---|
|  | 73 | } | 
|---|
|  | 74 | void update() { container.resize(G.edge_id); } | 
|---|
|  | 75 | void update(T a) { container.resize(G.edge_id, a); } | 
|---|
|  | 76 | }; | 
|---|
|  | 77 |  | 
|---|
|  | 78 | private: | 
|---|
|  | 79 | int node_id; | 
|---|
|  | 80 | int edge_id; | 
|---|
|  | 81 | int _node_num; | 
|---|
|  | 82 | int _edge_num; | 
|---|
|  | 83 |  | 
|---|
|  | 84 | node_item* _first_node; | 
|---|
|  | 85 | node_item* _last_node; | 
|---|
|  | 86 |  | 
|---|
|  | 87 | struct node_item { | 
|---|
|  | 88 | int id; | 
|---|
|  | 89 | edge_item* _first_out_edge; | 
|---|
|  | 90 | edge_item* _last_out_edge; | 
|---|
|  | 91 | edge_item* _first_in_edge; | 
|---|
|  | 92 | edge_item* _last_in_edge; | 
|---|
|  | 93 | node_item* _next_node; | 
|---|
|  | 94 | node_item* _prev_node; | 
|---|
|  | 95 | }; | 
|---|
|  | 96 |  | 
|---|
|  | 97 | struct edge_item { | 
|---|
|  | 98 | int id; | 
|---|
| [986] | 99 | node_item* _source; | 
|---|
|  | 100 | node_item* _target; | 
|---|
| [642] | 101 | edge_item* _next_out; | 
|---|
|  | 102 | edge_item* _prev_out; | 
|---|
|  | 103 | edge_item* _next_in; | 
|---|
|  | 104 | edge_item* _prev_in; | 
|---|
|  | 105 | }; | 
|---|
|  | 106 |  | 
|---|
|  | 107 | node_item* _add_node() { | 
|---|
|  | 108 | node_item* p=new node_item; | 
|---|
|  | 109 | p->id=node_id++; | 
|---|
|  | 110 | p->_first_out_edge=0; | 
|---|
|  | 111 | p->_last_out_edge=0; | 
|---|
|  | 112 | p->_first_in_edge=0; | 
|---|
|  | 113 | p->_last_in_edge=0; | 
|---|
|  | 114 | p->_prev_node=_last_node; | 
|---|
|  | 115 | p->_next_node=0; | 
|---|
|  | 116 | if (_last_node) _last_node->_next_node=p; | 
|---|
|  | 117 | _last_node=p; | 
|---|
|  | 118 | if (!_first_node) _first_node=p; | 
|---|
|  | 119 |  | 
|---|
|  | 120 | ++_node_num; | 
|---|
|  | 121 | return p; | 
|---|
|  | 122 | } | 
|---|
|  | 123 |  | 
|---|
| [986] | 124 | edge_item* _add_edge(node_item* _source, node_item* _target) { | 
|---|
| [642] | 125 | edge_item* e=new edge_item; | 
|---|
|  | 126 | e->id=edge_id++; | 
|---|
| [986] | 127 | e->_source=_source; | 
|---|
|  | 128 | e->_target=_target; | 
|---|
| [642] | 129 |  | 
|---|
| [986] | 130 | e->_prev_out=_source->_last_out_edge; | 
|---|
|  | 131 | if (_source->_last_out_edge) (_source->_last_out_edge)->_next_out=e; | 
|---|
|  | 132 | _source->_last_out_edge=e; | 
|---|
|  | 133 | if (!_source->_first_out_edge) _source->_first_out_edge=e; | 
|---|
| [642] | 134 | e->_next_out=0; | 
|---|
|  | 135 |  | 
|---|
| [986] | 136 | e->_prev_in=_target->_last_in_edge; | 
|---|
|  | 137 | if (_target->_last_in_edge) (_target->_last_in_edge)->_next_in=e; | 
|---|
|  | 138 | _target->_last_in_edge=e; | 
|---|
|  | 139 | if (!_target->_first_in_edge) { _target->_first_in_edge=e; } | 
|---|
| [642] | 140 | e->_next_in=0; | 
|---|
|  | 141 |  | 
|---|
|  | 142 | ++_edge_num; | 
|---|
|  | 143 | return e; | 
|---|
|  | 144 | } | 
|---|
|  | 145 |  | 
|---|
|  | 146 | //deletes a node which has no out edge and no in edge | 
|---|
|  | 147 | void _delete_node(node_item* v) { | 
|---|
|  | 148 | if (v->_next_node) (v->_next_node)->_prev_node=v->_prev_node; else | 
|---|
|  | 149 | _last_node=v->_prev_node; | 
|---|
|  | 150 | if (v->_prev_node) (v->_prev_node)->_next_node=v->_next_node; else | 
|---|
|  | 151 | _first_node=v->_next_node; | 
|---|
|  | 152 |  | 
|---|
|  | 153 | delete v; | 
|---|
|  | 154 | --_node_num; | 
|---|
|  | 155 | } | 
|---|
|  | 156 |  | 
|---|
|  | 157 | void _delete_edge(edge_item* e) { | 
|---|
|  | 158 | if (e->_next_out) (e->_next_out)->_prev_out=e->_prev_out; else | 
|---|
| [986] | 159 | (e->_source)->_last_out_edge=e->_prev_out; | 
|---|
| [642] | 160 | if (e->_prev_out) (e->_prev_out)->_next_out=e->_next_out; else | 
|---|
| [986] | 161 | (e->_source)->_first_out_edge=e->_next_out; | 
|---|
| [642] | 162 | if (e->_next_in) (e->_next_in)->_prev_in=e->_prev_in; else | 
|---|
| [986] | 163 | (e->_target)->_last_in_edge=e->_prev_in; | 
|---|
| [642] | 164 | if (e->_prev_in) (e->_prev_in)->_next_in=e->_next_in; else | 
|---|
| [986] | 165 | (e->_target)->_first_in_edge=e->_next_in; | 
|---|
| [642] | 166 |  | 
|---|
|  | 167 | delete e; | 
|---|
|  | 168 | --_edge_num; | 
|---|
|  | 169 | } | 
|---|
|  | 170 |  | 
|---|
| [986] | 171 | void _set_source(edge_item* e, node_item* _source) { | 
|---|
| [642] | 172 | if (e->_next_out) (e->_next_out)->_prev_out=e->_prev_out; else | 
|---|
| [986] | 173 | (e->_source)->_last_out_edge=e->_prev_out; | 
|---|
| [642] | 174 | if (e->_prev_out) (e->_prev_out)->_next_out=e->_next_out; else | 
|---|
| [986] | 175 | (e->_source)->_first_out_edge=e->_next_out; | 
|---|
| [642] | 176 |  | 
|---|
| [986] | 177 | e->_source=_source; | 
|---|
| [642] | 178 |  | 
|---|
| [986] | 179 | e->_prev_out=_source->_last_out_edge; | 
|---|
|  | 180 | if (_source->_last_out_edge) (_source->_last_out_edge)->_next_out=e; | 
|---|
|  | 181 | _source->_last_out_edge=e; | 
|---|
|  | 182 | if (!_source->_first_out_edge) _source->_first_out_edge=e; | 
|---|
| [642] | 183 | e->_next_out=0; | 
|---|
|  | 184 | } | 
|---|
|  | 185 |  | 
|---|
| [986] | 186 | void _set_target(edge_item* e, node_item* _target) { | 
|---|
| [642] | 187 | if (e->_next_in) (e->_next_in)->_prev_in=e->_prev_in; else | 
|---|
| [986] | 188 | (e->_target)->_last_in_edge=e->_prev_in; | 
|---|
| [642] | 189 | if (e->_prev_in) (e->_prev_in)->_next_in=e->_next_in; else | 
|---|
| [986] | 190 | (e->_target)->_first_in_edge=e->_next_in; | 
|---|
| [642] | 191 |  | 
|---|
| [986] | 192 | e->_target=_target; | 
|---|
| [642] | 193 |  | 
|---|
| [986] | 194 | e->_prev_in=_target->_last_in_edge; | 
|---|
|  | 195 | if (_target->_last_in_edge) (_target->_last_in_edge)->_next_in=e; | 
|---|
|  | 196 | _target->_last_in_edge=e; | 
|---|
|  | 197 | if (!_target->_first_in_edge) { _target->_first_in_edge=e; } | 
|---|
| [642] | 198 | e->_next_in=0; | 
|---|
|  | 199 | } | 
|---|
|  | 200 |  | 
|---|
|  | 201 | public: | 
|---|
|  | 202 |  | 
|---|
|  | 203 | /* default constructor */ | 
|---|
|  | 204 |  | 
|---|
|  | 205 | SageGraph() : node_id(0), edge_id(0), _node_num(0), _edge_num(0), _first_node(0), _last_node(0) { } | 
|---|
|  | 206 |  | 
|---|
|  | 207 | ~SageGraph() { | 
|---|
|  | 208 | NodeIt n; | 
|---|
|  | 209 | while (this->valid(first(n))) erase(n); | 
|---|
|  | 210 | //while (first<NodeIt>().valid()) erase(first<NodeIt>()); | 
|---|
|  | 211 | } | 
|---|
|  | 212 |  | 
|---|
|  | 213 | int nodeNum() const { return _node_num; } | 
|---|
|  | 214 | int edgeNum() const { return _edge_num; } | 
|---|
|  | 215 |  | 
|---|
|  | 216 | /* functions to construct iterators from the graph, or from each other */ | 
|---|
|  | 217 |  | 
|---|
|  | 218 | //NodeIt firstNode() const { return NodeIt(*this); } | 
|---|
|  | 219 | //EdgeIt firstEdge() const { return EdgeIt(*this); } | 
|---|
|  | 220 |  | 
|---|
|  | 221 | //OutEdgeIt firstOutEdge(const Node v) const { return OutEdgeIt(v); } | 
|---|
|  | 222 | //InEdgeIt firstInEdge(const Node v) const { return InEdgeIt(v); } | 
|---|
|  | 223 | //SymEdgeIt firstSymEdge(const Node v) const { return SymEdgeIt(v); } | 
|---|
| [986] | 224 | Node source(Edge e) const { return e.sourceNode(); } | 
|---|
|  | 225 | Node target(Edge e) const { return e.targetNode(); } | 
|---|
| [642] | 226 |  | 
|---|
|  | 227 | Node aNode(const OutEdgeIt& e) const { return e.aNode(); } | 
|---|
|  | 228 | Node aNode(const InEdgeIt& e) const { return e.aNode(); } | 
|---|
|  | 229 | Node aNode(const SymEdgeIt& e) const { return e.aNode(); } | 
|---|
|  | 230 |  | 
|---|
|  | 231 | Node bNode(const OutEdgeIt& e) const { return e.bNode(); } | 
|---|
|  | 232 | Node bNode(const InEdgeIt& e) const { return e.bNode(); } | 
|---|
|  | 233 | Node bNode(const SymEdgeIt& e) const { return e.bNode(); } | 
|---|
|  | 234 |  | 
|---|
|  | 235 | //Node invalid_node() { return Node(); } | 
|---|
|  | 236 | //Edge invalid_edge() { return Edge(); } | 
|---|
|  | 237 | //OutEdgeIt invalid_out_edge() { return OutEdgeIt(); } | 
|---|
|  | 238 | //InEdgeIt invalid_in_edge() { return InEdgeIt(); } | 
|---|
|  | 239 | //SymEdgeIt invalid_sym_edge() { return SymEdgeIt(); } | 
|---|
|  | 240 |  | 
|---|
|  | 241 | /* same methods in other style */ | 
|---|
|  | 242 | /* for experimental purpose */ | 
|---|
|  | 243 |  | 
|---|
|  | 244 | NodeIt& first(NodeIt& v) const { | 
|---|
|  | 245 | v=NodeIt(*this); return v; } | 
|---|
|  | 246 | EdgeIt& first(EdgeIt& e) const { | 
|---|
|  | 247 | e=EdgeIt(*this); return e; } | 
|---|
|  | 248 | OutEdgeIt& first(OutEdgeIt& e, Node v) const { | 
|---|
|  | 249 | e=OutEdgeIt(*this, v); return e; } | 
|---|
|  | 250 | InEdgeIt& first(InEdgeIt& e, Node v) const { | 
|---|
|  | 251 | e=InEdgeIt(*this, v); return e; } | 
|---|
|  | 252 | SymEdgeIt& first(SymEdgeIt& e, Node v) const { | 
|---|
|  | 253 | e=SymEdgeIt(*this, v); return e; } | 
|---|
| [986] | 254 | //void getSource(Node& n, const Edge& e) const { n=source(e); } | 
|---|
|  | 255 | //void getTarget(Node& n, const Edge& e) const { n=target(e); } | 
|---|
| [642] | 256 |  | 
|---|
|  | 257 | //void getANode(Node& n, const OutEdgeIt& e) const { n=e.aNode(); } | 
|---|
|  | 258 | //void getANode(Node& n, const InEdgeIt& e) const { n=e.aNode(); } | 
|---|
|  | 259 | //void getANode(Node& n, const SymEdgeIt& e) const { n=e.aNode(); } | 
|---|
|  | 260 | //void getBNode(Node& n, const OutEdgeIt& e) const { n=e.bNode(); } | 
|---|
|  | 261 | //void getBNode(Node& n, const InEdgeIt& e) const { n=e.bNode(); } | 
|---|
|  | 262 | //void getBNode(Node& n, const SymEdgeIt& e) const { n=e.bNode(); } | 
|---|
|  | 263 | //void get_invalid(Node& n) { n=Node(); } | 
|---|
|  | 264 | //void get_invalid(Edge& e) { e=Edge(); } | 
|---|
|  | 265 | //void get_invalid(OutEdgeIt& e) { e=OutEdgeIt(); } | 
|---|
|  | 266 | //void get_invalid(InEdgeIt& e) { e=InEdgeIt(); } | 
|---|
|  | 267 | //void get_invalid(SymEdgeIt& e) { e=SymEdgeIt(); } | 
|---|
|  | 268 |  | 
|---|
|  | 269 | //     template< typename It > | 
|---|
|  | 270 | //     It first() const { | 
|---|
|  | 271 | //       It e; | 
|---|
|  | 272 | //       first(e); | 
|---|
|  | 273 | //       return e; | 
|---|
|  | 274 | //     } | 
|---|
|  | 275 |  | 
|---|
|  | 276 | //     template< typename It > | 
|---|
|  | 277 | //     It first(Node v) const { | 
|---|
|  | 278 | //       It e; | 
|---|
|  | 279 | //       first(e, v); | 
|---|
|  | 280 | //       return e; | 
|---|
|  | 281 | //     } | 
|---|
|  | 282 |  | 
|---|
|  | 283 | bool valid(Node n) const { return n.valid(); } | 
|---|
|  | 284 | bool valid(Edge e) const { return e.valid(); } | 
|---|
|  | 285 |  | 
|---|
|  | 286 | //    template <typename It> It getNext(It it) const { | 
|---|
|  | 287 | //      It tmp(it); next(tmp); return tmp; } | 
|---|
|  | 288 | //     NodeIt& next(NodeIt& it) const { return ++it; } | 
|---|
|  | 289 | //     EdgeIt& next(EdgeIt& it) const { return ++it; } | 
|---|
|  | 290 | //     OutEdgeIt& next(OutEdgeIt& it) const { return ++it; } | 
|---|
|  | 291 | //     InEdgeIt& next(InEdgeIt& it) const { return ++it; } | 
|---|
|  | 292 | //     SymEdgeIt& next(SymEdgeIt& it) const { return ++it; } | 
|---|
|  | 293 | //    template <typename It> It& next(It& it) const { return ++it; } | 
|---|
|  | 294 | template <typename It> It& next(It& it) const { ++it; return it; } | 
|---|
|  | 295 |  | 
|---|
|  | 296 |  | 
|---|
|  | 297 | /* for getting id's of graph objects */ | 
|---|
|  | 298 | /* these are important for the implementation of property vectors */ | 
|---|
|  | 299 |  | 
|---|
|  | 300 | int id(Node v) const { return v.node->id; } | 
|---|
|  | 301 | int id(Edge e) const { return e.edge->id; } | 
|---|
|  | 302 |  | 
|---|
|  | 303 | /* adding nodes and edges */ | 
|---|
|  | 304 |  | 
|---|
|  | 305 | Node addNode() { return Node(_add_node()); } | 
|---|
|  | 306 | Edge addEdge(Node u, Node v) { | 
|---|
|  | 307 | return Edge(_add_edge(u.node, v.node)); | 
|---|
|  | 308 | } | 
|---|
|  | 309 |  | 
|---|
|  | 310 | void erase(Node i) { | 
|---|
|  | 311 | { | 
|---|
|  | 312 | OutEdgeIt e; | 
|---|
|  | 313 | while (this->valid(first(e, i))) erase(e); | 
|---|
|  | 314 | } | 
|---|
|  | 315 | { | 
|---|
|  | 316 | InEdgeIt e; | 
|---|
|  | 317 | while (this->valid(first(e, i))) erase(e); | 
|---|
|  | 318 | } | 
|---|
|  | 319 | //while (first<OutEdgeIt>(i).valid()) erase(first<OutEdgeIt>(i)); | 
|---|
|  | 320 | //while (first<InEdgeIt>(i).valid()) erase(first<InEdgeIt>(i)); | 
|---|
|  | 321 | _delete_node(i.node); | 
|---|
|  | 322 | } | 
|---|
|  | 323 |  | 
|---|
|  | 324 | void erase(Edge e) { _delete_edge(e.edge); } | 
|---|
|  | 325 |  | 
|---|
|  | 326 | void clear() { | 
|---|
|  | 327 | NodeIt e; | 
|---|
|  | 328 | while (this->valid(first(e))) erase(e); | 
|---|
|  | 329 | //while (first<NodeIt>().valid()) erase(first<NodeIt>()); | 
|---|
|  | 330 | } | 
|---|
|  | 331 |  | 
|---|
| [986] | 332 | void setSource(Edge e, Node source) { | 
|---|
|  | 333 | _set_source(e.edge, source.node); | 
|---|
| [642] | 334 | } | 
|---|
|  | 335 |  | 
|---|
| [986] | 336 | void setTarget(Edge e, Node target) { | 
|---|
|  | 337 | _set_target(e.edge, target.node); | 
|---|
| [642] | 338 | } | 
|---|
|  | 339 |  | 
|---|
|  | 340 | /* stream operations, for testing purpose */ | 
|---|
|  | 341 |  | 
|---|
|  | 342 | //     friend std::ostream& operator<<(std::ostream& os, const Node& i) { | 
|---|
|  | 343 | //       if (i.valid()) | 
|---|
|  | 344 | //      os << i.node->id; | 
|---|
|  | 345 | //       else | 
|---|
|  | 346 | //      os << "invalid"; | 
|---|
|  | 347 | //       return os; | 
|---|
|  | 348 | //     } | 
|---|
|  | 349 | //     friend std::ostream& operator<<(std::ostream& os, const Edge& i) { | 
|---|
|  | 350 | //       if (i.valid()) | 
|---|
| [986] | 351 | //      os << "(" << i.edge->_source->id << "--" << i.edge->id << "->" << i.edge->_target->id << ")"; | 
|---|
| [642] | 352 | //       else | 
|---|
|  | 353 | //      os << "invalid"; | 
|---|
|  | 354 | //       return os; | 
|---|
|  | 355 | //     } | 
|---|
|  | 356 |  | 
|---|
|  | 357 | class Node { | 
|---|
|  | 358 | friend class SageGraph; | 
|---|
|  | 359 | template <typename T> friend class NodeMap; | 
|---|
|  | 360 |  | 
|---|
|  | 361 | friend class Edge; | 
|---|
|  | 362 | friend class OutEdgeIt; | 
|---|
|  | 363 | friend class InEdgeIt; | 
|---|
|  | 364 | friend class SymEdgeIt; | 
|---|
|  | 365 | //public:  //FIXME: It is required by op= of NodeIt | 
|---|
|  | 366 | protected: | 
|---|
|  | 367 | node_item* node; | 
|---|
|  | 368 | protected: | 
|---|
|  | 369 | friend int SageGraph::id(Node v) const; | 
|---|
|  | 370 | public: | 
|---|
|  | 371 | Node() /*: node(0)*/ { } | 
|---|
|  | 372 | Node(const Invalid&) : node(0) { } | 
|---|
|  | 373 | protected: | 
|---|
|  | 374 | Node(node_item* _node) : node(_node) { } | 
|---|
|  | 375 | bool valid() const { return (node); } | 
|---|
|  | 376 | public: | 
|---|
|  | 377 | //void makeInvalid() { node=0; } | 
|---|
|  | 378 | friend bool operator==(Node u, Node v) { return v.node==u.node; } | 
|---|
|  | 379 | friend bool operator!=(Node u, Node v) { return v.node!=u.node; } | 
|---|
|  | 380 | friend std::ostream& operator<<(std::ostream& os, const Node& i); | 
|---|
|  | 381 | }; | 
|---|
|  | 382 |  | 
|---|
|  | 383 | class NodeIt : public Node { | 
|---|
|  | 384 | friend class SageGraph; | 
|---|
|  | 385 | //protected: | 
|---|
|  | 386 | public: //for everybody but marci | 
|---|
|  | 387 | NodeIt(const SageGraph& G) : Node(G._first_node) { } | 
|---|
| [774] | 388 | NodeIt(const SageGraph& G, const Node& n) : Node(n) { } | 
|---|
| [642] | 389 | public: | 
|---|
|  | 390 | NodeIt() : Node() { } | 
|---|
|  | 391 | NodeIt(const Invalid& i) : Node(i) { } | 
|---|
|  | 392 | protected: | 
|---|
|  | 393 | NodeIt(node_item* v) : Node(v) { } | 
|---|
| [774] | 394 | public: | 
|---|
| [642] | 395 | NodeIt& operator++() { node=node->_next_node; return *this; } | 
|---|
|  | 396 | //FIXME:: | 
|---|
|  | 397 | //      NodeIt& operator=(const Node& e) | 
|---|
|  | 398 | //      { node=e.node; return *this; } | 
|---|
|  | 399 | }; | 
|---|
|  | 400 |  | 
|---|
|  | 401 | class Edge { | 
|---|
|  | 402 | friend class SageGraph; | 
|---|
|  | 403 | template <typename T> friend class EdgeMap; | 
|---|
|  | 404 |  | 
|---|
|  | 405 | friend class Node; | 
|---|
|  | 406 | friend class NodeIt; | 
|---|
|  | 407 | protected: | 
|---|
|  | 408 | edge_item* edge; | 
|---|
|  | 409 | friend int SageGraph::id(Edge e) const; | 
|---|
|  | 410 | public: | 
|---|
|  | 411 | Edge() /*: edge(0)*/ { } | 
|---|
|  | 412 | Edge(const Invalid&) : edge(0) { } | 
|---|
|  | 413 | //Edge() { } | 
|---|
|  | 414 | protected: | 
|---|
|  | 415 | Edge(edge_item* _edge) : edge(_edge) { } | 
|---|
|  | 416 | bool valid() const { return (edge); } | 
|---|
|  | 417 | public: | 
|---|
|  | 418 | //void makeInvalid() { edge=0; } | 
|---|
|  | 419 | friend bool operator==(Edge u, Edge v) { return v.edge==u.edge; } | 
|---|
|  | 420 | friend bool operator!=(Edge u, Edge v) { return v.edge!=u.edge; } | 
|---|
|  | 421 | protected: | 
|---|
| [986] | 422 | Node sourceNode() const { return Node(edge->_source); } | 
|---|
|  | 423 | Node targetNode() const { return Node(edge->_target); } | 
|---|
| [642] | 424 | public: | 
|---|
|  | 425 | friend std::ostream& operator<<(std::ostream& os, const Edge& i); | 
|---|
|  | 426 | }; | 
|---|
|  | 427 |  | 
|---|
|  | 428 | class EdgeIt : public Edge { | 
|---|
|  | 429 | friend class SageGraph; | 
|---|
| [774] | 430 | public: | 
|---|
|  | 431 | EdgeIt() : Edge() { } | 
|---|
|  | 432 | EdgeIt(const Invalid& i) : Edge(i) { } | 
|---|
| [642] | 433 | EdgeIt(const SageGraph& G) { | 
|---|
|  | 434 | node_item* v=G._first_node; | 
|---|
|  | 435 | if (v) edge=v->_first_out_edge; else edge=0; | 
|---|
|  | 436 | while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; } | 
|---|
|  | 437 | } | 
|---|
| [774] | 438 | EdgeIt(const SageGraph& G, const Edge& e) : Edge(e) { } | 
|---|
|  | 439 | //     protected: | 
|---|
|  | 440 | //       EdgeIt(edge_item* _e) : Edge(_e) { } | 
|---|
| [642] | 441 | public: | 
|---|
|  | 442 | EdgeIt& operator++() { | 
|---|
| [986] | 443 | node_item* v=edge->_source; | 
|---|
| [642] | 444 | edge=edge->_next_out; | 
|---|
|  | 445 | while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; } | 
|---|
|  | 446 | return *this; | 
|---|
|  | 447 | } | 
|---|
|  | 448 | }; | 
|---|
|  | 449 |  | 
|---|
|  | 450 | class OutEdgeIt : public Edge { | 
|---|
|  | 451 | friend class SageGraph; | 
|---|
|  | 452 | public: | 
|---|
| [774] | 453 | OutEdgeIt() : Edge() { } | 
|---|
| [642] | 454 | OutEdgeIt(const Invalid& i) : Edge(i) { } | 
|---|
| [774] | 455 | OutEdgeIt(const SageGraph&, Node _v) : Edge(_v.node->_first_out_edge) { } | 
|---|
|  | 456 | OutEdgeIt(const SageGraph&, const Edge& e) : Edge(e) { } | 
|---|
| [642] | 457 | OutEdgeIt& operator++() { edge=edge->_next_out; return *this; } | 
|---|
|  | 458 | protected: | 
|---|
| [986] | 459 | Node aNode() const { return Node(edge->_source); } | 
|---|
|  | 460 | Node bNode() const { return Node(edge->_target); } | 
|---|
| [642] | 461 | }; | 
|---|
|  | 462 |  | 
|---|
|  | 463 | class InEdgeIt : public Edge { | 
|---|
|  | 464 | friend class SageGraph; | 
|---|
|  | 465 | public: | 
|---|
| [774] | 466 | InEdgeIt() : Edge() { } | 
|---|
|  | 467 | InEdgeIt(Invalid i) : Edge(i) { } | 
|---|
|  | 468 | InEdgeIt(const SageGraph&, Node _v) : Edge(_v.node->_first_in_edge) { } | 
|---|
|  | 469 | InEdgeIt(const SageGraph&, const Edge& e) : Edge(e) { } | 
|---|
| [642] | 470 | InEdgeIt& operator++() { edge=edge->_next_in; return *this; } | 
|---|
|  | 471 | protected: | 
|---|
| [986] | 472 | Node aNode() const { return Node(edge->_target); } | 
|---|
|  | 473 | Node bNode() const { return Node(edge->_source); } | 
|---|
| [642] | 474 | }; | 
|---|
|  | 475 |  | 
|---|
|  | 476 | class SymEdgeIt : public Edge { | 
|---|
|  | 477 | friend class SageGraph; | 
|---|
|  | 478 | bool out_or_in; //1 iff out, 0 iff in | 
|---|
|  | 479 | //node_item* v; | 
|---|
|  | 480 | //protected: | 
|---|
|  | 481 | protected: //for alpar | 
|---|
|  | 482 | SymEdgeIt(const Node& _v) /*: v(_v.node)*/ { | 
|---|
|  | 483 | out_or_in=1; | 
|---|
|  | 484 | edge=_v.node->_first_out_edge; | 
|---|
|  | 485 | if (!edge) { edge=_v.node->_first_in_edge; out_or_in=0; } | 
|---|
|  | 486 | } | 
|---|
|  | 487 | public: | 
|---|
|  | 488 | SymEdgeIt() : Edge() /*, v(0)*/ { } | 
|---|
|  | 489 | SymEdgeIt(const Invalid& i) : Edge(i) { } | 
|---|
|  | 490 | SymEdgeIt(const SageGraph&, Node _v) /*: v(_v.node)*/ { | 
|---|
|  | 491 | out_or_in=1; | 
|---|
|  | 492 | edge=_v.node->_first_out_edge; | 
|---|
|  | 493 | if (!edge) { edge=_v.node->_first_in_edge; out_or_in=0; } | 
|---|
|  | 494 | } | 
|---|
|  | 495 | protected: | 
|---|
|  | 496 | SymEdgeIt& operator++() { | 
|---|
|  | 497 | if (out_or_in) { | 
|---|
| [986] | 498 | node_item* v=edge->_source; | 
|---|
| [642] | 499 | edge=edge->_next_out; | 
|---|
|  | 500 | if (!edge) { out_or_in=0; edge=v->_first_in_edge; } | 
|---|
|  | 501 | } else { | 
|---|
|  | 502 | edge=edge->_next_in; | 
|---|
|  | 503 | } | 
|---|
|  | 504 | return *this; | 
|---|
|  | 505 | } | 
|---|
|  | 506 | protected: | 
|---|
|  | 507 | Node aNode() const { | 
|---|
| [986] | 508 | return (out_or_in) ? Node(edge->_source) : Node(edge->_target); } | 
|---|
| [642] | 509 | Node bNode() const { | 
|---|
| [986] | 510 | return (out_or_in) ? Node(edge->_target) : Node(edge->_source); } | 
|---|
| [642] | 511 | }; | 
|---|
|  | 512 | }; | 
|---|
|  | 513 |  | 
|---|
|  | 514 | inline | 
|---|
|  | 515 | std::ostream& operator<<(std::ostream& os, const SageGraph::Node& i) { | 
|---|
|  | 516 | if (i.valid()) | 
|---|
|  | 517 | os << i.node->id; | 
|---|
|  | 518 | else | 
|---|
|  | 519 | os << "invalid"; | 
|---|
|  | 520 | return os; | 
|---|
|  | 521 | } | 
|---|
|  | 522 |  | 
|---|
|  | 523 | inline | 
|---|
|  | 524 | std::ostream& operator<<(std::ostream& os, const SageGraph::Edge& i) { | 
|---|
|  | 525 | if (i.valid()) | 
|---|
| [986] | 526 | os << "(" << i.sourceNode() << "--" << i.edge->id << "->" | 
|---|
|  | 527 | << i.targetNode() << ")"; | 
|---|
| [642] | 528 | else | 
|---|
|  | 529 | os << "invalid"; | 
|---|
|  | 530 | return os; | 
|---|
|  | 531 | } | 
|---|
|  | 532 |  | 
|---|
|  | 533 | class UndirSageGraph : public SageGraph { | 
|---|
|  | 534 | public: | 
|---|
|  | 535 | typedef SymEdgeIt OutEdgeIt; | 
|---|
|  | 536 | typedef SymEdgeIt InEdgeIt; | 
|---|
|  | 537 | }; | 
|---|
|  | 538 |  | 
|---|
| [921] | 539 | } //namespace lemon | 
|---|
| [642] | 540 |  | 
|---|
| [921] | 541 | #endif //LEMON_SAGE_GRAPH_H | 
|---|