src/work/marci/merge_node_graph_wrapper.h
author alpar
Sat, 08 Jan 2005 20:16:56 +0000
changeset 1062 8226427845bc
parent 1025 3b1ad8bc21da
child 1164 80bb73097736
permissions -rw-r--r--
- Parallel edge support (without arrowheads)
- Texts on the nodes
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@1013
    25
marci@1008
    26
using std::cout;
marci@1008
    27
using std::endl;
marci@915
    28
marci@1007
    29
#include <boost/type_traits.hpp>
marci@1007
    30
#include <boost/utility/enable_if.hpp>
marci@1007
    31
alpar@921
    32
namespace lemon {
marci@915
    33
marci@1007
    34
  template <class _Graph1>
marci@1007
    35
  class P1 : public GraphWrapperBase<_Graph1> {
marci@1007
    36
  };
marci@1007
    37
marci@1007
    38
  template <class _Graph2>
marci@1007
    39
  class P2 : public GraphWrapperBase<_Graph2> {
marci@1007
    40
  };
marci@1007
    41
marci@1013
    42
marci@1002
    43
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1025
    44
  class MergeNodeGraphWrapperBaseBase : 
marci@1007
    45
    public P1<_Graph1>, public P2<_Graph2> {
marci@915
    46
  public:
marci@1013
    47
    static void printNode() { std::cout << "node: generic" << std::endl; }
marci@1002
    48
    typedef _Graph1 Graph1;
marci@1002
    49
    typedef _Graph2 Graph2;
marci@1007
    50
    typedef P1<_Graph1> Parent1;
marci@1007
    51
    typedef P2<_Graph2> Parent2;
marci@1002
    52
    typedef typename Parent1::Node Graph1Node;
marci@1002
    53
    typedef typename Parent2::Node Graph2Node;
marci@1002
    54
  protected:
marci@1025
    55
    MergeNodeGraphWrapperBaseBase() { }
marci@1002
    56
  public:
marci@915
    57
marci@915
    58
    class Node : public Graph1Node, public Graph2Node {
marci@1025
    59
      friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@915
    60
    protected:
marci@915
    61
      bool backward; //true, iff backward
marci@915
    62
    public:
marci@915
    63
      Node() { }
marci@915
    64
      /// \todo =false is needed, or causes problems?
marci@915
    65
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@915
    66
      /// original one, otherwise its oppositely directed pair is obtained.
marci@915
    67
      Node(const Graph1Node& n1, 
marci@915
    68
	   const Graph2Node& n2, bool _backward) : 
marci@915
    69
	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
marci@915
    70
      Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
marci@915
    71
      bool operator==(const Node& v) const { 
marci@1013
    72
	if (backward) 
marci@1013
    73
	  return (v.backward && 
marci@1013
    74
		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
marci@1013
    75
	else 
marci@1013
    76
	  return (!v.backward && 
marci@1013
    77
		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
marci@915
    78
      } 
marci@915
    79
      bool operator!=(const Node& v) const { 
marci@1013
    80
	return !(*this==v);
marci@915
    81
      }
marci@915
    82
    };
marci@915
    83
marci@1025
    84
    static bool forward(const Node& n) { return !n.backward; }
marci@1025
    85
    static bool backward(const Node& n) { return n.backward; }
marci@1025
    86
    static void setForward(Node& n) { n.backward=false; }
marci@1025
    87
    static void setBackward(Node& n) { n.backward=true; }    
marci@1002
    88
  };
marci@1002
    89
marci@1013
    90
marci@1007
    91
  template <typename _Graph1, typename _Graph2>
marci@1025
    92
  class MergeNodeGraphWrapperBaseBase<
marci@1007
    93
    _Graph1, _Graph2, typename boost::enable_if<
marci@1007
    94
    boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
marci@1007
    95
    public P1<_Graph1>, public P2<_Graph2> {
marci@1013
    96
  public:
marci@1013
    97
    static void printNode() { std::cout << "node: same" << std::endl; }
marci@1007
    98
    typedef _Graph1 Graph1;
marci@1007
    99
    typedef _Graph2 Graph2;
marci@1007
   100
    typedef P1<_Graph1> Parent1;
marci@1007
   101
    typedef P2<_Graph2> Parent2;
marci@1007
   102
    typedef typename Parent1::Node Graph1Node;
marci@1007
   103
    typedef typename Parent2::Node Graph2Node;
marci@1007
   104
  protected:
marci@1025
   105
    MergeNodeGraphWrapperBaseBase() { }
marci@1007
   106
  public:
marci@1013
   107
marci@1013
   108
    class Node : public Graph1Node {
marci@1025
   109
      friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1013
   110
    protected:
marci@1013
   111
      bool backward; //true, iff backward
marci@1013
   112
    public:
marci@1013
   113
      Node() { }
marci@1013
   114
      /// \todo =false is needed, or causes problems?
marci@1013
   115
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1013
   116
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1013
   117
      Node(const Graph1Node& n1, 
marci@1013
   118
	   const Graph2Node& n2, bool _backward) : 
marci@1025
   119
	Graph1Node(!_backward ? n1 : n2), backward(_backward) { }
marci@1013
   120
      Node(Invalid i) : Graph1Node(i), backward(true) { }
marci@1013
   121
      bool operator==(const Node& v) const { 
marci@1013
   122
	return (backward==v.backward && 
marci@1013
   123
		static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v));
marci@1013
   124
      } 
marci@1013
   125
      bool operator!=(const Node& v) const { 
marci@1013
   126
	return !(*this==v);
marci@1013
   127
      }
marci@1013
   128
    };
marci@1013
   129
marci@1025
   130
    static bool forward(const Node& n) { return !n.backward; }
marci@1025
   131
    static bool backward(const Node& n) { return n.backward; }
marci@1025
   132
    static void setForward(Node& n) { n.backward=false; }
marci@1025
   133
    static void setBackward(Node& n) { n.backward=true; }
marci@1007
   134
  };
marci@1007
   135
marci@1013
   136
marci@1007
   137
  template <typename _Graph1, typename _Graph2>
marci@1025
   138
  class MergeNodeGraphWrapperBaseBase<
marci@1007
   139
    _Graph1, _Graph2, typename boost::enable_if<
marci@1007
   140
    boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
marci@1007
   141
    public P1<_Graph1>, public P2<_Graph2> {
marci@1007
   142
  public :
marci@1013
   143
    static void printNode() { std::cout << "node: 2nd is derived" << std::endl; }
marci@1007
   144
    typedef _Graph1 Graph1;
marci@1007
   145
    typedef _Graph2 Graph2;
marci@1007
   146
    typedef P1<_Graph1> Parent1;
marci@1007
   147
    typedef P2<_Graph2> Parent2;
marci@1007
   148
    typedef typename Parent1::Node Graph1Node;
marci@1007
   149
    typedef typename Parent2::Node Graph2Node;
marci@1007
   150
  protected:
marci@1025
   151
    MergeNodeGraphWrapperBaseBase() { }
marci@1007
   152
  public:
marci@1016
   153
marci@1016
   154
    class Node : public Graph2Node {
marci@1025
   155
      friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1016
   156
    protected:
marci@1016
   157
      bool backward; //true, iff backward
marci@1016
   158
    public:
marci@1016
   159
      Node() { }
marci@1016
   160
      /// \todo =false is needed, or causes problems?
marci@1016
   161
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1016
   162
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1016
   163
      Node(const Graph1Node& n1, 
marci@1016
   164
	   const Graph2Node& n2, bool _backward) : 
marci@1016
   165
	Graph2Node(n2), backward(_backward) { 
marci@1016
   166
	if (!backward) *this=n1;
marci@1016
   167
      }
marci@1016
   168
      Node(Invalid i) : Graph2Node(i), backward(true) { }
marci@1016
   169
      bool operator==(const Node& v) const { 
marci@1016
   170
	if (backward) 
marci@1016
   171
	  return (v.backward && 
marci@1016
   172
		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
marci@1016
   173
	else 
marci@1016
   174
	  return (!v.backward && 
marci@1016
   175
		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
marci@1016
   176
      } 
marci@1016
   177
      bool operator!=(const Node& v) const { 
marci@1016
   178
	return !(*this==v);
marci@1016
   179
      }
marci@1016
   180
    };
marci@1016
   181
marci@1025
   182
    static bool forward(const Node& n) { return !n.backward; }
marci@1025
   183
    static bool backward(const Node& n) { return n.backward; }
marci@1025
   184
    static void setForward(Node& n) { n.backward=false; }
marci@1025
   185
    static void setBackward(Node& n) { n.backward=true; }
marci@1025
   186
  };
marci@1025
   187
  
marci@1016
   188
marci@1007
   189
  template <typename _Graph1, typename _Graph2>
marci@1025
   190
  class MergeNodeGraphWrapperBaseBase<
marci@1007
   191
    _Graph1, _Graph2, typename boost::enable_if<
marci@1007
   192
    boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
marci@1007
   193
    public P1<_Graph1>, public P2<_Graph2> {
marci@1007
   194
  public :
marci@1013
   195
    static void printNode() { std::cout << "node: 1st is derived" << std::endl; }
marci@1007
   196
    typedef _Graph1 Graph1;
marci@1007
   197
    typedef _Graph2 Graph2;
marci@1007
   198
    typedef P1<_Graph1> Parent1;
marci@1007
   199
    typedef P2<_Graph2> Parent2;
marci@1007
   200
    typedef typename Parent1::Node Graph1Node;
marci@1007
   201
    typedef typename Parent2::Node Graph2Node;
marci@1007
   202
  protected:
marci@1025
   203
    MergeNodeGraphWrapperBaseBase() { }
marci@1007
   204
  public:
marci@1016
   205
marci@1016
   206
    class Node : public Graph1Node {
marci@1025
   207
      friend class MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1016
   208
    protected:
marci@1016
   209
      bool backward; //true, iff backward
marci@1016
   210
    public:
marci@1016
   211
      Node() { }
marci@1016
   212
      /// \todo =false is needed, or causes problems?
marci@1016
   213
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1016
   214
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1016
   215
      Node(const Graph1Node& n1, 
marci@1016
   216
	   const Graph2Node& n2, bool _backward) : 
marci@1016
   217
	Graph1Node(n1), backward(_backward) { 
marci@1016
   218
	if (backward) *this=n2;
marci@1016
   219
      }
marci@1016
   220
      Node(Invalid i) : Graph1Node(i), backward(true) { }
marci@1016
   221
      bool operator==(const Node& v) const { 
marci@1016
   222
	if (backward) 
marci@1016
   223
	  return (v.backward && 
marci@1016
   224
		  static_cast<Graph2Node>(*this)==static_cast<Graph2Node>(v)); 
marci@1016
   225
	else 
marci@1016
   226
	  return (!v.backward && 
marci@1016
   227
		  static_cast<Graph1Node>(*this)==static_cast<Graph1Node>(v)); 
marci@1016
   228
      } 
marci@1016
   229
      bool operator!=(const Node& v) const { 
marci@1016
   230
	return !(*this==v);
marci@1016
   231
      }
marci@1016
   232
    };
marci@1016
   233
marci@1025
   234
    static bool forward(const Node& n) { return !n.backward; }
marci@1025
   235
    static bool backward(const Node& n) { return n.backward; }
marci@1025
   236
    static void setForward(Node& n) { n.backward=false; }
marci@1025
   237
    static void setBackward(Node& n) { n.backward=true; }
marci@1025
   238
  };
marci@1025
   239
marci@1025
   240
marci@1025
   241
  template <typename _Graph1, typename _Graph2>
marci@1025
   242
  class MergeNodeGraphWrapperBase : 
marci@1025
   243
    public MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> {
marci@1025
   244
  public:
marci@1025
   245
    typedef MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
marci@1025
   246
    typedef _Graph1 Graph1;
marci@1025
   247
    typedef _Graph2 Graph2;
marci@1025
   248
    typedef P1<_Graph1> Parent1;
marci@1025
   249
    typedef P2<_Graph2> Parent2;
marci@1025
   250
    typedef typename Parent1::Node Graph1Node;
marci@1025
   251
    typedef typename Parent2::Node Graph2Node;
marci@1025
   252
marci@1025
   253
    typedef typename Parent::Node Node; 
marci@1007
   254
    class Edge { };
marci@1016
   255
    
marci@1016
   256
    void first(Node& i) const {
marci@1016
   257
      Parent1::graph->first(*static_cast<Graph1Node*>(&i));
marci@1025
   258
      this->setForward(i);
marci@1016
   259
      if (*static_cast<Graph1Node*>(&i)==INVALID) {
marci@1016
   260
	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
marci@1025
   261
	this->setBackward(i);
marci@1016
   262
      }
marci@1016
   263
    }
marci@1016
   264
    void next(Node& i) const {
marci@1025
   265
      if (this->forward(i)) {
marci@1016
   266
	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
marci@1016
   267
	if (*static_cast<Graph1Node*>(&i)==INVALID) {
marci@1016
   268
	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
marci@1025
   269
	  this->setBackward(i);
marci@1016
   270
	}
marci@1016
   271
      } else {
marci@1016
   272
	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
marci@1016
   273
      }
marci@1016
   274
    }
marci@1016
   275
marci@1016
   276
    int id(const Node& n) const { 
marci@1025
   277
      if (this->forward(n)) 
marci@1016
   278
	return this->Parent1::graph->id(n);
marci@1016
   279
      else
marci@1016
   280
	return this->Parent2::graph->id(n);
marci@1016
   281
    }
marci@1016
   282
marci@1016
   283
    template <typename _Value> 
marci@1016
   284
    class NodeMap { 
marci@1016
   285
    protected:
marci@1016
   286
      typedef typename _Graph1::template NodeMap<_Value> ParentMap1;
marci@1016
   287
      typedef typename _Graph2::template NodeMap<_Value> ParentMap2;
marci@1016
   288
      ParentMap1 forward_map;
marci@1016
   289
      ParentMap2 backward_map;
marci@1016
   290
    public:
marci@1016
   291
      typedef _Value Value;
marci@1016
   292
      typedef Node Key;
marci@1016
   293
      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
marci@1016
   294
	forward_map(*(gw.Parent1::graph)), 
marci@1016
   295
	backward_map(*(gw.Parent2::graph)) { }
marci@1016
   296
      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
marci@1016
   297
	      const _Value& value) : 
marci@1016
   298
	forward_map(*(gw.Parent1::graph), value), 
marci@1016
   299
	backward_map(*(gw.Parent2::graph), value) { }
marci@1016
   300
      _Value operator[](const Node& n) const {
marci@1025
   301
	if (Parent::forward(n)) 
marci@1016
   302
	  return forward_map[n];
marci@1016
   303
	else 
marci@1016
   304
	  return backward_map[n];
marci@1016
   305
      }
marci@1016
   306
      void set(const Node& n, const _Value& value) {
marci@1025
   307
	if (Parent::forward(n)) 
marci@1016
   308
	  forward_map.set(n, value);
marci@1016
   309
	else 
marci@1016
   310
	  backward_map.set(n, value);
marci@1016
   311
      }
marci@1016
   312
//       using ParentMap1::operator[];
marci@1016
   313
//       using ParentMap2::operator[];
marci@1016
   314
    };
marci@1016
   315
marci@1007
   316
  };
marci@1007
   317
marci@1002
   318
marci@1013
   319
  /*! A graph wrapper class 
marci@1025
   320
    for merging the node-set of two node-disjoint graphs 
marci@1025
   321
    into the node-set of one graph. 
marci@1025
   322
    Different implementations are according to the relation of 
marci@1025
   323
    _Graph1::Node and _Graph2::Node. 
marci@1025
   324
    If _Graph1::Node and _Graph2::Node are unrelated, then 
marci@1025
   325
    MergeNodeGraphWrapper<_Graph1, _Graph2>::Node 
marci@1025
   326
    is derived from both. 
marci@1025
   327
    If _Graph1::Node and _Graph2::Node are the same type, then 
marci@1025
   328
    MergeNodeGraphWrapper<_Graph1, _Graph2>::Node 
marci@1025
   329
    is derived from _Graph1::Node. 
marci@1025
   330
    If one of _Graph1::Node and _Graph2::Node 
marci@1025
   331
    is derived from the other one, then 
marci@1025
   332
    MergeNodeGraphWrapper<_Graph1, _Graph2>::Node 
marci@1025
   333
    is derived from the derived type.
marci@1025
   334
    It does not satisfy 
marci@1013
   335
    StaticGraph concept as it has no edge-set which 
marci@1013
   336
    works together with the node-set.
marci@1025
   337
  */
marci@1009
   338
  template <typename _Graph1, typename _Graph2>
marci@1002
   339
  class MergeNodeGraphWrapper : public 
marci@1009
   340
  IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
marci@1002
   341
  public:
marci@1002
   342
    typedef _Graph1 Graph1;
marci@1002
   343
    typedef _Graph2 Graph2;
marci@1002
   344
    typedef IterableGraphExtender<
marci@1009
   345
      MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
marci@1002
   346
  protected:
marci@1002
   347
    MergeNodeGraphWrapper() { }
marci@1002
   348
  public:
marci@1002
   349
    MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
marci@1002
   350
      Parent::Parent1::setGraph(_graph1);
marci@1002
   351
      Parent::Parent2::setGraph(_graph2);
marci@1002
   352
    }
marci@915
   353
  };
marci@915
   354
marci@1009
   355
marci@1013
   356
  /*! A grah wrapper base class 
marci@1013
   357
    for merging the node-sets and edge-sets of 
marci@1009
   358
    two node-disjoint graphs 
marci@1009
   359
    into one graph.
marci@1013
   360
    Generic implementation for unrelated _Graph1::Edge and _Graph2::Edge.
marci@1009
   361
   */
marci@1009
   362
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1026
   363
  class MergeEdgeGraphWrapperBaseBase : 
marci@1009
   364
    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
marci@1009
   365
  public:
marci@1013
   366
    static void printEdge() { std::cout << "edge: generic" << std::endl; }
marci@1009
   367
    typedef _Graph1 Graph1;
marci@1009
   368
    typedef _Graph2 Graph2;
marci@1009
   369
    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
marci@1009
   370
    typedef typename Parent::Parent1 Parent1;
marci@1009
   371
    typedef typename Parent::Parent2 Parent2;
marci@1009
   372
//     typedef P1<_Graph1> Parent1;
marci@1009
   373
//     typedef P2<_Graph2> Parent2;
marci@1009
   374
    typedef typename Parent1::Edge Graph1Edge;
marci@1009
   375
    typedef typename Parent2::Edge Graph2Edge;
marci@1009
   376
  protected:
marci@1026
   377
    MergeEdgeGraphWrapperBaseBase() { }
marci@1009
   378
  public:
marci@1009
   379
marci@1009
   380
    class Edge : public Graph1Edge, public Graph2Edge {
marci@1026
   381
      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1009
   382
    protected:
marci@1009
   383
      bool backward; //true, iff backward
marci@1009
   384
    public:
marci@1009
   385
      Edge() { }
marci@1009
   386
      /// \todo =false is needed, or causes problems?
marci@1009
   387
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1009
   388
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1009
   389
      Edge(const Graph1Edge& n1, 
marci@1009
   390
	   const Graph2Edge& n2, bool _backward) : 
marci@1009
   391
	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
marci@1009
   392
      Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
marci@1009
   393
      bool operator==(const Edge& v) const { 
marci@1013
   394
	if (backward) 
marci@1013
   395
	  return (v.backward && 
marci@1013
   396
		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
marci@1013
   397
	else 
marci@1013
   398
	  return (!v.backward && 
marci@1013
   399
		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
marci@1009
   400
      } 
marci@1009
   401
      bool operator!=(const Edge& v) const { 
marci@1013
   402
	return !(*this==v);
marci@1009
   403
      }
marci@1009
   404
    };
marci@1009
   405
marci@1025
   406
    using Parent::forward;
marci@1025
   407
    using Parent::backward;
marci@1026
   408
    using Parent::setForward;
marci@1026
   409
    using Parent::setBackward;
marci@1026
   410
    static bool forward(const Edge& e) { return !e.backward; }
marci@1026
   411
    static bool backward(const Edge& e) { return e.backward; }
marci@1026
   412
    static void setForward(Edge& e) { e.backward=false; }
marci@1026
   413
    static void setBackward(Edge& e) { e.backward=true; }
marci@1026
   414
  };
marci@1025
   415
marci@1009
   416
marci@1009
   417
marci@1013
   418
  /*! A graph wrapper base class 
marci@1013
   419
    for merging the node-sets and edge-sets of 
marci@1013
   420
    two node-disjoint graphs 
marci@1013
   421
    into one graph.
marci@1013
   422
    Specialization for the case when _Graph1::Edge and _Graph2::Edge
marci@1013
   423
    are the same.
marci@1013
   424
   */
marci@1013
   425
  template <typename _Graph1, typename _Graph2>
marci@1026
   426
  class MergeEdgeGraphWrapperBaseBase<
marci@1013
   427
    _Graph1, _Graph2, typename boost::enable_if<
marci@1016
   428
    boost::is_same<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
marci@1013
   429
    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
marci@1013
   430
  public:
marci@1013
   431
    static void printEdge() { std::cout << "edge: same" << std::endl; }
marci@1013
   432
    typedef _Graph1 Graph1;
marci@1013
   433
    typedef _Graph2 Graph2;
marci@1013
   434
    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
marci@1013
   435
    typedef typename Parent::Parent1 Parent1;
marci@1013
   436
    typedef typename Parent::Parent2 Parent2;
marci@1013
   437
//     typedef P1<_Graph1> Parent1;
marci@1013
   438
//     typedef P2<_Graph2> Parent2;
marci@1013
   439
    typedef typename Parent1::Edge Graph1Edge;
marci@1013
   440
    typedef typename Parent2::Edge Graph2Edge;
marci@1013
   441
  protected:
marci@1026
   442
    MergeEdgeGraphWrapperBaseBase() { }
marci@1013
   443
  public:
marci@1013
   444
marci@1013
   445
    class Edge : public Graph1Edge {
marci@1026
   446
      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1013
   447
    protected:
marci@1013
   448
      bool backward; //true, iff backward
marci@1013
   449
    public:
marci@1013
   450
      Edge() { }
marci@1013
   451
      /// \todo =false is needed, or causes problems?
marci@1013
   452
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1013
   453
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1013
   454
      Edge(const Graph1Edge& n1, 
marci@1013
   455
	   const Graph2Edge& n2, bool _backward) : 
marci@1025
   456
	Graph1Edge(!_backward ? n1 : n2), backward(_backward) { }
marci@1013
   457
      Edge(Invalid i) : Graph1Edge(i), backward(true) { }
marci@1013
   458
      bool operator==(const Edge& v) const { 
marci@1013
   459
	return (backward==v.backward && 
marci@1013
   460
		static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
marci@1013
   461
      }
marci@1013
   462
      bool operator!=(const Edge& v) const { 
marci@1013
   463
	return !(*this==v);
marci@1013
   464
      }
marci@1013
   465
    };
marci@1013
   466
marci@1025
   467
    using Parent::forward;
marci@1025
   468
    using Parent::backward;
marci@1026
   469
    using Parent::setForward;
marci@1026
   470
    using Parent::setBackward;
marci@1026
   471
    static bool forward(const Edge& e) { return !e.backward; }
marci@1026
   472
    static bool backward(const Edge& e) { return e.backward; }
marci@1026
   473
    static void setForward(Edge& e) { e.backward=false; }
marci@1026
   474
    static void setBackward(Edge& e) { e.backward=true; }
marci@1013
   475
  };
marci@1013
   476
marci@1013
   477
marci@1016
   478
  /*! A grah wrapper base class 
marci@1016
   479
    for merging the node-sets and edge-sets of 
marci@1016
   480
    two node-disjoint graphs 
marci@1016
   481
    into one graph. 
marci@1016
   482
    Specialized implementation for the case 
marci@1016
   483
    when _Graph1::Edge is a base class and _Graph2::Edge
marci@1016
   484
    is derived from it.
marci@1016
   485
   */
marci@1016
   486
  template <typename _Graph1, typename _Graph2>
marci@1026
   487
  class MergeEdgeGraphWrapperBaseBase<
marci@1016
   488
    _Graph1, _Graph2, typename boost::enable_if<
marci@1016
   489
    boost::is_base_and_derived<typename _Graph1::Edge, typename _Graph2::Edge> >::type> : 
marci@1016
   490
    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
marci@1016
   491
  public:
marci@1016
   492
    static void printEdge() { std::cout << "edge: 2nd is derived" << std::endl; }
marci@1016
   493
    typedef _Graph1 Graph1;
marci@1016
   494
    typedef _Graph2 Graph2;
marci@1016
   495
    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
marci@1016
   496
    typedef typename Parent::Parent1 Parent1;
marci@1016
   497
    typedef typename Parent::Parent2 Parent2;
marci@1016
   498
//     typedef P1<_Graph1> Parent1;
marci@1016
   499
//     typedef P2<_Graph2> Parent2;
marci@1016
   500
    typedef typename Parent1::Edge Graph1Edge;
marci@1016
   501
    typedef typename Parent2::Edge Graph2Edge;
marci@1016
   502
  protected:
marci@1026
   503
    MergeEdgeGraphWrapperBaseBase() { }
marci@1016
   504
  public:
marci@1016
   505
marci@1016
   506
    class Edge : public Graph2Edge {
marci@1026
   507
      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1016
   508
    protected:
marci@1016
   509
      bool backward; //true, iff backward
marci@1016
   510
    public:
marci@1016
   511
      Edge() { }
marci@1016
   512
      /// \todo =false is needed, or causes problems?
marci@1016
   513
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1016
   514
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1016
   515
      Edge(const Graph1Edge& n1, 
marci@1016
   516
	   const Graph2Edge& n2, bool _backward) : 
marci@1016
   517
	Graph2Edge(n2), backward(_backward) { 
marci@1016
   518
	if (!backward) *this=n1;
marci@1016
   519
      }
marci@1016
   520
      Edge(Invalid i) : Graph2Edge(i), backward(true) { }
marci@1016
   521
      bool operator==(const Edge& v) const { 
marci@1016
   522
	if (backward) 
marci@1016
   523
	  return (v.backward && 
marci@1016
   524
		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
marci@1016
   525
	else 
marci@1016
   526
	  return (!v.backward && 
marci@1016
   527
		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
marci@1016
   528
      } 
marci@1016
   529
      bool operator!=(const Edge& v) const { 
marci@1016
   530
	return !(*this==v);
marci@1016
   531
      }
marci@1016
   532
    };
marci@1016
   533
marci@1025
   534
    using Parent::forward;
marci@1025
   535
    using Parent::backward;
marci@1026
   536
    using Parent::setForward;
marci@1026
   537
    using Parent::setBackward;
marci@1026
   538
    static bool forward(const Edge& e) { return !e.backward; }
marci@1026
   539
    static bool backward(const Edge& e) { return e.backward; }
marci@1026
   540
    static void setForward(Edge& e) { e.backward=false; }
marci@1026
   541
    static void setBackward(Edge& e) { e.backward=true; }
marci@1016
   542
  };
marci@1016
   543
marci@1016
   544
marci@1016
   545
  /*! A grah wrapper base class 
marci@1016
   546
    for merging the node-sets and edge-sets of 
marci@1016
   547
    two node-disjoint graphs 
marci@1016
   548
    into one graph. 
marci@1016
   549
    Specialized implementation for the case 
marci@1016
   550
    when _Graph1::Edge is derived from _Graph2::Edge.
marci@1016
   551
   */
marci@1016
   552
  template <typename _Graph1, typename _Graph2>
marci@1026
   553
  class MergeEdgeGraphWrapperBaseBase<
marci@1016
   554
    _Graph1, _Graph2, typename boost::enable_if<
marci@1016
   555
    boost::is_base_and_derived<typename _Graph2::Edge, typename _Graph1::Edge> >::type> : 
marci@1016
   556
    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
marci@1016
   557
  public:
marci@1016
   558
    static void printEdge() { std::cout << "edge: 1st is derived" << std::endl; }
marci@1016
   559
    typedef _Graph1 Graph1;
marci@1016
   560
    typedef _Graph2 Graph2;
marci@1026
   561
    typedef MergeNodeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
marci@1016
   562
    typedef typename Parent::Parent1 Parent1;
marci@1016
   563
    typedef typename Parent::Parent2 Parent2;
marci@1016
   564
//     typedef P1<_Graph1> Parent1;
marci@1016
   565
//     typedef P2<_Graph2> Parent2;
marci@1016
   566
    typedef typename Parent1::Edge Graph1Edge;
marci@1016
   567
    typedef typename Parent2::Edge Graph2Edge;
marci@1016
   568
  protected:
marci@1026
   569
    MergeEdgeGraphWrapperBaseBase() { }
marci@1016
   570
  public:
marci@1016
   571
marci@1016
   572
    class Edge : public Graph1Edge {
marci@1026
   573
      friend class MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2>;
marci@1016
   574
    protected:
marci@1016
   575
      bool backward; //true, iff backward
marci@1016
   576
    public:
marci@1016
   577
      Edge() { }
marci@1016
   578
      /// \todo =false is needed, or causes problems?
marci@1016
   579
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1016
   580
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1016
   581
      Edge(const Graph1Edge& n1, 
marci@1016
   582
	   const Graph2Edge& n2, bool _backward) : 
marci@1016
   583
	Graph1Edge(n1), backward(_backward) { 
marci@1016
   584
	if (backward) *this=n2;
marci@1016
   585
      }
marci@1016
   586
      Edge(Invalid i) : Graph1Edge(i), backward(true) { }
marci@1016
   587
      bool operator==(const Edge& v) const { 
marci@1016
   588
	if (backward) 
marci@1016
   589
	  return (v.backward && 
marci@1016
   590
		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
marci@1016
   591
	else 
marci@1016
   592
	  return (!v.backward && 
marci@1016
   593
		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
marci@1016
   594
      } 
marci@1016
   595
      bool operator!=(const Edge& v) const { 
marci@1016
   596
	return !(*this==v);
marci@1016
   597
      }
marci@1016
   598
    };
marci@1016
   599
marci@1025
   600
    using Parent::forward;
marci@1025
   601
    using Parent::backward;
marci@1026
   602
    using Parent::setForward;
marci@1026
   603
    using Parent::setBackward;
marci@1026
   604
    static bool forward(const Edge& e) { return !e.backward; }
marci@1026
   605
    static bool backward(const Edge& e) { return e.backward; }
marci@1026
   606
    static void setForward(Edge& e) { e.backward=false; }
marci@1026
   607
    static void setBackward(Edge& e) { e.backward=true; }
marci@1026
   608
  };
marci@1026
   609
marci@1026
   610
marci@1026
   611
  template <typename _Graph1, typename _Graph2>
marci@1026
   612
  class MergeEdgeGraphWrapperBase : 
marci@1026
   613
    public MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2> {
marci@1026
   614
  public:
marci@1026
   615
    typedef MergeEdgeGraphWrapperBaseBase<_Graph1, _Graph2> Parent;
marci@1026
   616
    typedef _Graph1 Graph1;
marci@1026
   617
    typedef _Graph2 Graph2;
marci@1026
   618
    typedef typename Parent::Parent1 Parent1;
marci@1026
   619
    typedef typename Parent::Parent2 Parent2;
marci@1026
   620
    typedef typename Parent1::Node Graph1Node;
marci@1026
   621
    typedef typename Parent2::Node Graph2Node;
marci@1026
   622
    typedef typename Parent1::Edge Graph1Edge;
marci@1026
   623
    typedef typename Parent2::Edge Graph2Edge;
marci@1026
   624
marci@1026
   625
    typedef typename Parent::Node Node;
marci@1026
   626
    typedef typename Parent::Edge Edge;
marci@1025
   627
marci@1016
   628
    using Parent::first;
marci@1016
   629
    void first(Edge& i) const {
marci@1016
   630
      Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
marci@1026
   631
      this->setForward(i);
marci@1016
   632
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1016
   633
	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
marci@1026
   634
	this->setBackward(i);
marci@1016
   635
      }
marci@1016
   636
    }
marci@1016
   637
    void firstIn(Edge& i, const Node& n) const {
marci@1026
   638
      if (forward(n)) {
marci@1025
   639
	Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
marci@1025
   640
	if (*static_cast<Graph1Edge*>(&i)==INVALID) 
marci@1025
   641
	  i=INVALID;
marci@1025
   642
	else
marci@1026
   643
	  this->setForward(i);
marci@1025
   644
      } else {
marci@1016
   645
	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
marci@1026
   646
	this->setBackward(i);
marci@1016
   647
      }
marci@1016
   648
    }
marci@1016
   649
    void firstOut(Edge& i, const Node& n) const {
marci@1026
   650
      if (forward(n)) {
marci@1025
   651
	Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
marci@1025
   652
	if (*static_cast<Graph1Edge*>(&i)==INVALID) 
marci@1025
   653
	  i=INVALID;
marci@1026
   654
	else
marci@1026
   655
	  this->setForward(i);
marci@1025
   656
      } else {
marci@1016
   657
	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
marci@1026
   658
	this->setBackward(i);
marci@1016
   659
      }
marci@1016
   660
    }
marci@1016
   661
marci@1016
   662
    using Parent::next;
marci@1016
   663
    void next(Edge& i) const {
marci@1026
   664
      if (forward(i)) {
marci@1016
   665
	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
marci@1016
   666
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1016
   667
	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
marci@1026
   668
	  this->setBackward(i);
marci@1016
   669
	}
marci@1016
   670
      } else {
marci@1016
   671
	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
marci@1016
   672
      }
marci@1016
   673
    }
marci@1016
   674
    void nextIn(Edge& i) const {
marci@1026
   675
      if (forward(i)) {
marci@1016
   676
	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
marci@1025
   677
 	if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
marci@1016
   678
      } else {
marci@1016
   679
	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
marci@1016
   680
      }
marci@1016
   681
    }
marci@1016
   682
    void nextOut(Edge& i) const {
marci@1026
   683
      if (Parent::forward(i)) {
marci@1016
   684
	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
marci@1025
   685
 	if (*static_cast<Graph1Edge*>(&i)==INVALID) i=INVALID;
marci@1016
   686
      } else {
marci@1016
   687
	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
marci@1016
   688
      }
marci@1016
   689
    }
marci@1016
   690
marci@1016
   691
    Node source(const Edge& i) const {
marci@1026
   692
      if (forward(i)) {
marci@1016
   693
	return 
marci@1016
   694
	  Node(Parent1::graph->source(i), INVALID, false);
marci@1016
   695
      } else {
marci@1016
   696
	return 
marci@1016
   697
	  Node(INVALID, Parent2::graph->source(i), true);
marci@1016
   698
      }
marci@1016
   699
    }
marci@1016
   700
marci@1016
   701
    Node target(const Edge& i) const {
marci@1026
   702
      if (forward(i)) {
marci@1016
   703
	return 
marci@1016
   704
	  Node(Parent1::graph->target(i), INVALID, false);
marci@1016
   705
      } else {
marci@1016
   706
	return 
marci@1016
   707
	  Node(INVALID, Parent2::graph->target(i), true);
marci@1016
   708
      }
marci@1016
   709
    }
marci@1016
   710
marci@1016
   711
    using Parent::id;
marci@1016
   712
    int id(const Edge& n) const { 
marci@1026
   713
      if (forward(n)) 
marci@1016
   714
	return this->Parent1::graph->id(n);
marci@1016
   715
      else
marci@1016
   716
	return this->Parent2::graph->id(n);
marci@1016
   717
    }
marci@1016
   718
marci@1016
   719
    template <typename _Value> 
marci@1016
   720
    class EdgeMap { 
marci@1016
   721
    protected:
marci@1016
   722
      typedef typename Parent::Graph1::template EdgeMap<_Value> ParentMap1;
marci@1016
   723
      typedef typename Parent::Graph2::template EdgeMap<_Value> ParentMap2;
marci@1016
   724
      ParentMap1 forward_map;
marci@1016
   725
      ParentMap2 backward_map;
marci@1016
   726
    public:
marci@1016
   727
      typedef _Value Value;
marci@1016
   728
      typedef Edge Key;
marci@1016
   729
      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
marci@1016
   730
	forward_map(*(gw.Parent1::graph)), 
marci@1016
   731
	backward_map(*(gw.Parent2::graph)) { }
marci@1016
   732
      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
marci@1016
   733
	      const _Value& value) : 
marci@1016
   734
	forward_map(*(gw.Parent1::graph), value), 
marci@1016
   735
	backward_map(*(gw.Parent2::graph), value) { }
marci@1016
   736
      _Value operator[](const Edge& n) const {
marci@1026
   737
	if (Parent::forward(n)) 
marci@1016
   738
	  return forward_map[n];
marci@1016
   739
	else 
marci@1016
   740
	  return backward_map[n];
marci@1016
   741
      }
marci@1016
   742
      void set(const Edge& n, const _Value& value) {
marci@1026
   743
	if (Parent::forward(n)) 
marci@1016
   744
	  forward_map.set(n, value);
marci@1016
   745
	else 
marci@1016
   746
	  backward_map.set(n, value);
marci@1016
   747
      }
marci@1016
   748
//       using ParentMap1::operator[];
marci@1016
   749
//       using ParentMap2::operator[];
marci@1016
   750
    };
marci@1016
   751
marci@1016
   752
  };
marci@1016
   753
marci@1016
   754
marci@1026
   755
marci@1013
   756
  /*! A graph wrapper class 
marci@1026
   757
    for merging two node-disjoint graphs 
marci@1026
   758
    into one graph. 
marci@1026
   759
    Different implementations are according to the relation of 
marci@1026
   760
    _Graph1::Edge and _Graph2::Edge. 
marci@1026
   761
    If _Graph1::Edge and _Graph2::Edge are unrelated, then 
marci@1026
   762
    MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge 
marci@1026
   763
    is derived from both. 
marci@1026
   764
    If _Graph1::Edge and _Graph2::Edge are the same type, then 
marci@1026
   765
    MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge 
marci@1026
   766
    is derived from _Graph1::Edge. 
marci@1026
   767
    If one of _Graph1::Edge and _Graph2::Edge 
marci@1026
   768
    is derived from the other one, then 
marci@1026
   769
    MergeEdgeGraphWrapper<_Graph1, _Graph2>::Edge 
marci@1026
   770
    is derived from the derived type.
marci@1026
   771
    It does not satisfy 
marci@1026
   772
  */
marci@1009
   773
  template <typename _Graph1, typename _Graph2>
marci@1009
   774
  class MergeEdgeGraphWrapper : public 
marci@1009
   775
  IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
marci@1009
   776
  public:
marci@1009
   777
    typedef _Graph1 Graph1;
marci@1009
   778
    typedef _Graph2 Graph2;
marci@1009
   779
    typedef IterableGraphExtender<
marci@1009
   780
      MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
marci@1009
   781
  protected:
marci@1009
   782
    MergeEdgeGraphWrapper() { }
marci@1009
   783
  public:
marci@1009
   784
    MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
marci@1009
   785
      Parent::Parent1::setGraph(_graph1);
marci@1009
   786
      Parent::Parent2::setGraph(_graph2);
marci@1009
   787
    }
marci@1009
   788
  };
marci@1009
   789
marci@1008
   790
  
marci@1013
   791
  /*! A graph wrapper base class for the following functionality.
marci@1013
   792
    If a bijection is given between the node-sets of two graphs, 
marci@1013
   793
    then the second one can be considered as a new edge-set 
marci@1013
   794
    over th first node-set. 
marci@1013
   795
   */
marci@1008
   796
  template <typename _Graph, typename _EdgeSetGraph>
marci@1008
   797
  class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
marci@1008
   798
  public:
marci@1008
   799
    typedef GraphWrapperBase<_Graph> Parent; 
marci@1008
   800
    typedef _Graph Graph;
marci@1008
   801
    typedef _EdgeSetGraph EdgeSetGraph;
marci@1008
   802
    typedef typename _Graph::Node Node;
marci@1008
   803
    typedef typename _EdgeSetGraph::Node ENode;
marci@1008
   804
  protected:
marci@1008
   805
    EdgeSetGraph* edge_set_graph;
marci@1008
   806
    typename Graph::NodeMap<ENode>* e_node;
marci@1008
   807
    typename EdgeSetGraph::NodeMap<Node>* n_node;
marci@1008
   808
    void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) { 
marci@1008
   809
      edge_set_graph=&_edge_set_graph; 
marci@1008
   810
    }
marci@1008
   811
    /// For each node of \c Graph, this gives a node of \c EdgeSetGraph .
marci@1008
   812
    void setNodeMap(typename EdgeSetGraph::NodeMap<Node>& _n_node) { 
marci@1008
   813
      n_node=&_n_node; 
marci@1008
   814
    }
marci@1008
   815
    /// For each node of \c EdgeSetGraph, this gives a node of \c Graph .
marci@1008
   816
    void setENodeMap(typename Graph::NodeMap<ENode>& _e_node) { 
marci@1008
   817
      e_node=&_e_node; 
marci@1008
   818
    }
marci@1008
   819
  public:
marci@1008
   820
    class Edge : public EdgeSetGraph::Edge {
marci@1008
   821
      typedef typename EdgeSetGraph::Edge Parent;
marci@1008
   822
    public:
marci@1008
   823
      Edge() { }
marci@1008
   824
      Edge(const Parent& e) : Parent(e) { }
marci@1008
   825
      Edge(Invalid i) : Parent(i) { }
marci@1008
   826
    };
marci@1008
   827
marci@1008
   828
    using Parent::first;
marci@1008
   829
    void first(Edge &e) const { 
marci@1008
   830
      edge_set_graph->first(e);
marci@1008
   831
    }
marci@1008
   832
    void firstOut(Edge& e, const Node& n) const {
marci@1008
   833
//       cout << e_node << endl;
marci@1008
   834
//       cout << n_node << endl;
marci@1008
   835
      edge_set_graph->firstOut(e, (*e_node)[n]);
marci@1008
   836
    }
marci@1008
   837
    void firstIn(Edge& e, const Node& n) const {
marci@1008
   838
      edge_set_graph->firstIn(e, (*e_node)[n]);
marci@1008
   839
    }
marci@1008
   840
marci@1008
   841
    using Parent::next;
marci@1008
   842
    void next(Edge &e) const { 
marci@1008
   843
      edge_set_graph->next(e);
marci@1008
   844
    }
marci@1008
   845
    void nextOut(Edge& e) const {
marci@1008
   846
      edge_set_graph->nextOut(e);
marci@1008
   847
    }
marci@1008
   848
    void nextIn(Edge& e) const {
marci@1008
   849
      edge_set_graph->nextIn(e);
marci@1008
   850
    }
marci@1008
   851
marci@1008
   852
    Node source(const Edge& e) const { 
marci@1008
   853
      return (*n_node)[edge_set_graph->source(e)];
marci@1008
   854
    }
marci@1008
   855
    Node target(const Edge& e) const { 
marci@1008
   856
      return (*n_node)[edge_set_graph->target(e)];
marci@1008
   857
    }
marci@1008
   858
marci@1008
   859
    int edgeNum() const { return edge_set_graph->edgeNum(); }
marci@1008
   860
marci@1025
   861
//     NNode addOldNode() {
marci@1025
   862
//       return Parent::addNode();
marci@1025
   863
//     }
marci@1025
   864
marci@1025
   865
//     ENode addNewNode() {
marci@1025
   866
//       return edge_set_graph->addNode();
marci@1025
   867
//     }
marci@1025
   868
marci@1008
   869
    Edge addEdge(const Node& u, const Node& v) {
marci@1008
   870
      return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]);
marci@1008
   871
    }
marci@1008
   872
marci@1008
   873
    using Parent::erase;
marci@1008
   874
    void erase(const Edge& i) const { edge_set_graph->erase(i); }
marci@1008
   875
  
marci@1008
   876
    void clear() const { Parent::clear(); edge_set_graph->clear(); }
marci@1008
   877
marci@1008
   878
    bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
marci@1008
   879
    bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
marci@1008
   880
marci@1013
   881
    int id(const Node& e) const { return Parent::id(e); }
marci@1008
   882
    int id(const Edge& e) const { return edge_set_graph->id(e); }
marci@1008
   883
    
marci@1008
   884
    Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
marci@1008
   885
marci@1008
   886
    template <typename _Value>
marci@1008
   887
    class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> {
marci@1008
   888
    public:
marci@1008
   889
      typedef typename EdgeSetGraph::EdgeMap<_Value> Parent; 
marci@1008
   890
      typedef _Value Value;
marci@1008
   891
      typedef Edge Key;
marci@1008
   892
      EdgeMap(const NewEdgeSetGraphWrapperBase& gw) : 
marci@1008
   893
	Parent(*(gw.edge_set_graph)) { }
marci@1008
   894
      EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) : 
marci@1008
   895
	Parent(*(gw.edge_set_graph), _value) { }
marci@1008
   896
    };
marci@1008
   897
marci@1008
   898
  };
marci@1008
   899
marci@1013
   900
marci@1013
   901
  /*! A graph wrapper class for the following functionality.
marci@1013
   902
    If a bijection is given between the node-sets of two graphs, 
marci@1013
   903
    then the second one can be considered as a new edge-set 
marci@1013
   904
    over th first node-set. 
marci@1013
   905
   */
marci@1008
   906
  template <typename _Graph, typename _EdgeSetGraph>
marci@1008
   907
  class NewEdgeSetGraphWrapper : 
marci@1008
   908
    public IterableGraphExtender<
marci@1008
   909
    NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
marci@1008
   910
  public:
marci@1008
   911
    typedef _Graph Graph;
marci@1008
   912
    typedef _EdgeSetGraph EdgeSetGraph;
marci@1008
   913
    typedef IterableGraphExtender<
marci@1025
   914
      NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > Parent;
marci@1008
   915
  protected:
marci@1008
   916
    NewEdgeSetGraphWrapper() { }
marci@1008
   917
  public:
marci@1008
   918
    NewEdgeSetGraphWrapper(_Graph& _graph, 
marci@1008
   919
			   _EdgeSetGraph& _edge_set_graph, 
marci@1008
   920
			   typename _Graph::
marci@1008
   921
			   NodeMap<typename _EdgeSetGraph::Node>& _e_node, 
marci@1008
   922
			   typename _EdgeSetGraph::
marci@1008
   923
			   NodeMap<typename _Graph::Node>& _n_node) { 
marci@1008
   924
      setGraph(_graph);
marci@1008
   925
      setEdgeSetGraph(_edge_set_graph);
marci@1008
   926
      setNodeMap(_n_node);
marci@1008
   927
      setENodeMap(_e_node);
marci@1008
   928
    }
marci@1008
   929
  };
marci@1008
   930
marci@1025
   931
  /*! A graph wrapper class for the following functionality.
marci@1025
   932
    The same as NewEdgeSetGrapWrapper, but the bijection and the graph of 
marci@1025
   933
    new edges is andled inthe class.
marci@1025
   934
   */
marci@1025
   935
  template <typename _Graph, typename _EdgeSetGraph>
marci@1025
   936
  class NewEdgeSetGraphWrapper2 : 
marci@1025
   937
    public IterableGraphExtender<
marci@1025
   938
    NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
marci@1025
   939
  public:
marci@1025
   940
    typedef _Graph Graph;
marci@1025
   941
    typedef _EdgeSetGraph EdgeSetGraph;
marci@1025
   942
    typedef IterableGraphExtender<
marci@1025
   943
      NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > Parent;
marci@1025
   944
  protected:
marci@1025
   945
    _EdgeSetGraph _edge_set_graph;
marci@1025
   946
    typename Graph::template NodeMap<typename EdgeSetGraph::Node> _e_node;
marci@1025
   947
    typename EdgeSetGraph::template NodeMap<typename Graph::Node> _n_node;
marci@1025
   948
    NewEdgeSetGraphWrapper2() { }
marci@1025
   949
  public:
marci@1025
   950
    typedef typename Graph::Node Node;
marci@1025
   951
    //    typedef typename Parent::Edge Edge;
marci@1025
   952
marci@1025
   953
    NewEdgeSetGraphWrapper2(_Graph& _graph) : 
marci@1025
   954
      _edge_set_graph(), 
marci@1025
   955
      _e_node(_graph), _n_node(_edge_set_graph) { 
marci@1025
   956
      setGraph(_graph);
marci@1025
   957
      setEdgeSetGraph(_edge_set_graph);
marci@1025
   958
      setNodeMap(_n_node); setENodeMap(_e_node);
marci@1025
   959
      Node n;
marci@1025
   960
      for (this->first(n); n!=INVALID; this->next(n)) {
marci@1025
   961
	typename EdgeSetGraph::Node e=_edge_set_graph.addNode();
marci@1025
   962
	_e_node.set(n, e);
marci@1025
   963
	_n_node.set(e, n);
marci@1025
   964
      }
marci@1025
   965
    }
marci@1025
   966
marci@1025
   967
//     Node addNode() {
marci@1025
   968
//       Node n=(*this).Parent::addNode();
marci@1025
   969
//       typename EdgeSetGraph::Node e=_edge_set_graph.addNode();
marci@1025
   970
//       _e_node.set(n, e);
marci@1025
   971
//       _n_node.set(e, n);
marci@1025
   972
//       return n;
marci@1025
   973
//     }
marci@1025
   974
marci@1025
   975
  };
marci@1013
   976
marci@1013
   977
  /*! A graph wrapper base class 
marci@1013
   978
    for merging graphs of type _Graph1 and _Graph2 
marci@1013
   979
    which are given on the same node-set 
marci@1013
   980
    (specially on the node-set of Graph1) 
marci@1013
   981
    into one graph.
marci@1013
   982
    In an other point of view, _Graph1 is extended with 
marci@1013
   983
    the edge-set of _Graph2.
marci@1025
   984
    \warning we need specialize dimplementations
marci@1025
   985
    \todo we need specialize dimplementations
marci@1025
   986
    \bug we need specialize dimplementations
marci@1013
   987
   */
marci@1013
   988
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1013
   989
  class AugmentingGraphWrapperBase : 
marci@1013
   990
    public P1<_Graph1> {
marci@1013
   991
  public:
marci@1013
   992
    void printAugment() const { std::cout << "generic" << std::endl; }
marci@1013
   993
    typedef _Graph1 Graph1;
marci@1013
   994
    typedef _Graph2 Graph2;
marci@1013
   995
    typedef P1<_Graph1> Parent1;
marci@1013
   996
    typedef P2<_Graph2> Parent2;
marci@1013
   997
    typedef typename Parent1::Edge Graph1Edge;
marci@1013
   998
    typedef typename Parent2::Edge Graph2Edge;
marci@1013
   999
  protected:
marci@1013
  1000
    AugmentingGraphWrapperBase() { }
marci@1013
  1001
    _Graph2* graph2;
marci@1013
  1002
    void setGraph2(_Graph2& _graph2) { graph2=&_graph2; }
marci@1013
  1003
  public:
marci@1013
  1004
    
marci@1013
  1005
    template <typename _Value> class EdgeMap;
marci@1013
  1006
marci@1013
  1007
    typedef typename Parent1::Node Node;
marci@1013
  1008
marci@1013
  1009
    class Edge : public Graph1Edge, public Graph2Edge {
marci@1013
  1010
      friend class AugmentingGraphWrapperBase<_Graph1, _Graph2>;
marci@1013
  1011
      template <typename _Value> friend class EdgeMap;
marci@1013
  1012
    protected:
marci@1013
  1013
      bool backward; //true, iff backward
marci@1013
  1014
    public:
marci@1013
  1015
      Edge() { }
marci@1013
  1016
      /// \todo =false is needed, or causes problems?
marci@1013
  1017
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1013
  1018
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1013
  1019
      Edge(const Graph1Edge& n1, 
marci@1013
  1020
	   const Graph2Edge& n2, bool _backward) : 
marci@1013
  1021
	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
marci@1013
  1022
      Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
marci@1013
  1023
      bool operator==(const Edge& v) const { 
marci@1013
  1024
	if (backward) 
marci@1013
  1025
	  return (v.backward && 
marci@1013
  1026
		  static_cast<Graph2Edge>(*this)==static_cast<Graph2Edge>(v)); 
marci@1013
  1027
	else 
marci@1013
  1028
	  return (!v.backward && 
marci@1013
  1029
		  static_cast<Graph1Edge>(*this)==static_cast<Graph1Edge>(v)); 
marci@1013
  1030
      } 
marci@1013
  1031
      bool operator!=(const Edge& v) const { 
marci@1013
  1032
	return !(*this==v);
marci@1013
  1033
      }
marci@1013
  1034
    };
marci@1013
  1035
marci@1013
  1036
    using Parent1::first;
marci@1013
  1037
    void first(Edge& i) const {
marci@1013
  1038
      Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
marci@1013
  1039
      i.backward=false;
marci@1013
  1040
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1013
  1041
	graph2->first(*static_cast<Graph2Edge*>(&i));
marci@1013
  1042
	i.backward=true;
marci@1013
  1043
      }
marci@1013
  1044
    }
marci@1013
  1045
    void firstIn(Edge& i, const Node& n) const {
marci@1013
  1046
      Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
marci@1013
  1047
      i.backward=false;
marci@1013
  1048
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1013
  1049
	graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
marci@1013
  1050
	i.backward=true;
marci@1013
  1051
      }
marci@1013
  1052
    }
marci@1013
  1053
    void firstOut(Edge& i, const Node& n) const {
marci@1013
  1054
      Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
marci@1013
  1055
      i.backward=false;
marci@1013
  1056
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1013
  1057
	graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
marci@1013
  1058
	i.backward=true;
marci@1013
  1059
      }
marci@1013
  1060
    }
marci@1013
  1061
marci@1013
  1062
    using Parent1::next;
marci@1013
  1063
    void next(Edge& i) const {
marci@1013
  1064
      if (!(i.backward)) {
marci@1013
  1065
	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
marci@1013
  1066
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1013
  1067
	  graph2->first(*static_cast<Graph2Edge*>(&i));
marci@1013
  1068
	  i.backward=true;
marci@1013
  1069
	}
marci@1013
  1070
      } else {
marci@1013
  1071
	graph2->next(*static_cast<Graph2Edge*>(&i));
marci@1013
  1072
      }
marci@1013
  1073
    }
marci@1013
  1074
    void nextIn(Edge& i) const {
marci@1013
  1075
      if (!(i.backward)) {
marci@1025
  1076
	Node n=target(i);
marci@1013
  1077
	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
marci@1013
  1078
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1025
  1079
	  graph2->firstIn(*static_cast<Graph2Edge*>(&i), n);
marci@1013
  1080
	  i.backward=true;
marci@1013
  1081
	}
marci@1013
  1082
      } else {
marci@1013
  1083
	graph2->nextIn(*static_cast<Graph2Edge*>(&i));
marci@1013
  1084
      }
marci@1013
  1085
    }
marci@1013
  1086
    void nextOut(Edge& i) const {
marci@1013
  1087
      if (!(i.backward)) {
marci@1025
  1088
	Node n=source(i);
marci@1013
  1089
	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
marci@1013
  1090
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1025
  1091
	  graph2->firstOut(*static_cast<Graph2Edge*>(&i), n);
marci@1013
  1092
	  i.backward=true;
marci@1013
  1093
	}
marci@1013
  1094
      } else {
marci@1013
  1095
	graph2->nextOut(*static_cast<Graph2Edge*>(&i));
marci@1013
  1096
      }
marci@1013
  1097
    }
marci@1013
  1098
marci@1013
  1099
    Node source(const Edge& i) const {
marci@1013
  1100
      if (!(i.backward)) {
marci@1013
  1101
	return Parent1::graph->source(i);
marci@1013
  1102
      } else {
marci@1013
  1103
	return graph2->source(i);
marci@1013
  1104
      }
marci@1013
  1105
    }
marci@1013
  1106
marci@1013
  1107
    Node target(const Edge& i) const {
marci@1013
  1108
      if (!(i.backward)) {
marci@1013
  1109
	return Parent1::graph->target(i);
marci@1013
  1110
      } else {
marci@1013
  1111
	return graph2->target(i);
marci@1013
  1112
      }
marci@1013
  1113
    }
marci@1013
  1114
marci@1013
  1115
    int id(const Node& n) const {
marci@1013
  1116
      return Parent1::id(n);
marci@1013
  1117
    };
marci@1013
  1118
    int id(const Edge& n) const { 
marci@1013
  1119
      if (!n.backward) 
marci@1013
  1120
	return this->Parent1::graph->id(n);
marci@1013
  1121
      else
marci@1013
  1122
	return this->graph2->id(n);
marci@1013
  1123
    }
marci@1013
  1124
marci@1013
  1125
    template <typename _Value> 
marci@1013
  1126
    class EdgeMap { 
marci@1013
  1127
    protected:
marci@1013
  1128
      typedef typename _Graph1::template EdgeMap<_Value> ParentMap1;
marci@1013
  1129
      typedef typename _Graph2::template EdgeMap<_Value> ParentMap2;
marci@1013
  1130
      ParentMap1 forward_map;
marci@1013
  1131
      ParentMap2 backward_map;
marci@1013
  1132
    public:
marci@1013
  1133
      typedef _Value Value;
marci@1013
  1134
      typedef Edge Key;
marci@1013
  1135
      EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw) : 
marci@1013
  1136
	forward_map(*(gw.Parent1::graph)), 
marci@1013
  1137
	backward_map(*(gw.graph2)) { }
marci@1013
  1138
      EdgeMap(const AugmentingGraphWrapperBase<_Graph1, _Graph2>& gw, 
marci@1013
  1139
	      const _Value& value) : 
marci@1013
  1140
	forward_map(*(gw.Parent1::graph), value), 
marci@1013
  1141
	backward_map(*(gw.graph2), value) { }
marci@1013
  1142
      _Value operator[](const Edge& n) const {
marci@1013
  1143
	if (!n.backward) 
marci@1013
  1144
	  return forward_map[n];
marci@1013
  1145
	else 
marci@1013
  1146
	  return backward_map[n];
marci@1013
  1147
      }
marci@1013
  1148
      void set(const Edge& n, const _Value& value) {
marci@1013
  1149
	if (!n.backward) 
marci@1013
  1150
	  forward_map.set(n, value);
marci@1013
  1151
	else 
marci@1013
  1152
	  backward_map.set(n, value);
marci@1013
  1153
      }
marci@1013
  1154
//       using ParentMap1::operator[];
marci@1013
  1155
//       using ParentMap2::operator[];
marci@1013
  1156
    };
marci@1013
  1157
marci@1013
  1158
  };
marci@1013
  1159
marci@1013
  1160
marci@1013
  1161
  /*! A graph wrapper class 
marci@1013
  1162
    for merging two graphs (of type _Graph1 and _Graph2)
marci@1013
  1163
    with the same node-set 
marci@1013
  1164
    (specially on the node-set of Graph1) 
marci@1013
  1165
    into one graph. 
marci@1013
  1166
    In an other point of view, _Graph1 is extended with 
marci@1013
  1167
    the edge-set of _Graph2.
marci@1013
  1168
   */  
marci@1013
  1169
  template <typename _Graph1, typename _Graph2>
marci@1013
  1170
  class AugmentingGraphWrapper : public 
marci@1013
  1171
  IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> > {
marci@1013
  1172
  public:
marci@1013
  1173
    typedef 
marci@1013
  1174
    IterableGraphExtender<AugmentingGraphWrapperBase<_Graph1, _Graph2> >
marci@1013
  1175
    Parent;
marci@1013
  1176
    typedef _Graph1 Graph1;
marci@1013
  1177
    typedef _Graph2 Graph2;
marci@1013
  1178
  protected:
marci@1013
  1179
    AugmentingGraphWrapper() { }
marci@1013
  1180
  public:
marci@1013
  1181
    AugmentingGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
marci@1013
  1182
      setGraph(_graph1); 
marci@1013
  1183
      setGraph2(_graph2);
marci@1013
  1184
    }
marci@1013
  1185
  };
marci@1013
  1186
alpar@921
  1187
} //namespace lemon
marci@915
  1188
alpar@921
  1189
#endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H