/* -*- 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 #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) { } // NodeMap(const NodeMap& copy) // : ParentMap1(copy), // ParentMap2(copy) { } // template // NodeMap(const NodeMap& copy) // : ParentMap1(copy), // ParentMap2(copy) { } // NodeMap& operator=(const NodeMap& copy) { // ParentMap1::operator=(copy); // ParentMap2::operator=(copy); // return *this; // } // template // NodeMap& operator=(const NodeMap& copy) { // ParentMap1::operator=(copy); // ParentMap2::operator=(copy); // return *this; // } _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[]; }; }; 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; }; 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; }; 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); } }; } //namespace lemon #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H