diff -r be43902fadb7 -r 19f3943521ab src/work/marci/oldies/marci_list_graph.hh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/marci/oldies/marci_list_graph.hh Sat Apr 03 14:41:31 2004 +0000 @@ -0,0 +1,343 @@ +#ifndef MARCI_LIST_GRAPH_HH +#define MARCI_LIST_GRAPH_HH + +#include + +namespace hugo { + + class list_graph { + class node_item; + class edge_item; + public: + class node_iterator; + class each_node_iterator; + class edge_iterator; + class each_edge_iterator; + class out_edge_iterator; + class in_edge_iterator; + class sym_edge_iterator; + private: + int node_id; + int edge_id; + int _node_num; + int _edge_num; + + node_item* _first_node; + node_item* _last_node; + + class node_item { + friend class list_graph; + friend class node_iterator; + friend class each_node_iterator; + friend class edge_iterator; + friend class each_edge_iterator; + friend class out_edge_iterator; + friend class in_edge_iterator; + friend class sym_edge_iterator; + friend std::ostream& operator<<(std::ostream& os, const node_iterator& i); + friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i); + list_graph* G; + int id; + edge_item* _first_out_edge; + edge_item* _last_out_edge; + edge_item* _first_in_edge; + edge_item* _last_in_edge; + node_item* _next_node; + node_item* _prev_node; + public: + node_item() { } + }; + + class edge_item { + friend class list_graph; + friend class node_iterator; + friend class each_node_iterator; + friend class edge_iterator; + friend class each_edge_iterator; + friend class out_edge_iterator; + friend class in_edge_iterator; + friend class sym_edge_iterator; + friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i); + list_graph* G; + int id; + node_item* _tail; + node_item* _head; + edge_item* _next_out; + edge_item* _prev_out; + edge_item* _next_in; + edge_item* _prev_in; + public: + edge_item() { } + }; + + node_item* _add_node() { + node_item* p=new node_item; + p->id=node_id++; + p->_first_out_edge=0; + p->_last_out_edge=0; + p->_first_in_edge=0; + p->_last_in_edge=0; + p->_prev_node=_last_node; + p->_next_node=0; + if (_last_node) _last_node->_next_node=p; + _last_node=p; + if (!_first_node) _first_node=p; + ++_node_num; + return p; + } + + edge_item* _add_edge(node_item* _tail, node_item* _head) { + edge_item* e=new edge_item; + e->id=edge_id++; + e->_tail=_tail; + e->_head=_head; + + e->_prev_out=_tail->_last_out_edge; + if (_tail->_last_out_edge) (_tail->_last_out_edge)->_next_out=e; + _tail->_last_out_edge=e; + if (!_tail->_first_out_edge) _tail->_first_out_edge=e; + + e->_prev_in=_head->_last_in_edge; + if (_head->_last_in_edge) (_head->_last_in_edge)->_next_in=e; + _head->_last_in_edge=e; + if (!_head->_first_in_edge) { _head->_first_in_edge=e; } + ++_edge_num; + return e; + } + + public: + + /* default constructor */ + + list_graph() : node_id(0), edge_id(0), _node_num(0), _edge_num(0), _first_node(0), _last_node(0) { } + + int node_num() { return _node_num; } + int edge_num() { return _edge_num; } + + /* functions to construct iterators from the graph, or from each other */ + + each_node_iterator first_node() { return each_node_iterator(_first_node); } + each_edge_iterator first_edge() { + node_item* v=_first_node; + edge_item* edge=v->_first_out_edge; + while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; } + return each_edge_iterator(v, edge); + } + + out_edge_iterator first_out_edge(const node_iterator& v) { + return out_edge_iterator(v); + } + in_edge_iterator first_in_edge(const node_iterator& v) { + return in_edge_iterator(v); + } + sym_edge_iterator first_sym_edge(const node_iterator& v) { + return sym_edge_iterator(v); + } + node_iterator tail(const edge_iterator& e) { return e.tail_node(); } + node_iterator head(const edge_iterator& e) { return e.head_node(); } + + node_iterator a_node(const out_edge_iterator& e) { return e.a_node(); } + node_iterator a_node(const in_edge_iterator& e) { return e.a_node(); } + node_iterator a_node(const sym_edge_iterator& e) { return e.a_node(); } + + node_iterator b_node(const out_edge_iterator& e) { return e.b_node(); } + node_iterator b_node(const in_edge_iterator& e) { return e.b_node(); } + node_iterator b_node(const sym_edge_iterator& e) { return e.b_node(); } + + //node_iterator invalid_node() { return node_iterator(); } + //edge_iterator invalid_edge() { return edge_iterator(); } + //out_edge_iterator invalid_out_edge() { return out_edge_iterator(); } + //in_edge_iterator invalid_in_edge() { return in_edge_iterator(); } + //sym_edge_iterator invalid_sym_edge() { return sym_edge_iterator(); } + + /* same methods in other style */ + /* for experimental purpose */ + + void get_first(each_node_iterator& v) { v=each_node_iterator(_first_node); } + void get_first(each_edge_iterator& e) { e=first_edge(); } + void get_first(out_edge_iterator& e, const node_iterator& v) { + e=out_edge_iterator(v); + } + void get_first(in_edge_iterator& e, const node_iterator& v) { + e=in_edge_iterator(v); + } + void get_first(sym_edge_iterator& e, const node_iterator& v) { + e=sym_edge_iterator(v); + } + void get_tail(node_iterator& n, const edge_iterator& e) { n=tail(e); } + void get_head(node_iterator& n, const edge_iterator& e) { n=head(e); } + + void get_a_node(node_iterator& n, const out_edge_iterator& e) { n=e.a_node(); } + void get_a_node(node_iterator& n, const in_edge_iterator& e) { n=e.a_node(); } + void get_a_node(node_iterator& n, const sym_edge_iterator& e) { n=e.a_node(); } + void get_b_node(node_iterator& n, const out_edge_iterator& e) { n=e.b_node(); } + void get_b_node(node_iterator& n, const in_edge_iterator& e) { n=e.b_node(); } + void get_b_node(node_iterator& n, const sym_edge_iterator& e) { n=e.b_node(); } + //void get_invalid(node_iterator& n) { n=node_iterator(); } + //void get_invalid(edge_iterator& e) { e=edge_iterator(); } + //void get_invalid(out_edge_iterator& e) { e=out_edge_iterator(); } + //void get_invalid(in_edge_iterator& e) { e=in_edge_iterator(); } + //void get_invalid(sym_edge_iterator& e) { e=sym_edge_iterator(); } + + + /* for getting id's of graph objects */ + /* these are important for the implementation of property vectors */ + + int id(const node_iterator& v) { return v.node->id; } + int id(const edge_iterator& e) { return e.edge->id; } + + /* adding nodes and edges */ + + node_iterator add_node() { return node_iterator(_add_node()); } + edge_iterator add_edge(const node_iterator& u, const node_iterator& v) { + return edge_iterator(_add_edge(u.node, v.node)); + } + + /* stream operations, for testing purpose */ + + friend std::ostream& operator<<(std::ostream& os, const node_iterator& i) { + os << i.node->id; return os; + } + friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i) { + os << "(" << i.edge->_tail->id << "--" << i.edge->id << "->" << i.edge->_head->id << ")"; + return os; + } + + class node_iterator { + friend class list_graph; + + friend class edge_iterator; + friend class out_edge_iterator; + friend class in_edge_iterator; + friend class sym_edge_iterator; + protected: + node_item* node; + friend int list_graph::id(const node_iterator& v); + public: + node_iterator() : node(0) { } + node_iterator(node_item* _node) : node(_node) { } + bool valid() { return (node!=0); } + void make_invalid() { node=0; } + friend bool operator==(const node_iterator& u, const node_iterator& v) { + return v.node==u.node; + } + friend bool operator!=(const node_iterator& u, const node_iterator& v) { + return v.node!=u.node; + } + friend std::ostream& operator<<(std::ostream& os, const node_iterator& i); + }; + + class each_node_iterator : public node_iterator { + friend class list_graph; + public: + each_node_iterator() : node_iterator() { } + each_node_iterator(node_item* v) : node_iterator(v) { } + each_node_iterator& operator++() { node=node->_next_node; return *this; } + }; + + class edge_iterator { + friend class list_graph; + + friend class node_iterator; + friend class each_node_iterator; + protected: + edge_item* edge; + friend int list_graph::id(const edge_iterator& e); + public: + edge_iterator() : edge(0) { } + edge_iterator(edge_item* _edge) : edge(_edge) { } + bool valid() { return (edge!=0); } + void make_invalid() { edge=0; } + friend bool operator==(const edge_iterator& u, const edge_iterator& v) { + return v.edge==u.edge; + } + friend bool operator!=(const edge_iterator& u, const edge_iterator& v) { + return v.edge!=u.edge; + } + protected: + node_iterator tail_node() const { return node_iterator(edge->_tail); } + node_iterator head_node() const { return node_iterator(edge->_head); } + public: + friend std::ostream& operator<<(std::ostream& os, const edge_iterator& i); + }; + + class each_edge_iterator : public edge_iterator { + friend class list_graph; + node_item* v; + public: + each_edge_iterator() : edge_iterator(), v(0) { } + each_edge_iterator(node_item* _v, edge_item* _e) : edge_iterator(_e), v(_v) { } + each_edge_iterator& operator++() { + edge=edge->_next_out; + while (v && !edge) { v=v->_next_node; if (v) edge=v->_first_out_edge; } + return *this; + } + }; + + class out_edge_iterator : public edge_iterator { + friend class list_graph; + node_item* v; + public: + out_edge_iterator() : edge_iterator(), v(0) { } + protected: + out_edge_iterator(const node_iterator& _v) : v(_v.node) { edge=v->_first_out_edge; } + public: + out_edge_iterator& operator++() { edge=edge->_next_out; return *this; } + protected: + node_iterator a_node() const { return node_iterator(v); } + node_iterator b_node() const { + return (edge->_tail==v) ? node_iterator(edge->_head) : node_iterator(edge->_tail); } + }; + + class in_edge_iterator : public edge_iterator { + friend class list_graph; + node_item* v; + public: + in_edge_iterator() : edge_iterator(), v(0) { } + protected: + in_edge_iterator(const node_iterator& _v) : v(_v.node) { + edge=v->_first_in_edge; + } + public: + in_edge_iterator& operator++() { edge=edge->_next_in; return *this; } + protected: + node_iterator a_node() const { return node_iterator(v); } + node_iterator b_node() const { + return (edge->_tail==v) ? node_iterator(edge->_head) : node_iterator(edge->_tail); } + }; + + class sym_edge_iterator : public edge_iterator { + friend class list_graph; + bool out_or_in; //1 iff out, 0 iff in + node_item* v; + public: + sym_edge_iterator() : edge_iterator(), v(0) { } + protected: + sym_edge_iterator(const node_iterator& _v) : v(_v.node) { + out_or_in=1; + edge=v->_first_out_edge; + if (!edge) { edge=v->_first_in_edge; out_or_in=0; } + } + public: + sym_edge_iterator& operator++() { + if (out_or_in) { + edge=edge->_next_out; + if (!edge) { out_or_in=0; edge=v->_first_in_edge; } + } else { + edge=edge->_next_in; + } + return *this; + } + protected: + node_iterator a_node() const { return node_iterator(v); } + node_iterator b_node() const { + return (edge->_tail==v) ? node_iterator(edge->_head) : node_iterator(edge->_tail); } + }; + + }; + + + +} //namespace hugo + +#endif //MARCI_LIST_GRAPH_HH