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