marci@189: // -*- c++ -*-
alpar@921: #ifndef LEMON_LEDA_GRAPH_WRAPPER_H
alpar@921: #define LEMON_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: 
alpar@921: #include <lemon/invalid.h>
marci@189: 
alpar@921: namespace lemon {
marci@189: 
alpar@921:   /// \brief A graph wrapper structure for wrapping LEDA graphs in LEMON.
marci@617:   ///
marci@617:   /// This graph wrapper class wraps LEDA graphs and LEDA parametrized graphs
alpar@921:   /// to satisfy LEMON graph concepts.
alpar@921:   /// Then the generic LEMON 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@650: 
marci@650:     /// Constructor for wrapping LEDA graphs.
marci@617:     LedaGraphWrapper(Graph& _l_graph) : l_graph(&_l_graph) { }
marci@650:     /// Copy constructor
marci@650:     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@646:     template <typename T> class NodeMapWrapper;
marci@646:     template <typename T> class EdgeMapWrapper;
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@650:     /// Trivial node-iterator
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@650:       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@650:       NodeIt() { } //FIXME
marci@189:       /// Initialize the iterator to be invalid
marci@650:       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@650:     /// Trivial edge-iterator.
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@650:       Edge() { }   //FIXME
marci@189:       /// Initialize the iterator to be invalid
marci@650:       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@650:     /// This iterator goes trought the outgoing edges of a certain node.
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@650:       OutEdgeIt() { }
marci@189:       /// Initialize the iterator to be invalid
marci@650:       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@650:     /// This iterator goes trought the incoming edges of a certain node.
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@650:       InEdgeIt() { }
marci@189:       /// Initialize the iterator to be invalid
marci@650:       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@650:     
marci@650:     /// This iterator goes trought the edges of the graph.
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@650:       EdgeIt() { }
marci@189:       /// Initialize the iterator to be invalid
marci@650:       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@650:     ///
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@650:     /// 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: 
alpar@986:     ///Gives back the target node of an edge.
alpar@986:     Node target(Edge e) const { 
marci@617:       return Node(l_graph->target(e.l_e)); 
marci@189:     }
alpar@986:     ///Gives back the source node of an edge.
alpar@986:     Node source(Edge e) const { 
marci@617:       return Node(l_graph->source(e.l_e)); 
marci@189:     }
marci@189:   
alpar@986:     Node aNode(InEdgeIt e) const { return target(e); }
alpar@986:     Node aNode(OutEdgeIt e) const { return source(e); }
marci@189:     //   Node aNode(SymEdgeIt) const {}
marci@189: 
alpar@986:     Node bNode(InEdgeIt e) const { return source(e); }
alpar@986:     Node bNode(OutEdgeIt e) const { return target(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()); }
alpar@986:     Edge addEdge(Node source, Node target) const { 
alpar@986:       return Edge(l_graph->new_edge(source.l_n, target.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@650:     /// 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:
alpar@987:       typedef T Value;
alpar@987:       typedef Node Key;
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@650:     /// 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:
alpar@987:       typedef T Value;
alpar@987:       typedef Edge Key;
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@646: 
marci@650:     /// This class is to wrap existing 
alpar@921:     /// LEDA node-maps to LEMON ones.
marci@646:     template<typename T> class NodeMapWrapper
marci@646:     {
marci@650:       leda_node_array<T>* leda_stuff;
marci@646:     public:
alpar@987:       typedef T Value;
alpar@987:       typedef Node Key;
marci@646: 
marci@650:       NodeMapWrapper(leda_node_array<T>& _leda_stuff) : 
marci@646: 	leda_stuff(&_leda_stuff) { }
marci@646:       //NodeMap(leda_node_map& &G, T t) : leda_stuff(*(G.l_graph), t) {}
marci@646: 
marci@646:       void set(Node i, T t) { (*leda_stuff)[i.l_n]=t; }
marci@650:       //T get(Node i) const { return (*leda_stuff)[i.l_n]; }  //FIXME: Is it necessary
marci@646:       T &operator[](Node i) { return (*leda_stuff)[i.l_n]; }
marci@646:       const T &operator[](Node i) const { return (*leda_stuff)[i.l_n]; }
marci@646: 
marci@646:       void update() { /*leda_stuff.init(leda_stuff.get_graph());*/ }
marci@646:       //void update(T a) { leda_stuff.init(leda_stuff.get_graph()/**(G.l_graph)*/, a); }   //FIXME: Is it necessary
marci@646:     };
marci@646: 
marci@650:     /// This class is to wrap existing 
alpar@921:     /// LEDA edge-maps to LEMON ones.
marci@646:     template<typename T> class EdgeMapWrapper
marci@646:     {
marci@650:       leda_edge_array<T>* leda_stuff;
marci@646:     public:
alpar@987:       typedef T Value;
alpar@987:       typedef Edge Key;
marci@646: 
marci@650:       EdgeMapWrapper(leda_edge_array<T>& _leda_stuff) : 
marci@646: 	leda_stuff(_leda_stuff) { }
marci@646:       //EdgeMap(const LedaGraphWrapper &G, T t) : leda_stuff(*(G.l_graph), t) {}
marci@646: 
marci@646:       void set(Edge i, T t) { (*leda_stuff)[i.l_e]=t; }
marci@650:       //T get(Edge i) const { return (*leda_stuff)[i.l_e]; }  //FIXME: Is it necessary
marci@646:       T &operator[](Edge i) { return (*leda_stuff)[i.l_e]; }
marci@646:       const T &operator[](Edge i) const { return (*leda_stuff)[i.l_e]; }
marci@646: 
marci@646:       void update() { /*leda_stuff.init(leda_stuff.get_graph());*/ }
marci@646:       //void update(T a) { leda_stuff.init(leda_stuff.get_graph()/**(G.l_graph)*/, a); }   //FIXME: Is it necessary
marci@646:     };
marci@646: 
marci@650:     /// This class is used for access node-data of 
marci@650:     /// LEDA parametrized graphs.
marci@650:     template<typename T> 
marci@650:     class NodeDataMap : public NodeMapWrapper<T>
marci@650:     {
marci@650:     public:
marci@650:       NodeDataMap(LedaGraphWrapper<Graph>& LGW) : 
marci@650: 	NodeMapWrapper<T>(*(LGW._g_graph).node_data()) { }
marci@650:     };
marci@650: 
marci@650:     /// This class is used for access edge-data of 
marci@650:     /// LEDA parametrized graphs.
marci@650:     template<typename T> 
marci@650:     class EdgeDataMap : public EdgeMapWrapper<T>
marci@650:     {
marci@650:     public:
marci@650:       EdgeDataMap(LedaGraphWrapper<Graph>& LGW) : 
marci@650: 	EdgeMapWrapper<T>(*(LGW._g_graph).edge_data()) { }
marci@650:     };
marci@650: 
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: 
alpar@921: } //namespace lemon
marci@189: 
alpar@921: #endif // LEMON_LEDA_GRAPH_WRAPPER_H