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@1002: template marci@1002: class MergeNodeGraphWrapperBase : marci@1002: public GraphWrapperBase<_Graph1>, public GraphWrapperBase<_Graph2> { marci@915: public: marci@1002: typedef _Graph1 Graph1; marci@1002: typedef _Graph2 Graph2; marci@1002: typedef GraphWrapperBase<_Graph1> Parent1; marci@1002: typedef GraphWrapperBase<_Graph2> Parent2; marci@1002: typedef typename Parent1::Node Graph1Node; marci@1002: typedef typename Parent2::Node Graph2Node; marci@1002: protected: marci@1002: MergeNodeGraphWrapperBase() { } marci@1002: public: marci@1002: template class NodeMap; marci@915: marci@915: class Node : public Graph1Node, public Graph2Node { marci@1002: friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>; marci@1002: 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@1002: //typedef void Edge; marci@1002: class Edge { }; marci@1002: marci@1002: void first(Node& i) const { marci@1002: Parent1::graph->first(*static_cast(&i)); marci@1002: i.backward=false; marci@1002: if (*static_cast(&i)==INVALID) { marci@1002: Parent2::graph->first(*static_cast(&i)); marci@1002: i.backward=true; marci@1002: } marci@1002: } marci@1002: void next(Node& i) const { marci@1002: if (!(i.backward)) { marci@1002: Parent1::graph->next(*static_cast(&i)); marci@1002: if (*static_cast(&i)==INVALID) { marci@1002: Parent2::graph->first(*static_cast(&i)); marci@1002: i.backward=true; marci@915: } marci@1002: } else { marci@1002: Parent2::graph->next(*static_cast(&i)); marci@915: } marci@1002: } 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@1002: template marci@1002: class NodeMap : public Parent1::template NodeMap<_Value>, marci@1002: public Parent2::template NodeMap<_Value> { marci@1002: typedef typename Parent1::template NodeMap<_Value> ParentMap1; marci@1002: typedef typename Parent2::template NodeMap<_Value> ParentMap2; marci@917: public: marci@1002: typedef _Value Value; marci@1002: typedef Node Key; marci@1002: NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : marci@1002: ParentMap1(gw), ParentMap2(gw) { } marci@1002: NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, marci@1002: const _Value& value) : marci@1002: ParentMap1(gw, value), ParentMap2(gw, value) { } marci@1002: // NodeMap(const NodeMap& copy) marci@1002: // : ParentMap1(copy), marci@1002: // ParentMap2(copy) { } marci@1002: // template marci@1002: // NodeMap(const NodeMap& copy) marci@1002: // : ParentMap1(copy), marci@1002: // ParentMap2(copy) { } marci@1002: // NodeMap& operator=(const NodeMap& copy) { marci@1002: // ParentMap1::operator=(copy); marci@1002: // ParentMap2::operator=(copy); marci@1002: // return *this; marci@1002: // } marci@1002: // template marci@1002: // NodeMap& operator=(const NodeMap& copy) { marci@1002: // ParentMap1::operator=(copy); marci@1002: // ParentMap2::operator=(copy); marci@1002: // return *this; marci@1002: // } marci@1002: _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@1002: 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@1002: marci@1002: }; marci@1002: marci@1002: marci@1002: template marci@1002: class MergeNodeGraphWrapper : public marci@1002: IterableGraphExtender > { marci@1002: public: marci@1002: typedef _Graph1 Graph1; marci@1002: typedef _Graph2 Graph2; marci@1002: typedef IterableGraphExtender< marci@1002: MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent; marci@1002: protected: marci@1002: MergeNodeGraphWrapper() { } marci@1002: public: marci@1002: MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { marci@1002: Parent::Parent1::setGraph(_graph1); marci@1002: Parent::Parent2::setGraph(_graph2); marci@1002: } marci@915: }; marci@915: alpar@921: } //namespace lemon marci@915: alpar@921: #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H