/* -*- 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 namespace lemon { template class MergeNodeGraphWrapper : public GraphWrapper, public GraphWrapper { typedef GraphWrapper Parent1; typedef GraphWrapper Parent2; typedef typename GraphWrapper::Node Graph1Node; typedef typename GraphWrapper::Node Graph2Node; public: class Node; class NodeIt; friend class Node; friend class NodeIt; template class NodeMap; MergeNodeGraphWrapper(Graph1& _graph1, Graph2& _graph2) : Parent1(_graph1), Parent2(_graph2) { } class Node : public Graph1Node, public Graph2Node { friend class MergeNodeGraphWrapper; 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)); } }; class NodeIt : public Node { friend class MergeNodeGraphWrapper; protected: const MergeNodeGraphWrapper* gw; public: NodeIt() { } NodeIt(Invalid i) : Node(i) { } NodeIt(const MergeNodeGraphWrapper& _gw) : Node(typename Graph1::NodeIt(*_gw.Parent1::graph), typename Graph2::Node(), false), gw(&_gw) { if (*static_cast(this)==INVALID) { // *static_cast(this)= // Node(Graph1Node(INVALID), // typename Graph2::NodeIt(*_gw.Parent2::graph), // true); *static_cast(this)= typename Graph2::NodeIt(*_gw.Parent2::graph); backward=true; } } NodeIt(const MergeNodeGraphWrapper& _gw, const Node& n) : Node(n), gw(&_gw) { } NodeIt& operator++() { if (!this->backward) { *(static_cast(this))= ++(typename Graph1::NodeIt(*gw->Parent1::graph, *this)); if (*static_cast(this)==INVALID) { // *static_cast(this)= // Node(typename Graph1::Node(INVALID), // typename Graph2::NodeIt(*gw->Parent2::graph), true); *static_cast(this)= typename Graph2::NodeIt(*gw->Parent2::graph); backward=true; } } else { *(static_cast(this))= ++(typename Graph2::NodeIt(*gw->Parent2::graph, *this)); } return *this; } }; 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, public Parent2::template NodeMap { typedef typename Parent1::template NodeMap ParentMap1; typedef typename Parent2::template NodeMap ParentMap2; public: NodeMap(const MergeNodeGraphWrapper& gw) : ParentMap1(gw), ParentMap2(gw) { } NodeMap(const MergeNodeGraphWrapper& 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[]; }; }; } //namespace lemon #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H