src/work/marci/merge_node_graph_wrapper.h
author alpar
Wed, 17 Nov 2004 22:18:30 +0000
changeset 1005 63ccf7136641
parent 921 818510fa3d99
child 1007 a7d5fe18d8f9
permissions -rw-r--r--
- Timer class got direct access to the components of the ellapsed time/
- Better docs.
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@1002
    28
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1002
    29
  class MergeNodeGraphWrapperBase : 
marci@1002
    30
    public GraphWrapperBase<_Graph1>, public GraphWrapperBase<_Graph2> {
marci@915
    31
  public:
marci@1002
    32
    typedef _Graph1 Graph1;
marci@1002
    33
    typedef _Graph2 Graph2;
marci@1002
    34
    typedef GraphWrapperBase<_Graph1> Parent1;
marci@1002
    35
    typedef GraphWrapperBase<_Graph2> Parent2;
marci@1002
    36
    typedef typename Parent1::Node Graph1Node;
marci@1002
    37
    typedef typename Parent2::Node Graph2Node;
marci@1002
    38
  protected:
marci@1002
    39
    MergeNodeGraphWrapperBase() { }
marci@1002
    40
  public:
marci@1002
    41
    template <typename _Value> class NodeMap;
marci@915
    42
marci@915
    43
    class Node : public Graph1Node, public Graph2Node {
marci@1002
    44
      friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
marci@1002
    45
      template <typename Value> friend class NodeMap;
marci@915
    46
    protected:
marci@915
    47
      bool backward; //true, iff backward
marci@915
    48
    public:
marci@915
    49
      Node() { }
marci@915
    50
      /// \todo =false is needed, or causes problems?
marci@915
    51
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@915
    52
      /// original one, otherwise its oppositely directed pair is obtained.
marci@915
    53
      Node(const Graph1Node& n1, 
marci@915
    54
	   const Graph2Node& n2, bool _backward) : 
marci@915
    55
	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
marci@915
    56
      Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
marci@915
    57
      bool operator==(const Node& v) const { 
marci@915
    58
	return (this->backward==v.backward && 
marci@915
    59
		static_cast<Graph1Node>(*this)==
marci@915
    60
		static_cast<Graph1Node>(v) && 
marci@915
    61
		static_cast<Graph2Node>(*this)==
marci@915
    62
		static_cast<Graph2Node>(v));
marci@915
    63
      } 
marci@915
    64
      bool operator!=(const Node& v) const { 
marci@915
    65
	return (this->backward!=v.backward || 
marci@915
    66
		static_cast<Graph1Node>(*this)!=
marci@915
    67
		static_cast<Graph1Node>(v) || 
marci@915
    68
		static_cast<Graph2Node>(*this)!=
marci@915
    69
		static_cast<Graph2Node>(v));
marci@915
    70
      }
marci@915
    71
    };
marci@915
    72
marci@1002
    73
    //typedef void Edge;
marci@1002
    74
    class Edge { };
marci@1002
    75
    
marci@1002
    76
    void first(Node& i) const {
marci@1002
    77
      Parent1::graph->first(*static_cast<Graph1Node*>(&i));
marci@1002
    78
      i.backward=false;
marci@1002
    79
      if (*static_cast<Graph1Node*>(&i)==INVALID) {
marci@1002
    80
	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
marci@1002
    81
	i.backward=true;
marci@1002
    82
      }
marci@1002
    83
    }
marci@1002
    84
    void next(Node& i) const {
marci@1002
    85
      if (!(i.backward)) {
marci@1002
    86
	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
marci@1002
    87
	if (*static_cast<Graph1Node*>(&i)==INVALID) {
marci@1002
    88
	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
marci@1002
    89
	  i.backward=true;
marci@915
    90
	}
marci@1002
    91
      } else {
marci@1002
    92
	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
marci@915
    93
      }
marci@1002
    94
    }
marci@915
    95
marci@915
    96
    int id(const Node& n) const { 
marci@915
    97
      if (!n.backward) 
marci@915
    98
	return this->Parent1::graph->id(n);
marci@915
    99
      else
marci@915
   100
	return this->Parent2::graph->id(n);
marci@915
   101
    }
marci@915
   102
marci@1002
   103
    template <typename _Value> 
marci@1002
   104
    class NodeMap : public Parent1::template NodeMap<_Value>, 
marci@1002
   105
		    public Parent2::template NodeMap<_Value> { 
marci@1002
   106
      typedef typename Parent1::template NodeMap<_Value> ParentMap1;
marci@1002
   107
      typedef typename Parent2::template NodeMap<_Value> ParentMap2;
marci@917
   108
    public:
marci@1002
   109
      typedef _Value Value;
marci@1002
   110
      typedef Node Key;
marci@1002
   111
      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
marci@1002
   112
	ParentMap1(gw), ParentMap2(gw) { }
marci@1002
   113
      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
marci@1002
   114
	      const _Value& value) : 
marci@1002
   115
	ParentMap1(gw, value), ParentMap2(gw, value) { }
marci@1002
   116
//       NodeMap(const NodeMap& copy)
marci@1002
   117
// 	: ParentMap1(copy), 
marci@1002
   118
// 	  ParentMap2(copy) { }
marci@1002
   119
//       template <typename TT>
marci@1002
   120
//       NodeMap(const NodeMap<TT>& copy)
marci@1002
   121
// 	: ParentMap1(copy),
marci@1002
   122
// 	  ParentMap2(copy) { }
marci@1002
   123
//       NodeMap& operator=(const NodeMap& copy) {
marci@1002
   124
// 	ParentMap1::operator=(copy);
marci@1002
   125
// 	ParentMap2::operator=(copy);
marci@1002
   126
// 	return *this;
marci@1002
   127
//       }
marci@1002
   128
//       template <typename TT>
marci@1002
   129
//       NodeMap& operator=(const NodeMap<TT>& copy) {
marci@1002
   130
// 	ParentMap1::operator=(copy);
marci@1002
   131
// 	ParentMap2::operator=(copy);
marci@1002
   132
// 	return *this;
marci@1002
   133
//       }
marci@1002
   134
      _Value operator[](const Node& n) const {
marci@917
   135
	if (!n.backward) 
marci@917
   136
	  return ParentMap1::operator[](n);
marci@917
   137
	else 
marci@917
   138
	  return ParentMap2::operator[](n);
marci@917
   139
      }
marci@1002
   140
      void set(const Node& n, const _Value& value) {
marci@917
   141
	if (!n.backward) 
marci@917
   142
	  ParentMap1::set(n, value);
marci@917
   143
	else 
marci@917
   144
	  ParentMap2::set(n, value);
marci@917
   145
      }
marci@917
   146
      using ParentMap1::operator[];
marci@917
   147
      using ParentMap2::operator[];
marci@917
   148
    };
marci@1002
   149
marci@1002
   150
  };
marci@1002
   151
marci@1002
   152
marci@1002
   153
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1002
   154
  class MergeNodeGraphWrapper : public 
marci@1002
   155
  IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > {
marci@1002
   156
  public:
marci@1002
   157
    typedef _Graph1 Graph1;
marci@1002
   158
    typedef _Graph2 Graph2;
marci@1002
   159
    typedef IterableGraphExtender<
marci@1002
   160
      MergeNodeGraphWrapperBase<_Graph1, _Graph2, Enable> > Parent;
marci@1002
   161
  protected:
marci@1002
   162
    MergeNodeGraphWrapper() { }
marci@1002
   163
  public:
marci@1002
   164
    MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
marci@1002
   165
      Parent::Parent1::setGraph(_graph1);
marci@1002
   166
      Parent::Parent2::setGraph(_graph2);
marci@1002
   167
    }
marci@915
   168
  };
marci@915
   169
alpar@921
   170
} //namespace lemon
marci@915
   171
alpar@921
   172
#endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H