src/work/marci/merge_node_graph_wrapper.h
author alpar
Sat, 20 Nov 2004 10:19:06 +0000
changeset 1011 5bd6c7671c9e
parent 1008 3fef334f5f37
child 1013 b3bdd856faf4
permissions -rw-r--r--
- snapshot-rollback functionarity added to ListGraph
- The iterface of the snapshot-rollback functionarity in SmartGraph has
changed to be compatible with ListGraph::SnapShot.
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@1008
    25
using std::cout;
marci@1008
    26
using std::endl;
marci@915
    27
marci@1007
    28
#include <boost/type_traits.hpp>
marci@1007
    29
#include <boost/utility/enable_if.hpp>
marci@1007
    30
alpar@921
    31
namespace lemon {
marci@915
    32
marci@1007
    33
  template <class _Graph1>
marci@1007
    34
  class P1 : public GraphWrapperBase<_Graph1> {
marci@1007
    35
  };
marci@1007
    36
marci@1007
    37
  template <class _Graph2>
marci@1007
    38
  class P2 : public GraphWrapperBase<_Graph2> {
marci@1007
    39
  };
marci@1007
    40
marci@1009
    41
  /*! A base class for merging the node-set of two node-disjoint graphs 
marci@1009
    42
    into the node-set of one graph.
marci@1009
    43
   */
marci@1002
    44
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1002
    45
  class MergeNodeGraphWrapperBase : 
marci@1007
    46
    public P1<_Graph1>, public P2<_Graph2> {
marci@915
    47
  public:
marci@1009
    48
    void printNode() const { std::cout << "generic" << std::endl; }
marci@1002
    49
    typedef _Graph1 Graph1;
marci@1002
    50
    typedef _Graph2 Graph2;
marci@1007
    51
    typedef P1<_Graph1> Parent1;
marci@1007
    52
    typedef P2<_Graph2> Parent2;
marci@1002
    53
    typedef typename Parent1::Node Graph1Node;
marci@1002
    54
    typedef typename Parent2::Node Graph2Node;
marci@1002
    55
  protected:
marci@1002
    56
    MergeNodeGraphWrapperBase() { }
marci@1002
    57
  public:
marci@1002
    58
    template <typename _Value> class NodeMap;
marci@915
    59
marci@915
    60
    class Node : public Graph1Node, public Graph2Node {
marci@1002
    61
      friend class MergeNodeGraphWrapperBase<_Graph1, _Graph2>;
marci@1002
    62
      template <typename Value> friend class NodeMap;
marci@915
    63
    protected:
marci@915
    64
      bool backward; //true, iff backward
marci@915
    65
    public:
marci@915
    66
      Node() { }
marci@915
    67
      /// \todo =false is needed, or causes problems?
marci@915
    68
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@915
    69
      /// original one, otherwise its oppositely directed pair is obtained.
marci@915
    70
      Node(const Graph1Node& n1, 
marci@915
    71
	   const Graph2Node& n2, bool _backward) : 
marci@915
    72
	Graph1Node(n1), Graph2Node(n2), backward(_backward) { }
marci@915
    73
      Node(Invalid i) : Graph1Node(i), Graph2Node(i), backward(true) { }
marci@915
    74
      bool operator==(const Node& v) const { 
marci@915
    75
	return (this->backward==v.backward && 
marci@915
    76
		static_cast<Graph1Node>(*this)==
marci@915
    77
		static_cast<Graph1Node>(v) && 
marci@915
    78
		static_cast<Graph2Node>(*this)==
marci@915
    79
		static_cast<Graph2Node>(v));
marci@915
    80
      } 
marci@915
    81
      bool operator!=(const Node& v) const { 
marci@915
    82
	return (this->backward!=v.backward || 
marci@915
    83
		static_cast<Graph1Node>(*this)!=
marci@915
    84
		static_cast<Graph1Node>(v) || 
marci@915
    85
		static_cast<Graph2Node>(*this)!=
marci@915
    86
		static_cast<Graph2Node>(v));
marci@915
    87
      }
marci@915
    88
    };
marci@915
    89
marci@1002
    90
    //typedef void Edge;
marci@1002
    91
    class Edge { };
marci@1002
    92
    
marci@1002
    93
    void first(Node& i) const {
marci@1002
    94
      Parent1::graph->first(*static_cast<Graph1Node*>(&i));
marci@1002
    95
      i.backward=false;
marci@1002
    96
      if (*static_cast<Graph1Node*>(&i)==INVALID) {
marci@1002
    97
	Parent2::graph->first(*static_cast<Graph2Node*>(&i));
marci@1002
    98
	i.backward=true;
marci@1002
    99
      }
marci@1002
   100
    }
marci@1002
   101
    void next(Node& i) const {
marci@1002
   102
      if (!(i.backward)) {
marci@1002
   103
	Parent1::graph->next(*static_cast<Graph1Node*>(&i));
marci@1002
   104
	if (*static_cast<Graph1Node*>(&i)==INVALID) {
marci@1002
   105
	  Parent2::graph->first(*static_cast<Graph2Node*>(&i));
marci@1002
   106
	  i.backward=true;
marci@915
   107
	}
marci@1002
   108
      } else {
marci@1002
   109
	Parent2::graph->next(*static_cast<Graph2Node*>(&i));
marci@915
   110
      }
marci@1002
   111
    }
marci@915
   112
marci@915
   113
    int id(const Node& n) const { 
marci@915
   114
      if (!n.backward) 
marci@915
   115
	return this->Parent1::graph->id(n);
marci@915
   116
      else
marci@915
   117
	return this->Parent2::graph->id(n);
marci@915
   118
    }
marci@915
   119
marci@1002
   120
    template <typename _Value> 
marci@1002
   121
    class NodeMap : public Parent1::template NodeMap<_Value>, 
marci@1002
   122
		    public Parent2::template NodeMap<_Value> { 
marci@1002
   123
      typedef typename Parent1::template NodeMap<_Value> ParentMap1;
marci@1002
   124
      typedef typename Parent2::template NodeMap<_Value> ParentMap2;
marci@917
   125
    public:
marci@1002
   126
      typedef _Value Value;
marci@1002
   127
      typedef Node Key;
marci@1002
   128
      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
marci@1002
   129
	ParentMap1(gw), ParentMap2(gw) { }
marci@1002
   130
      NodeMap(const MergeNodeGraphWrapperBase<_Graph1, _Graph2>& gw, 
marci@1002
   131
	      const _Value& value) : 
marci@1002
   132
	ParentMap1(gw, value), ParentMap2(gw, value) { }
marci@1002
   133
      _Value operator[](const Node& n) const {
marci@917
   134
	if (!n.backward) 
marci@917
   135
	  return ParentMap1::operator[](n);
marci@917
   136
	else 
marci@917
   137
	  return ParentMap2::operator[](n);
marci@917
   138
      }
marci@1002
   139
      void set(const Node& n, const _Value& value) {
marci@917
   140
	if (!n.backward) 
marci@917
   141
	  ParentMap1::set(n, value);
marci@917
   142
	else 
marci@917
   143
	  ParentMap2::set(n, value);
marci@917
   144
      }
marci@1009
   145
//       using ParentMap1::operator[];
marci@1009
   146
//       using ParentMap2::operator[];
marci@917
   147
    };
marci@1002
   148
marci@1002
   149
  };
marci@1002
   150
marci@1008
   151
  //not yet working
marci@1007
   152
  template <typename _Graph1, typename _Graph2>
marci@1007
   153
  class MergeNodeGraphWrapperBase<
marci@1007
   154
    _Graph1, _Graph2, typename boost::enable_if<
marci@1007
   155
    boost::is_same<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
marci@1007
   156
    public P1<_Graph1>, public P2<_Graph2> {
marci@1007
   157
  public :
marci@1009
   158
    void printNode() const { std::cout << "same" << std::endl; }
marci@1007
   159
    typedef _Graph1 Graph1;
marci@1007
   160
    typedef _Graph2 Graph2;
marci@1007
   161
    typedef P1<_Graph1> Parent1;
marci@1007
   162
    typedef P2<_Graph2> Parent2;
marci@1007
   163
    typedef typename Parent1::Node Graph1Node;
marci@1007
   164
    typedef typename Parent2::Node Graph2Node;
marci@1007
   165
  protected:
marci@1007
   166
    MergeNodeGraphWrapperBase() { }
marci@1007
   167
  public:
marci@1007
   168
    class Node { };
marci@1007
   169
    class Edge { };
marci@1007
   170
    void first() const;
marci@1007
   171
    void next() const;
marci@1007
   172
  };
marci@1007
   173
marci@1008
   174
  //not yet working
marci@1007
   175
  template <typename _Graph1, typename _Graph2>
marci@1007
   176
  class MergeNodeGraphWrapperBase<
marci@1007
   177
    _Graph1, _Graph2, typename boost::enable_if<
marci@1007
   178
    boost::is_base_and_derived<typename _Graph1::Node, typename _Graph2::Node> >::type> : 
marci@1007
   179
    public P1<_Graph1>, public P2<_Graph2> {
marci@1007
   180
  public :
marci@1009
   181
    void printNode() const { std::cout << "2. nagyobb" << std::endl; }
marci@1007
   182
    typedef _Graph1 Graph1;
marci@1007
   183
    typedef _Graph2 Graph2;
marci@1007
   184
    typedef P1<_Graph1> Parent1;
marci@1007
   185
    typedef P2<_Graph2> Parent2;
marci@1007
   186
    typedef typename Parent1::Node Graph1Node;
marci@1007
   187
    typedef typename Parent2::Node Graph2Node;
marci@1007
   188
  protected:
marci@1007
   189
    MergeNodeGraphWrapperBase() { }
marci@1007
   190
  public:
marci@1007
   191
    class Node { };
marci@1007
   192
    class Edge { };
marci@1007
   193
    void first() const;
marci@1007
   194
    void next() const;
marci@1007
   195
  };
marci@1007
   196
marci@1008
   197
  //not yet working
marci@1007
   198
  template <typename _Graph1, typename _Graph2>
marci@1007
   199
  class MergeNodeGraphWrapperBase<
marci@1007
   200
    _Graph1, _Graph2, typename boost::enable_if<
marci@1007
   201
    boost::is_base_and_derived<typename _Graph2::Node, typename _Graph1::Node> >::type> : 
marci@1007
   202
    public P1<_Graph1>, public P2<_Graph2> {
marci@1007
   203
  public :
marci@1009
   204
    void printNode() const { std::cout << "1. nagyobb" << std::endl; }
marci@1007
   205
    typedef _Graph1 Graph1;
marci@1007
   206
    typedef _Graph2 Graph2;
marci@1007
   207
    typedef P1<_Graph1> Parent1;
marci@1007
   208
    typedef P2<_Graph2> Parent2;
marci@1007
   209
    typedef typename Parent1::Node Graph1Node;
marci@1007
   210
    typedef typename Parent2::Node Graph2Node;
marci@1007
   211
  protected:
marci@1007
   212
    MergeNodeGraphWrapperBase() { }
marci@1007
   213
  public:
marci@1007
   214
    class Node { };
marci@1007
   215
    class Edge { };
marci@1007
   216
    void first() const;
marci@1007
   217
    void next() const;
marci@1007
   218
  };
marci@1007
   219
marci@1002
   220
marci@1009
   221
  template <typename _Graph1, typename _Graph2>
marci@1002
   222
  class MergeNodeGraphWrapper : public 
marci@1009
   223
  IterableGraphExtender<MergeNodeGraphWrapperBase<_Graph1, _Graph2> > {
marci@1002
   224
  public:
marci@1002
   225
    typedef _Graph1 Graph1;
marci@1002
   226
    typedef _Graph2 Graph2;
marci@1002
   227
    typedef IterableGraphExtender<
marci@1009
   228
      MergeNodeGraphWrapperBase<_Graph1, _Graph2> > Parent;
marci@1002
   229
  protected:
marci@1002
   230
    MergeNodeGraphWrapper() { }
marci@1002
   231
  public:
marci@1002
   232
    MergeNodeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
marci@1002
   233
      Parent::Parent1::setGraph(_graph1);
marci@1002
   234
      Parent::Parent2::setGraph(_graph2);
marci@1002
   235
    }
marci@915
   236
  };
marci@915
   237
marci@1009
   238
marci@1009
   239
  /*! A base class for merging the node-sets and edge-sets of 
marci@1009
   240
    two node-disjoint graphs 
marci@1009
   241
    into one graph.
marci@1009
   242
   */
marci@1009
   243
  template <typename _Graph1, typename _Graph2, typename Enable=void>
marci@1009
   244
  class MergeEdgeGraphWrapperBase : 
marci@1009
   245
    public MergeNodeGraphWrapperBase<_Graph1, _Graph2> {
marci@1009
   246
  public:
marci@1009
   247
    void printEdge() const { std::cout << "generic" << std::endl; }
marci@1009
   248
    typedef _Graph1 Graph1;
marci@1009
   249
    typedef _Graph2 Graph2;
marci@1009
   250
    typedef MergeNodeGraphWrapperBase<_Graph1, _Graph2> Parent;
marci@1009
   251
    typedef typename Parent::Parent1 Parent1;
marci@1009
   252
    typedef typename Parent::Parent2 Parent2;
marci@1009
   253
//     typedef P1<_Graph1> Parent1;
marci@1009
   254
//     typedef P2<_Graph2> Parent2;
marci@1009
   255
    typedef typename Parent1::Edge Graph1Edge;
marci@1009
   256
    typedef typename Parent2::Edge Graph2Edge;
marci@1009
   257
  protected:
marci@1009
   258
    MergeEdgeGraphWrapperBase() { }
marci@1009
   259
  public:
marci@1009
   260
    template <typename _Value> class EdgeMap;
marci@1009
   261
marci@1009
   262
    typedef typename Parent::Node Node;
marci@1009
   263
marci@1009
   264
    class Edge : public Graph1Edge, public Graph2Edge {
marci@1009
   265
      friend class MergeEdgeGraphWrapperBase<_Graph1, _Graph2>;
marci@1009
   266
      template <typename Value> friend class EdgeMap;
marci@1009
   267
    protected:
marci@1009
   268
      bool backward; //true, iff backward
marci@1009
   269
    public:
marci@1009
   270
      Edge() { }
marci@1009
   271
      /// \todo =false is needed, or causes problems?
marci@1009
   272
      /// If \c _backward is false, then we get an edge corresponding to the 
marci@1009
   273
      /// original one, otherwise its oppositely directed pair is obtained.
marci@1009
   274
      Edge(const Graph1Edge& n1, 
marci@1009
   275
	   const Graph2Edge& n2, bool _backward) : 
marci@1009
   276
	Graph1Edge(n1), Graph2Edge(n2), backward(_backward) { }
marci@1009
   277
      Edge(Invalid i) : Graph1Edge(i), Graph2Edge(i), backward(true) { }
marci@1009
   278
      bool operator==(const Edge& v) const { 
marci@1009
   279
	return (this->backward==v.backward && 
marci@1009
   280
		static_cast<Graph1Edge>(*this)==
marci@1009
   281
		static_cast<Graph1Edge>(v) && 
marci@1009
   282
		static_cast<Graph2Edge>(*this)==
marci@1009
   283
		static_cast<Graph2Edge>(v));
marci@1009
   284
      } 
marci@1009
   285
      bool operator!=(const Edge& v) const { 
marci@1009
   286
	return (this->backward!=v.backward || 
marci@1009
   287
		static_cast<Graph1Edge>(*this)!=
marci@1009
   288
		static_cast<Graph1Edge>(v) || 
marci@1009
   289
		static_cast<Graph2Edge>(*this)!=
marci@1009
   290
		static_cast<Graph2Edge>(v));
marci@1009
   291
      }
marci@1009
   292
    };
marci@1009
   293
marci@1009
   294
    using Parent::first;
marci@1009
   295
    void first(Edge& i) const {
marci@1009
   296
      Parent1::graph->first(*static_cast<Graph1Edge*>(&i));
marci@1009
   297
      i.backward=false;
marci@1009
   298
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1009
   299
	Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
marci@1009
   300
	i.backward=true;
marci@1009
   301
      }
marci@1009
   302
    }
marci@1009
   303
    void firstIn(Edge& i, const Node& n) const {
marci@1009
   304
      Parent1::graph->firstIn(*static_cast<Graph1Edge*>(&i), n);
marci@1009
   305
      i.backward=false;
marci@1009
   306
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1009
   307
	Parent2::graph->firstIn(*static_cast<Graph2Edge*>(&i), n);
marci@1009
   308
	i.backward=true;
marci@1009
   309
      }
marci@1009
   310
    }
marci@1009
   311
    void firstOut(Edge& i, const Node& n) const {
marci@1009
   312
      Parent1::graph->firstOut(*static_cast<Graph1Edge*>(&i), n);
marci@1009
   313
      i.backward=false;
marci@1009
   314
      if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1009
   315
	Parent2::graph->firstOut(*static_cast<Graph2Edge*>(&i), n);
marci@1009
   316
	i.backward=true;
marci@1009
   317
      }
marci@1009
   318
    }
marci@1009
   319
marci@1009
   320
    using Parent::next;
marci@1009
   321
    void next(Edge& i) const {
marci@1009
   322
      if (!(i.backward)) {
marci@1009
   323
	Parent1::graph->next(*static_cast<Graph1Edge*>(&i));
marci@1009
   324
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1009
   325
	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
marci@1009
   326
	  i.backward=true;
marci@1009
   327
	}
marci@1009
   328
      } else {
marci@1009
   329
	Parent2::graph->next(*static_cast<Graph2Edge*>(&i));
marci@1009
   330
      }
marci@1009
   331
    }
marci@1009
   332
    void nextIn(Edge& i) const {
marci@1009
   333
      if (!(i.backward)) {
marci@1009
   334
	Parent1::graph->nextIn(*static_cast<Graph1Edge*>(&i));
marci@1009
   335
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1009
   336
	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
marci@1009
   337
	  i.backward=true;
marci@1009
   338
	}
marci@1009
   339
      } else {
marci@1009
   340
	Parent2::graph->nextIn(*static_cast<Graph2Edge*>(&i));
marci@1009
   341
      }
marci@1009
   342
    }
marci@1009
   343
    void nextOut(Edge& i) const {
marci@1009
   344
      if (!(i.backward)) {
marci@1009
   345
	Parent1::graph->nextOut(*static_cast<Graph1Edge*>(&i));
marci@1009
   346
	if (*static_cast<Graph1Edge*>(&i)==INVALID) {
marci@1009
   347
	  Parent2::graph->first(*static_cast<Graph2Edge*>(&i));
marci@1009
   348
	  i.backward=true;
marci@1009
   349
	}
marci@1009
   350
      } else {
marci@1009
   351
	Parent2::graph->nextOut(*static_cast<Graph2Edge*>(&i));
marci@1009
   352
      }
marci@1009
   353
    }
marci@1009
   354
marci@1009
   355
    Node source(const Edge& i) const {
marci@1009
   356
      if (!(i.backward)) {
marci@1009
   357
	return 
marci@1009
   358
	  Node(Parent1::graph->source(i), INVALID, false);
marci@1009
   359
      } else {
marci@1009
   360
	return 
marci@1009
   361
	  Node(INVALID, Parent2::graph->source(i), true);
marci@1009
   362
      }
marci@1009
   363
    }
marci@1009
   364
marci@1009
   365
    Node target(const Edge& i) const {
marci@1009
   366
      if (!(i.backward)) {
marci@1009
   367
	return 
marci@1009
   368
	  Node(Parent1::graph->target(i), INVALID, false);
marci@1009
   369
      } else {
marci@1009
   370
	return 
marci@1009
   371
	  Node(INVALID, Parent2::graph->target(i), true);
marci@1009
   372
      }
marci@1009
   373
    }
marci@1009
   374
marci@1009
   375
    using Parent::id;
marci@1009
   376
    int id(const Edge& n) const { 
marci@1009
   377
      if (!n.backward) 
marci@1009
   378
	return this->Parent1::graph->id(n);
marci@1009
   379
      else
marci@1009
   380
	return this->Parent2::graph->id(n);
marci@1009
   381
    }
marci@1009
   382
marci@1009
   383
    template <typename _Value> 
marci@1009
   384
    class EdgeMap : public Parent1::template EdgeMap<_Value>, 
marci@1009
   385
		    public Parent2::template EdgeMap<_Value> { 
marci@1009
   386
      typedef typename Parent1::template EdgeMap<_Value> ParentMap1;
marci@1009
   387
      typedef typename Parent2::template EdgeMap<_Value> ParentMap2;
marci@1009
   388
    public:
marci@1009
   389
      typedef _Value Value;
marci@1009
   390
      typedef Edge Key;
marci@1009
   391
      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw) : 
marci@1009
   392
	ParentMap1(gw), ParentMap2(gw) { }
marci@1009
   393
      EdgeMap(const MergeEdgeGraphWrapperBase<_Graph1, _Graph2>& gw, 
marci@1009
   394
	      const _Value& value) : 
marci@1009
   395
	ParentMap1(gw, value), ParentMap2(gw, value) { }
marci@1009
   396
      _Value operator[](const Edge& n) const {
marci@1009
   397
	if (!n.backward) 
marci@1009
   398
	  return ParentMap1::operator[](n);
marci@1009
   399
	else 
marci@1009
   400
	  return ParentMap2::operator[](n);
marci@1009
   401
      }
marci@1009
   402
      void set(const Edge& n, const _Value& value) {
marci@1009
   403
	if (!n.backward) 
marci@1009
   404
	  ParentMap1::set(n, value);
marci@1009
   405
	else 
marci@1009
   406
	  ParentMap2::set(n, value);
marci@1009
   407
      }
marci@1009
   408
//       using ParentMap1::operator[];
marci@1009
   409
//       using ParentMap2::operator[];
marci@1009
   410
    };
marci@1009
   411
marci@1009
   412
  };
marci@1009
   413
marci@1009
   414
marci@1009
   415
  template <typename _Graph1, typename _Graph2>
marci@1009
   416
  class MergeEdgeGraphWrapper : public 
marci@1009
   417
  IterableGraphExtender<MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > {
marci@1009
   418
  public:
marci@1009
   419
    typedef _Graph1 Graph1;
marci@1009
   420
    typedef _Graph2 Graph2;
marci@1009
   421
    typedef IterableGraphExtender<
marci@1009
   422
      MergeEdgeGraphWrapperBase<_Graph1, _Graph2> > Parent;
marci@1009
   423
  protected:
marci@1009
   424
    MergeEdgeGraphWrapper() { }
marci@1009
   425
  public:
marci@1009
   426
    MergeEdgeGraphWrapper(_Graph1& _graph1, _Graph2& _graph2) { 
marci@1009
   427
      Parent::Parent1::setGraph(_graph1);
marci@1009
   428
      Parent::Parent2::setGraph(_graph2);
marci@1009
   429
    }
marci@1009
   430
  };
marci@1009
   431
marci@1008
   432
  
marci@1008
   433
  template <typename _Graph, typename _EdgeSetGraph>
marci@1008
   434
  class NewEdgeSetGraphWrapperBase : public GraphWrapperBase<_Graph> {
marci@1008
   435
  public:
marci@1008
   436
    typedef GraphWrapperBase<_Graph> Parent; 
marci@1008
   437
    typedef _Graph Graph;
marci@1008
   438
    typedef _EdgeSetGraph EdgeSetGraph;
marci@1008
   439
    typedef typename _Graph::Node Node;
marci@1008
   440
    typedef typename _EdgeSetGraph::Node ENode;
marci@1008
   441
  protected:
marci@1008
   442
    EdgeSetGraph* edge_set_graph;
marci@1008
   443
    typename Graph::NodeMap<ENode>* e_node;
marci@1008
   444
    typename EdgeSetGraph::NodeMap<Node>* n_node;
marci@1008
   445
    void setEdgeSetGraph(EdgeSetGraph& _edge_set_graph) { 
marci@1008
   446
      edge_set_graph=&_edge_set_graph; 
marci@1008
   447
    }
marci@1008
   448
    /// For each node of \c Graph, this gives a node of \c EdgeSetGraph .
marci@1008
   449
    void setNodeMap(typename EdgeSetGraph::NodeMap<Node>& _n_node) { 
marci@1008
   450
      n_node=&_n_node; 
marci@1008
   451
    }
marci@1008
   452
    /// For each node of \c EdgeSetGraph, this gives a node of \c Graph .
marci@1008
   453
    void setENodeMap(typename Graph::NodeMap<ENode>& _e_node) { 
marci@1008
   454
      e_node=&_e_node; 
marci@1008
   455
    }
marci@1008
   456
  public:
marci@1008
   457
    class Edge : public EdgeSetGraph::Edge {
marci@1008
   458
      typedef typename EdgeSetGraph::Edge Parent;
marci@1008
   459
    public:
marci@1008
   460
      Edge() { }
marci@1008
   461
      Edge(const Parent& e) : Parent(e) { }
marci@1008
   462
      Edge(Invalid i) : Parent(i) { }
marci@1008
   463
    };
marci@1008
   464
marci@1008
   465
    using Parent::first;
marci@1008
   466
    void first(Edge &e) const { 
marci@1008
   467
      edge_set_graph->first(e);
marci@1008
   468
    }
marci@1008
   469
    void firstOut(Edge& e, const Node& n) const {
marci@1008
   470
//       cout << e_node << endl;
marci@1008
   471
//       cout << n_node << endl;
marci@1008
   472
      edge_set_graph->firstOut(e, (*e_node)[n]);
marci@1008
   473
    }
marci@1008
   474
    void firstIn(Edge& e, const Node& n) const {
marci@1008
   475
      edge_set_graph->firstIn(e, (*e_node)[n]);
marci@1008
   476
    }
marci@1008
   477
marci@1008
   478
    using Parent::next;
marci@1008
   479
    void next(Edge &e) const { 
marci@1008
   480
      edge_set_graph->next(e);
marci@1008
   481
    }
marci@1008
   482
    void nextOut(Edge& e) const {
marci@1008
   483
      edge_set_graph->nextOut(e);
marci@1008
   484
    }
marci@1008
   485
    void nextIn(Edge& e) const {
marci@1008
   486
      edge_set_graph->nextIn(e);
marci@1008
   487
    }
marci@1008
   488
marci@1008
   489
    Node source(const Edge& e) const { 
marci@1008
   490
      return (*n_node)[edge_set_graph->source(e)];
marci@1008
   491
    }
marci@1008
   492
    Node target(const Edge& e) const { 
marci@1008
   493
      return (*n_node)[edge_set_graph->target(e)];
marci@1008
   494
    }
marci@1008
   495
marci@1008
   496
    int edgeNum() const { return edge_set_graph->edgeNum(); }
marci@1008
   497
marci@1008
   498
    Edge addEdge(const Node& u, const Node& v) {
marci@1008
   499
      return edge_set_graph->addEdge((*e_node)[u], (*e_node)[v]);
marci@1008
   500
    }
marci@1008
   501
marci@1008
   502
    using Parent::erase;
marci@1008
   503
    void erase(const Edge& i) const { edge_set_graph->erase(i); }
marci@1008
   504
  
marci@1008
   505
    void clear() const { Parent::clear(); edge_set_graph->clear(); }
marci@1008
   506
marci@1008
   507
    bool forward(const Edge& e) const { return edge_set_graph->forward(e); }
marci@1008
   508
    bool backward(const Edge& e) const { return edge_set_graph->backward(e); }
marci@1008
   509
marci@1008
   510
    using Parent::id;
marci@1008
   511
    int id(const Edge& e) const { return edge_set_graph->id(e); }
marci@1008
   512
    
marci@1008
   513
    Edge opposite(const Edge& e) const { return edge_set_graph->opposite(e); }
marci@1008
   514
marci@1008
   515
    template <typename _Value>
marci@1008
   516
    class EdgeMap : public EdgeSetGraph::EdgeMap<_Value> {
marci@1008
   517
    public:
marci@1008
   518
      typedef typename EdgeSetGraph::EdgeMap<_Value> Parent; 
marci@1008
   519
      typedef _Value Value;
marci@1008
   520
      typedef Edge Key;
marci@1008
   521
      EdgeMap(const NewEdgeSetGraphWrapperBase& gw) : 
marci@1008
   522
	Parent(*(gw.edge_set_graph)) { }
marci@1008
   523
      EdgeMap(const NewEdgeSetGraphWrapperBase& gw, const _Value& _value) : 
marci@1008
   524
	Parent(*(gw.edge_set_graph), _value) { }
marci@1008
   525
    };
marci@1008
   526
marci@1008
   527
  };
marci@1008
   528
marci@1008
   529
  template <typename _Graph, typename _EdgeSetGraph>
marci@1008
   530
  class NewEdgeSetGraphWrapper : 
marci@1008
   531
    public IterableGraphExtender<
marci@1008
   532
    NewEdgeSetGraphWrapperBase<_Graph, _EdgeSetGraph> > {
marci@1008
   533
  public:
marci@1008
   534
    typedef _Graph Graph;
marci@1008
   535
    typedef _EdgeSetGraph EdgeSetGraph;
marci@1008
   536
    typedef IterableGraphExtender<
marci@1008
   537
      NewEdgeSetGraphWrapper<_Graph, _EdgeSetGraph> > Parent;
marci@1008
   538
  protected:
marci@1008
   539
    NewEdgeSetGraphWrapper() { }
marci@1008
   540
  public:
marci@1008
   541
    NewEdgeSetGraphWrapper(_Graph& _graph, 
marci@1008
   542
			   _EdgeSetGraph& _edge_set_graph, 
marci@1008
   543
			   typename _Graph::
marci@1008
   544
			   NodeMap<typename _EdgeSetGraph::Node>& _e_node, 
marci@1008
   545
			   typename _EdgeSetGraph::
marci@1008
   546
			   NodeMap<typename _Graph::Node>& _n_node) { 
marci@1008
   547
      setGraph(_graph);
marci@1008
   548
      setEdgeSetGraph(_edge_set_graph);
marci@1008
   549
      setNodeMap(_n_node);
marci@1008
   550
      setENodeMap(_e_node);
marci@1008
   551
    }
marci@1008
   552
  };
marci@1008
   553
alpar@921
   554
} //namespace lemon
marci@915
   555
alpar@921
   556
#endif //LEMON_MERGE_NODE_GRAPH_WRAPPER_H