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