src/work/marci/merge_node_graph_wrapper.h
author klao
Wed, 10 Nov 2004 21:42:28 +0000
changeset 978 175cf8c3a994
parent 917 ffb8f0cbcb57
child 1002 ea3ecb3c9846
permissions -rw-r--r--
"make check" pass under gcc-3.4.3
     1 /* -*- C++ -*-
     2  * src/lemon/merge_node_graph_wrapper.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_MERGE_NODE_GRAPH_WRAPPER_H
    18 #define LEMON_MERGE_NODE_GRAPH_WRAPPER_H
    19 
    20 #include <lemon/invalid.h>
    21 #include <lemon/maps.h>
    22 #include <lemon/map_defines.h>
    23 #include <lemon/graph_wrapper.h>
    24 #include <iostream>
    25 
    26 namespace lemon {
    27 
    28   template <typename Graph1, typename Graph2, typename Enable=void> 
    29   class MergeNodeGraphWrapper : 
    30     public GraphWrapper<Graph1>, public GraphWrapper<Graph2> {
    31     typedef GraphWrapper<Graph1> Parent1;
    32     typedef GraphWrapper<Graph2> Parent2;
    33     typedef typename GraphWrapper<Graph1>::Node Graph1Node;
    34     typedef typename GraphWrapper<Graph2>::Node Graph2Node;
    35   public:
    36     class Node;
    37     class NodeIt;
    38     friend class Node;
    39     friend class NodeIt;
    40     template<typename Value> class NodeMap;
    41 
    42     MergeNodeGraphWrapper(Graph1& _graph1, Graph2& _graph2) : 
    43       Parent1(_graph1), Parent2(_graph2) { }
    44 
    45     class Node : public Graph1Node, public Graph2Node {
    46       friend class MergeNodeGraphWrapper<Graph1, Graph2>;
    47       template<typename Value> friend class NodeMap;
    48     protected:
    49       bool backward; //true, iff backward
    50     public:
    51       Node() { }
    52       /// \todo =false is needed, or causes problems?
    53       /// If \c _backward is false, then we get an edge corresponding to the 
    54       /// original one, otherwise its oppositely directed pair is obtained.
    55       Node(const Graph1Node& n1, 
    56 	   const Graph2Node& n2, bool _backward) : 
    57 	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
    58       Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
    59       bool operator==(const Node& v) const { 
    60 	return (this->backward==v.backward && 
    61 		static_cast<Graph1Node>(*this)==
    62 		static_cast<Graph1Node>(v) && 
    63 		static_cast<Graph2Node>(*this)==
    64 		static_cast<Graph2Node>(v));
    65       } 
    66       bool operator!=(const Node& v) const { 
    67 	return (this->backward!=v.backward || 
    68 		static_cast<Graph1Node>(*this)!=
    69 		static_cast<Graph1Node>(v) || 
    70 		static_cast<Graph2Node>(*this)!=
    71 		static_cast<Graph2Node>(v));
    72       }
    73     };
    74 
    75     class NodeIt : public Node {
    76       friend class MergeNodeGraphWrapper<Graph1, Graph2>;
    77     protected:
    78       const MergeNodeGraphWrapper<Graph1, Graph2>* gw;
    79     public:
    80       NodeIt() { }
    81       NodeIt(Invalid i) : Node(i) { }
    82       NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw) : 
    83 	Node(typename Graph1::NodeIt(*_gw.Parent1::graph), 
    84 	     typename Graph2::Node(),
    85 	     false), gw(&_gw) { 
    86 	if (*static_cast<Graph1Node*>(this)==INVALID) {
    87 // 	  *static_cast<Node*>(this)=
    88 // 	    Node(Graph1Node(INVALID), 
    89 // 		 typename Graph2::NodeIt(*_gw.Parent2::graph), 
    90 // 		 true);
    91 	  *static_cast<Graph2Node*>(this)=
    92 	    typename Graph2::NodeIt(*_gw.Parent2::graph);
    93 	  backward=true;
    94 	}
    95       }
    96       NodeIt(const MergeNodeGraphWrapper<Graph1, Graph2>& _gw, 
    97 	     const Node& n) : 
    98 	Node(n), gw(&_gw) { }
    99       NodeIt& operator++() { 
   100 	if (!this->backward) {
   101 	  *(static_cast<Graph1Node*>(this))=
   102 	    ++(typename Graph1::NodeIt(*gw->Parent1::graph, *this));
   103 	  if (*static_cast<Graph1Node*>(this)==INVALID) {
   104 // 	    *static_cast<Node*>(this)=
   105 // 	      Node(typename Graph1::Node(INVALID), 
   106 // 		   typename Graph2::NodeIt(*gw->Parent2::graph), true);
   107 	    *static_cast<Graph2Node*>(this)=
   108 	      typename Graph2::NodeIt(*gw->Parent2::graph);
   109 	    backward=true;
   110 	  }
   111 	} else {
   112 	  *(static_cast<Graph2Node*>(this))=
   113 	    ++(typename Graph2::NodeIt(*gw->Parent2::graph, *this));
   114 	}
   115 	return *this;
   116       }
   117     };
   118 
   119     int id(const Node& n) const { 
   120       if (!n.backward) 
   121 	return this->Parent1::graph->id(n);
   122       else
   123 	return this->Parent2::graph->id(n);
   124     }
   125 
   126     template <typename Value> 
   127     class NodeMap : public Parent1::template NodeMap<Value>, 
   128 		    public Parent2::template NodeMap<Value> { 
   129       typedef typename Parent1::template NodeMap<Value> ParentMap1;
   130       typedef typename Parent2::template NodeMap<Value> ParentMap2;
   131     public:
   132       NodeMap(const MergeNodeGraphWrapper<Graph1, Graph2>& gw) : 
   133 	ParentMap1(gw), 
   134 	ParentMap2(gw) { }
   135       NodeMap(const MergeNodeGraphWrapper<Graph1, Graph2>& gw, 
   136 	      const Value& value)
   137 	: ParentMap1(gw, value), 
   138 	  ParentMap2(gw, value) { }
   139       NodeMap(const NodeMap& copy)
   140 	: ParentMap1(copy), 
   141 	  ParentMap2(copy) { }
   142       template <typename TT>
   143       NodeMap(const NodeMap<TT>& copy)
   144 	: ParentMap1(copy),
   145 	  ParentMap2(copy) { }
   146       NodeMap& operator=(const NodeMap& copy) {
   147 	ParentMap1::operator=(copy);
   148 	ParentMap2::operator=(copy);
   149 	return *this;
   150       }
   151       template <typename TT>
   152       NodeMap& operator=(const NodeMap<TT>& copy) {
   153 	ParentMap1::operator=(copy);
   154 	ParentMap2::operator=(copy);
   155 	return *this;
   156       }
   157       Value operator[](const Node& n) const {
   158 	if (!n.backward) 
   159 	  return ParentMap1::operator[](n);
   160 	else 
   161 	  return ParentMap2::operator[](n);
   162       }
   163       void set(const Node& n, const Value& value) {
   164 	if (!n.backward) 
   165 	  ParentMap1::set(n, value);
   166 	else 
   167 	  ParentMap2::set(n, value);
   168       }
   169       using ParentMap1::operator[];
   170       using ParentMap2::operator[];
   171     };
   172     
   173   };
   174 
   175 } //namespace lemon
   176 
   177 #endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H