marci@915: /* -*- C++ -*- alpar@921: * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library marci@915: * marci@915: * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport marci@915: * (Egervary Combinatorial Optimization Research Group, EGRES). marci@915: * marci@915: * Permission to use, modify and distribute this software is granted marci@915: * provided that this copyright notice appears in all copies. For marci@915: * precise terms see the accompanying LICENSE file. marci@915: * marci@915: * This software is provided "AS IS" with no warranty of any kind, marci@915: * express or implied, and with no claim as to its suitability for any marci@915: * purpose. marci@915: * marci@915: */ marci@915: alpar@921: #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H alpar@921: #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H marci@917: alpar@921: #include alpar@921: #include alpar@921: #include alpar@921: #include marci@915: #include marci@915: alpar@921: namespace lemon { marci@915: marci@917: template marci@915: class MergeNodeGraphWrapper : marci@915: public GraphWrapper, public GraphWrapper { marci@915: typedef GraphWrapper Parent1; marci@915: typedef GraphWrapper Parent2; marci@915: typedef typename GraphWrapper::Node Graph1Node; marci@915: typedef typename GraphWrapper::Node Graph2Node; marci@915: public: marci@915: class Node; marci@915: class NodeIt; marci@915: friend class Node; marci@915: friend class NodeIt; marci@917: template class NodeMap; marci@915: marci@915: MergeNodeGraphWrapper(Graph1& _graph1, Graph2& _graph2) : marci@915: Parent1(_graph1), Parent2(_graph2) { } marci@915: marci@915: class Node : public Graph1Node, public Graph2Node { marci@915: friend class MergeNodeGraphWrapper; marci@917: template friend class NodeMap; marci@915: protected: marci@915: bool backward; //true, iff backward marci@915: public: marci@915: Node() { } marci@915: /// \todo =false is needed, or causes problems? marci@915: /// If \c _backward is false, then we get an edge corresponding to the marci@915: /// original one, otherwise its oppositely directed pair is obtained. marci@915: Node(const Graph1Node& n1, marci@915: const Graph2Node& n2, bool _backward) : marci@915: Graph1Node(n1), Graph2Node(n2), backward(_backward) { } marci@915: Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { } marci@915: bool operator==(const Node& v) const { marci@915: return (this->backward==v.backward && marci@915: static_cast(*this)== marci@915: static_cast(v) && marci@915: static_cast(*this)== marci@915: static_cast(v)); marci@915: } marci@915: bool operator!=(const Node& v) const { marci@915: return (this->backward!=v.backward || marci@915: static_cast(*this)!= marci@915: static_cast(v) || marci@915: static_cast(*this)!= marci@915: static_cast(v)); marci@915: } marci@915: }; marci@915: marci@915: class NodeIt : public Node { marci@915: friend class MergeNodeGraphWrapper; marci@915: protected: marci@915: const MergeNodeGraphWrapper* gw; marci@915: public: marci@915: NodeIt() { } marci@915: NodeIt(Invalid i) : Node(i) { } marci@915: NodeIt(const MergeNodeGraphWrapper& _gw) : marci@915: Node(typename Graph1::NodeIt(*_gw.Parent1::graph), marci@917: typename Graph2::Node(), marci@915: false), gw(&_gw) { marci@915: if (*static_cast(this)==INVALID) { marci@917: // *static_cast(this)= marci@917: // Node(Graph1Node(INVALID), marci@917: // typename Graph2::NodeIt(*_gw.Parent2::graph), marci@917: // true); marci@917: *static_cast(this)= marci@917: typename Graph2::NodeIt(*_gw.Parent2::graph); marci@917: backward=true; marci@915: } marci@915: } marci@915: NodeIt(const MergeNodeGraphWrapper& _gw, marci@915: const Node& n) : marci@915: Node(n), gw(&_gw) { } marci@915: NodeIt& operator++() { marci@915: if (!this->backward) { marci@915: *(static_cast(this))= marci@915: ++(typename Graph1::NodeIt(*gw->Parent1::graph, *this)); marci@915: if (*static_cast(this)==INVALID) { marci@917: // *static_cast(this)= marci@917: // Node(typename Graph1::Node(INVALID), marci@917: // typename Graph2::NodeIt(*gw->Parent2::graph), true); marci@917: *static_cast(this)= marci@917: typename Graph2::NodeIt(*gw->Parent2::graph); marci@917: backward=true; marci@915: } marci@915: } else { marci@915: *(static_cast(this))= marci@915: ++(typename Graph2::NodeIt(*gw->Parent2::graph, *this)); marci@915: } marci@915: return *this; marci@915: } marci@915: }; marci@915: marci@915: int id(const Node& n) const { marci@915: if (!n.backward) marci@915: return this->Parent1::graph->id(n); marci@915: else marci@915: return this->Parent2::graph->id(n); marci@915: } marci@915: marci@917: template marci@917: class NodeMap : public Parent1::template NodeMap, marci@917: public Parent2::template NodeMap { marci@917: typedef typename Parent1::template NodeMap ParentMap1; marci@917: typedef typename Parent2::template NodeMap ParentMap2; marci@917: public: marci@917: NodeMap(const MergeNodeGraphWrapper& gw) : marci@917: ParentMap1(gw), marci@917: ParentMap2(gw) { } marci@917: NodeMap(const MergeNodeGraphWrapper& gw, marci@917: const Value& value) marci@917: : ParentMap1(gw, value), marci@917: ParentMap2(gw, value) { } marci@917: NodeMap(const NodeMap& copy) marci@917: : ParentMap1(copy), marci@917: ParentMap2(copy) { } marci@917: template marci@917: NodeMap(const NodeMap& copy) marci@917: : ParentMap1(copy), marci@917: ParentMap2(copy) { } marci@917: NodeMap& operator=(const NodeMap& copy) { marci@917: ParentMap1::operator=(copy); marci@917: ParentMap2::operator=(copy); marci@917: return *this; marci@917: } marci@917: template marci@917: NodeMap& operator=(const NodeMap& copy) { marci@917: ParentMap1::operator=(copy); marci@917: ParentMap2::operator=(copy); marci@917: return *this; marci@917: } marci@917: Value operator[](const Node& n) const { marci@917: if (!n.backward) marci@917: return ParentMap1::operator[](n); marci@917: else marci@917: return ParentMap2::operator[](n); marci@917: } marci@917: void set(const Node& n, const Value& value) { marci@917: if (!n.backward) marci@917: ParentMap1::set(n, value); marci@917: else marci@917: ParentMap2::set(n, value); marci@917: } marci@917: using ParentMap1::operator[]; marci@917: using ParentMap2::operator[]; marci@917: }; marci@917: marci@915: }; marci@915: alpar@921: } //namespace lemon marci@915: alpar@921: #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H