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