marci@189: // -*- c++ -*-
marci@189: #ifndef HUGO_LEDA_GRAPH_WRAPPER_H
marci@189: #define HUGO_LEDA_GRAPH_WRAPPER_H
marci@189: 
marci@189: #include <LEDA/graph.h>
marci@189: #include <LEDA/node_array.h>
marci@189: #include <LEDA/edge_array.h>
marci@189: #include <LEDA/node_map.h>
marci@189: #include <LEDA/edge_map.h>
marci@189: //#include <LEDA/graph_alg.h>
marci@189: //#include <LEDA/dimacs.h>
marci@189: 
marci@189: //#if defined(LEDA_NAMESPACE)
marci@189: //using namespace leda;
marci@189: //#endif
marci@189: 
marci@616: #include <hugo/invalid.h>
marci@189: 
marci@189: namespace hugo {
marci@189: 
marci@617:   /// \brief A graph wrapper structure for wrapping LEDA graphs in HUGO.
marci@617:   ///
marci@617:   /// This graph wrapper class wraps LEDA graphs and LEDA parametrized graphs
marci@617:   /// to satisfy HUGO graph concepts.
marci@617:   /// Then the generic HUGOlib algorithms and wrappers can be used 
marci@409:   /// with LEDA graphs. 
marci@617:   /// \ingroup gwrapper
marci@189:   template<typename Graph>
marci@189:   class LedaGraphWrapper
marci@189:   {
marci@473:   protected:
marci@617:     Graph* l_graph;
marci@617:     LedaGraphWrapper() : l_graph(0) { }
marci@617:     void setGraph(Graph& _l_graph) { l_graph=&_l_graph; }
marci@189:   public:
marci@189:    
marci@189:         //LedaGraphWrapper() { }
marci@617:     LedaGraphWrapper(Graph& _l_graph) : l_graph(&_l_graph) { }
marci@617:     LedaGraphWrapper(const LedaGraphWrapper &G) : l_graph(G.l_graph) { }
marci@189: 
marci@189:     template <typename T> class NodeMap;
marci@189:     template <typename T> class EdgeMap;
marci@189: 
marci@461:     class Node;
marci@461:     class NodeIt;
marci@461:     class Edge;
marci@461:     class EdgeIt;
marci@461:     class OutEdgeIt;
marci@461:     class InEdgeIt;
marci@461: 
marci@189:     /// The base type of the node iterators.
marci@189:     class Node {
marci@461:       friend class LedaGraphWrapper<Graph>;
marci@189:       //friend class Edge;
marci@189:       friend class EdgeIt;
marci@189:       friend class InEdgeIt;
marci@189:       friend class OutEdgeIt;
marci@189:     protected:
marci@189:       template <typename T> friend class NodeMap;
marci@617:       leda_node l_n;
marci@446:     public: //FIXME
marci@617:       Node(leda_node _l_n) : l_n(_l_n) { } 
marci@189:     public:
marci@189:       /// @warning The default constructor sets the iterator
marci@189:       /// to an undefined value.
marci@189:       Node() {}   //FIXME
marci@189:       /// Initialize the iterator to be invalid
marci@617:       Node(Invalid) : l_n(0) { }
marci@189:       //Node(const Node &) {} 
marci@617:       bool operator==(Node n) const { return l_n==n.l_n; } //FIXME
marci@617:       bool operator!=(Node n) const { return l_n!=n.l_n; } //FIXME
marci@617:       operator leda_node () { return l_n; }
marci@189:     };
marci@189:     
marci@189:     /// This iterator goes through each node.
marci@189:     class NodeIt : public Node {
marci@189:     public:
marci@189:       /// @warning The default constructor sets the iterator
marci@189:       /// to an undefined value.
marci@189:       NodeIt() {} //FIXME
marci@189:       /// Initialize the iterator to be invalid
marci@189:       NodeIt(Invalid i) : Node(i) {}
marci@189:       /// Sets the iterator to the first node of \c G.
marci@617:       NodeIt(const LedaGraphWrapper &G) : Node(G.l_graph->first_node()) { }
marci@189:       //NodeIt(const NodeIt &) {} //FIXME
marci@189:     };
marci@189:     
marci@189:     /// The base type of the edge iterators.
marci@189:     class Edge {
marci@189:       friend class LedaGraphWrapper;
marci@189:     protected:
marci@189:       template <typename T> friend class EdgeMap;
marci@617:       leda_edge l_e;
marci@446:     public: //FIXME
marci@617:       Edge(leda_edge _l_e) : l_e(_l_e) { } 
marci@189:     public:
marci@189:       /// @warning The default constructor sets the iterator
marci@189:       /// to an undefined value.
marci@189:       Edge() {}   //FIXME
marci@189:       /// Initialize the iterator to be invalid
marci@617:       Edge(Invalid) : l_e(0) {}
marci@189:       //Edge(const Edge &) {} 
marci@617:       bool operator==(Edge e) const { return l_e==e.l_e; } //FIXME
marci@617:       bool operator!=(Edge e) const { return l_e!=e.l_e; } //FIXME 
marci@617:       operator leda_edge () { return l_e; }
marci@189:     };
marci@189:     
marci@189:     /// This iterator goes trought the outgoing edges of a certain graph.
marci@189:     
marci@189:     class OutEdgeIt : public Edge {
marci@189:     public:
marci@189:       /// @warning The default constructor sets the iterator
marci@189:       /// to an undefined value.
marci@189:       OutEdgeIt() {}
marci@189:       /// Initialize the iterator to be invalid
marci@189:       OutEdgeIt(Invalid i) : Edge(i) {}
marci@189:       /// This constructor sets the iterator to first outgoing edge.
marci@189:     
marci@189:       /// This constructor set the iterator to the first outgoing edge of
marci@189:       /// node
marci@189:       ///@param n the node
marci@189:       ///@param G the graph
marci@617:       OutEdgeIt(const LedaGraphWrapper & G, Node n) : Edge(G.l_graph->first_adj_edge(n.l_n)) { }
marci@189:     };
marci@189: 
marci@189:     class InEdgeIt : public Edge {
marci@189:     public:
marci@189:       /// @warning The default constructor sets the iterator
marci@189:       /// to an undefined value.
marci@189:       InEdgeIt() {}
marci@189:       /// Initialize the iterator to be invalid
marci@189:       InEdgeIt(Invalid i) : Edge(i) {}
marci@617:       InEdgeIt(const LedaGraphWrapper & G, Node n) : Edge(G.l_graph->first_in_edge(n.l_n)) { }
marci@189:     };
marci@189: 
marci@189:     //  class SymEdgeIt : public Edge {};
marci@189:     class EdgeIt : public Edge {
marci@189:     public:
marci@189:       /// @warning The default constructor sets the iterator
marci@189:       /// to an undefined value.
marci@189:       EdgeIt() {}
marci@189:       /// Initialize the iterator to be invalid
marci@189:       EdgeIt(Invalid i) : Edge(i) {}
marci@617:       EdgeIt(const LedaGraphWrapper & G) : Edge(G.l_graph->first_edge()) { }
marci@189:     };
marci@189: 
marci@189:     /// First node of the graph.
marci@189: 
marci@189:     /// \post \c i and the return value will be the first node.
marci@189:     ///
marci@189:     NodeIt &first(NodeIt &i) const { i=NodeIt(*this); return i; }
marci@189: 
marci@189:     /// The first outgoing edge.
marci@189:     InEdgeIt &first(InEdgeIt &i, Node n) const { 
marci@189:       i=InEdgeIt(*this, n); 
marci@189:       return i;
marci@189:     }
marci@189:     /// The first incoming edge.
marci@189:     OutEdgeIt &first(OutEdgeIt &i, Node n) const { 
marci@189:       i=OutEdgeIt(*this, n); 
marci@189:       return i;
marci@189:     }
marci@189:     //  SymEdgeIt &first(SymEdgeIt &, Node) const { return i;}
marci@189:     /// The first edge of the Graph.
marci@189:     EdgeIt &first(EdgeIt &i) const {      
marci@189:       i=EdgeIt(*this); 
marci@189:       return i; }
marci@189: 
marci@189: //     Node getNext(Node) const {}
marci@189: //     InEdgeIt getNext(InEdgeIt) const {}
marci@189: //     OutEdgeIt getNext(OutEdgeIt) const {}
marci@189: //     //SymEdgeIt getNext(SymEdgeIt) const {}
marci@189: //     EdgeIt getNext(EdgeIt) const {}
marci@189: 
marci@189:     /// Go to the next node.
marci@189:     NodeIt &next(NodeIt &i) const { 
marci@617:       i.l_n=l_graph->succ_node(i.l_n); 
marci@189:       return i; 
marci@189:     }
marci@189:     /// Go to the next incoming edge.
marci@189:     InEdgeIt &next(InEdgeIt &i) const { 
marci@617:       i.l_e=l_graph->in_succ(i.l_e); 
marci@189:       return i;
marci@189:     }
marci@189:     /// Go to the next outgoing edge.
marci@189:     OutEdgeIt &next(OutEdgeIt &i) const { 
marci@617:       i.l_e=l_graph->adj_succ(i.l_e); 
marci@189:       return i;
marci@189:     }
marci@189:     //SymEdgeIt &next(SymEdgeIt &) const {}
marci@189:     /// Go to the next edge.
marci@189:     EdgeIt &next(EdgeIt &i) const {      
marci@617:       i.l_e=l_graph->succ_edge(i.l_e); 
marci@189:       return i; 
marci@189:     }
marci@189: 
marci@409: //     template< typename It >
marci@409: //     It first() const { 
marci@409: //       It e;
marci@409: //       first(e);
marci@409: //       return e; 
marci@409: //     }
marci@189: 
marci@409: //     template< typename It >
marci@409: //     It first(Node v) const { 
marci@409: //       It e;
marci@409: //       first(e, v);
marci@409: //       return e; 
marci@409: //     }
marci@189: 
marci@189:     ///Gives back the head node of an edge.
marci@189:     Node head(Edge e) const { 
marci@617:       return Node(l_graph->target(e.l_e)); 
marci@189:     }
marci@189:     ///Gives back the tail node of an edge.
marci@189:     Node tail(Edge e) const { 
marci@617:       return Node(l_graph->source(e.l_e)); 
marci@189:     }
marci@189:   
marci@189:     Node aNode(InEdgeIt e) const { return head(e); }
marci@189:     Node aNode(OutEdgeIt e) const { return tail(e); }
marci@189:     //   Node aNode(SymEdgeIt) const {}
marci@189: 
marci@189:     Node bNode(InEdgeIt e) const { return tail(e); }
marci@189:     Node bNode(OutEdgeIt e) const { return head(e); }
marci@189:     //   Node bNode(SymEdgeIt) const {}
marci@189: 
marci@189:     /// Checks if a node iterator is valid
marci@617:     bool valid(Node n) const { return n.l_n; }
marci@189:     /// Checks if an edge iterator is valid
marci@617:     bool valid(Edge e) const { return e.l_e; }
marci@189: 
marci@189:     ///Gives back the \e id of a node.
marci@617:     int id(Node n) const { return n.l_n->id(); }
marci@189:     ///Gives back the \e id of an edge.
marci@617:     int id(Edge e) const { return e.l_e->id(); }
marci@189: 
marci@189:     //void setInvalid(Node &) const {};
marci@189:     //void setInvalid(Edge &) const {};
marci@189:   
marci@617:     Node addNode() const { return Node(l_graph->new_node()); }
marci@189:     Edge addEdge(Node tail, Node head) const { 
marci@617:       return Edge(l_graph->new_edge(tail.l_n, head.l_n));
marci@189:     }
marci@189:     
marci@617:     void erase(Node n) const { l_graph->del_node(n.l_n); }
marci@617:     void erase(Edge e) const { l_graph->del_edge(e.l_e); }
marci@189: 
marci@617:     void clear() const { l_graph->clear(); }
marci@189: 
marci@617:     int nodeNum() const { return l_graph->number_of_nodes(); }
marci@617:     int edgeNum() const { return l_graph->number_of_edges(); }
marci@189: 
marci@189:     ///Read/write map from the nodes to type \c T.
marci@189:     template<typename T> class NodeMap
marci@189:     {
marci@189:       leda_node_map<T> leda_stuff;
marci@189:     public:
marci@189:       typedef T ValueType;
marci@189:       typedef Node KeyType;
marci@189: 
marci@617:       NodeMap(const LedaGraphWrapper &G) : leda_stuff(*(G.l_graph)) {}
marci@617:       NodeMap(const LedaGraphWrapper &G, T t) : leda_stuff(*(G.l_graph), t) {}
marci@189: 
marci@617:       void set(Node i, T t) { leda_stuff[i.l_n]=t; }
marci@617:       T get(Node i) const { return leda_stuff[i.l_n]; }  //FIXME: Is it necessary
marci@617:       T &operator[](Node i) { return leda_stuff[i.l_n]; }
marci@617:       const T &operator[](Node i) const { return leda_stuff[i.l_n]; }
marci@189: 
marci@189:       void update() { /*leda_stuff.init(leda_stuff.get_graph());*/ }
marci@617:       //void update(T a) { leda_stuff.init(leda_stuff.get_graph()/**(G.l_graph)*/, a); }   //FIXME: Is it necessary
marci@189:     };
marci@189: 
marci@189:     ///Read/write map from the edges to type \c T.
marci@189:     template<typename T> class EdgeMap
marci@189:     {
marci@189:       leda_edge_map<T> leda_stuff;
marci@189:     public:
marci@189:       typedef T ValueType;
marci@189:       typedef Edge KeyType;
marci@189: 
marci@617:       EdgeMap(const LedaGraphWrapper &G) : leda_stuff(*(G.l_graph)) {}
marci@617:       EdgeMap(const LedaGraphWrapper &G, T t) : leda_stuff(*(G.l_graph), t) {}
marci@189: 
marci@617:       void set(Edge i, T t) { leda_stuff[i.l_e]=t; }
marci@617:       T get(Edge i) const { return leda_stuff[i.l_e]; }  //FIXME: Is it necessary
marci@617:       T &operator[](Edge i) { return leda_stuff[i.l_e]; }
marci@617:       const T &operator[](Edge i) const { return leda_stuff[i.l_e]; }
marci@189: 
marci@189:       void update() { /*leda_stuff.init(leda_stuff.get_graph());*/ }
marci@617:       //void update(T a) { leda_stuff.init(leda_stuff.get_graph()/**(G.l_graph)*/, a); }   //FIXME: Is it necessary
marci@189:     };
marci@189: 
marci@189:   };
marci@189: 
marci@617: 
marci@617:   /// \brief LEDA graph template.
marci@617:   ///
marci@617:   /// This graph stucture uses LEDA graphs for physical storage.
marci@617:   /// \ingroup graphs
marci@473:   template<typename Graph>
marci@473:   class LedaGraph : public LedaGraphWrapper<Graph> {
marci@473:     typedef LedaGraphWrapper<Graph> Parent;
marci@473:   protected:
marci@473:     Graph gr;
marci@473:   public:
marci@473:     LedaGraph() { 
marci@473:       Parent::setGraph(gr); 
marci@473:     }
marci@473:   };
marci@473: 
marci@189: } //namespace hugo
marci@189: 
marci@189: #endif // HUGO_LEDA_GRAPH_WRAPPER_H