/* -*- C++ -*- * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library * * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport * (Egervary Combinatorial Optimization Research Group, EGRES). * * Permission to use, modify and distribute this software is granted * provided that this copyright notice appears in all copies. For * precise terms see the accompanying LICENSE file. * * This software is provided "AS IS" with no warranty of any kind, * express or implied, and with no claim as to its suitability for any * purpose. * */ #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H #include #include #include #include #include using std::cout; using std::endl; #include #include namespace lemon { template class P1 : public GraphWrapperBase<_Graph1> { }; template class P2 : public GraphWrapperBase<_Graph2> { }; template class MergeNodeGraphWrapperBase : public P1<_Graph1>, public P2<_Graph2> { public: void print() const { std::cout << "generic" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; typedef P2<_Graph2> Parent2; typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: MergeNodeGraphWrapperBase() { } public: template class NodeMap; class Node : public Graph1Node, public Graph2Node { friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; template friend class NodeMap; protected: bool backward; //true, iff backward public: Node() { } /// \todo =false is needed, or causes problems? /// If \c _backward is false, then we get an edge corresponding to the /// original one, otherwise its oppositely directed pair is obtained. Node(const Graph1Node& n1, const Graph2Node& n2, bool _backward) : Graph1Node(n1), Graph2Node(n2), backward(_backward) { } Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { } bool operator==(const Node& v) const { return (this->backward==v.backward && static_cast(*this)== static_cast(v) && static_cast(*this)== static_cast(v)); } bool operator!=(const Node& v) const { return (this->backward!=v.backward || static_cast(*this)!= static_cast(v) || static_cast(*this)!= static_cast(v)); } }; //typedef void Edge; class Edge { }; void first(Node& i) const { Parent1::graph->first(*static_cast(&i)); i.backward=false; if (*static_cast(&i)==INVALID) { Parent2::graph->first(*static_cast(&i)); i.backward=true; } } void next(Node& i) const { if (!(i.backward)) { Parent1::graph->next(*static_cast(&i)); if (*static_cast(&i)==INVALID) { Parent2::graph->first(*static_cast(&i)); i.backward=true; } } else { Parent2::graph->next(*static_cast(&i)); } } int id(const Node& n) const { if (!n.backward) return this->Parent1::graph->id(n); else return this->Parent2::graph->id(n); } template class NodeMap : public Parent1::template NodeMap<_Value>, public Parent2::template NodeMap<_Value> { typedef typename Parent1::template NodeMap<_Value> ParentMap1; typedef typename Parent2::template NodeMap<_Value> ParentMap2; public: typedef _Value Value; typedef Node Key; NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : ParentMap1(gw), ParentMap2(gw) { } NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, const _Value& value) : ParentMap1(gw, value), ParentMap2(gw, value) { } _Value operator[](const Node& n) const { if (!n.backward) return ParentMap1::operator[](n); else return ParentMap2::operator[](n); } void set(const Node& n, const _Value& value) { if (!n.backward) ParentMap1::set(n, value); else ParentMap2::set(n, value); } using ParentMap1::operator[]; using ParentMap2::operator[]; }; }; //not yet working template class MergeNodeGraphWrapperBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_same >::type> : public P1<_Graph1>, public P2<_Graph2> { public : void print() const { std::cout << "same" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; typedef P2<_Graph2> Parent2; typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: MergeNodeGraphWrapperBase() { } public: class Node { }; class Edge { }; void first() const; void next() const; }; //not yet working template class MergeNodeGraphWrapperBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_base_and_derived >::type> : public P1<_Graph1>, public P2<_Graph2> { public : void print() const { std::cout << "2. nagyobb" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; typedef P2<_Graph2> Parent2; typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: MergeNodeGraphWrapperBase() { } public: class Node { }; class Edge { }; void first() const; void next() const; }; //not yet working template class MergeNodeGraphWrapperBase< _Graph1, _Graph2, typename boost::enable_if< boost::is_base_and_derived >::type> : public P1<_Graph1>, public P2<_Graph2> { public : void print() const { std::cout << "1. nagyobb" << std::endl; } typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef P1<_Graph1> Parent1; typedef P2<_Graph2> Parent2; typedef typename Parent1::Node Graph1Node; typedef typename Parent2::Node Graph2Node; protected: MergeNodeGraphWrapperBase() { } public: class Node { }; class Edge { }; void first() const; void next() const; }; template class MergeNodeGraphWrapper : public IterableGraphExtender > { public: typedef _Graph1 Graph1; typedef _Graph2 Graph2; typedef IterableGraphExtender< MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent; protected: MergeNodeGraphWrapper() { } public: MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { Parent::Parent1::setGraph(_graph1); Parent::Parent2::setGraph(_graph2); } }; template class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> { public: typedef GraphWrapperBase<_Graph> Parent; typedef _Graph Graph; typedef _EdgeSetGraph EdgeSetGraph; typedef typename _Graph::Node Node; typedef typename _EdgeSetGraph::Node ENode; protected: EdgeSetGraph* edge_set_graph; typename Graph::NodeMap* e_node; typename EdgeSetGraph::NodeMap* n_node; void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) { edge_set_graph=&_edge_set_graph; } /// For each node of \c Graph, this gives a node of \c EdgeSetGraph . void setNodeMap(typename EdgeSetGraph::NodeMap& _n_node) { n_node=&_n_node; } /// For each node of \c EdgeSetGraph, this gives a node of \c Graph . void setENodeMap(typename Graph::NodeMap& _e_node) { e_node=&_e_node; } public: class Edge : public EdgeSetGraph::Edge { typedef typename EdgeSetGraph::Edge Parent; public: Edge() { } Edge(const Parent& e) : Parent(e) { } Edge(Invalid i) : Parent(i) { } }; using Parent::first; void first(Edge &e) const { edge_set_graph->first(e); } void firstOut(Edge& e, const Node& n) const { // cout << e_node << endl; // cout << n_node << endl; edge_set_graph->firstOut(e, (*e_node)[n]); } void firstIn(Edge& e, const Node& n) const { edge_set_graph->firstIn(e, (*e_node)[n]); } using Parent::next; void next(Edge &e) const { edge_set_graph->next(e); } void nextOut(Edge& e) const { edge_set_graph->nextOut(e); } void nextIn(Edge& e) const { edge_set_graph->nextIn(e); } Node source(const Edge& e) const { return (*n_node)[edge_set_graph->source(e)]; } Node target(const Edge& e) const { return (*n_node)[edge_set_graph->target(e)]; } int edgeNum() const { return edge_set_graph->edgeNum(); } Edge addEdge(const Node& u, const Node& v) { return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]); } using Parent::erase; void erase(const Edge& i) const { edge_set_graph->erase(i); } void clear() const { Parent::clear(); edge_set_graph->clear(); } bool forward(const Edge& e) const { return edge_set_graph->forward(e); } bool backward(const Edge& e) const { return edge_set_graph->backward(e); } using Parent::id; int id(const Edge& e) const { return edge_set_graph->id(e); } Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); } template class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> { public: typedef typename EdgeSetGraph::EdgeMap<_Value> Parent; typedef _Value Value; typedef Edge Key; EdgeMap(const NewEdgeSetGraphWrapperBase& gw) : Parent(*(gw.edge_set_graph)) { } EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) : Parent(*(gw.edge_set_graph), _value) { } }; }; template class NewEdgeSetGraphWrapper : public IterableGraphExtender< NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > { public: typedef _Graph Graph; typedef _EdgeSetGraph EdgeSetGraph; typedef IterableGraphExtender< NewEdgeSetGraphWrapper<_Graph, _EdgeSetGraph> > Parent; protected: NewEdgeSetGraphWrapper() { } public: NewEdgeSetGraphWrapper(_Graph& _graph, _EdgeSetGraph& _edge_set_graph, typename _Graph:: NodeMap& _e_node, typename _EdgeSetGraph:: NodeMap& _n_node) { setGraph(_graph); setEdgeSetGraph(_edge_set_graph); setNodeMap(_n_node); setENodeMap(_e_node); } }; } //namespace lemon #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H