src/work/marci/graph_wrapper.h
author deba
Fri, 16 Apr 2004 13:42:03 +0000
changeset 340 a2ce3c4780b7
parent 335 999eb3cd7b49
child 341 6046b1d0f267
permissions -rw-r--r--
(none)
marci@174
     1
// -*- c++ -*-
marci@259
     2
#ifndef HUGO_GRAPH_WRAPPER_H
marci@259
     3
#define HUGO_GRAPH_WRAPPER_H
marci@76
     4
marci@174
     5
#include <invalid.h>
marci@174
     6
alpar@105
     7
namespace hugo {
marci@76
     8
marci@335
     9
  /// Graph wrappers
marci@335
    10
marci@335
    11
  /// The main parts of HUGOlib are the different graph structures, 
marci@335
    12
  /// generic graph algorithms, graph concepts which couple these, and 
marci@335
    13
  /// graph wrappers. While the previous ones are more or less clear, the 
marci@335
    14
  /// latter notion needs further explanation.
marci@335
    15
  /// Graph wrappers are graph classes which serve for considering graph 
marci@335
    16
  /// structures in different ways. A short example makes the notion much more 
marci@335
    17
  /// clear. 
marci@335
    18
  /// Suppose that we have an instance \code g \endcode of a directed graph
marci@335
    19
  /// type say \code ListGraph \endcode and an algorithm 
marci@335
    20
  /// \code template<typename Graph> int algorithm(const Graph&); \endcode 
marci@335
    21
  /// is needed to run on the reversed oriented graph. 
marci@335
    22
  /// It can be expensive (in time or in memory usage) to copy 
marci@335
    23
  /// \code g \endcode with the reversed orientation. 
marci@335
    24
  /// Thus, a wrapper class
marci@335
    25
  /// \code template<typename Graph> class RevGraphWrapper; \endcode is used. 
marci@335
    26
  /// The code looks as follows
marci@335
    27
  /// \code
marci@335
    28
  /// ListGraph g;
marci@335
    29
  /// RevGraphWrapper<ListGraph> rgw(g);
marci@335
    30
  /// int result=algorithm(rgw);
marci@335
    31
  /// \endcode
marci@335
    32
  /// After running the algorithm, the original graph \code g \endcode 
marci@335
    33
  /// is untouched. Thus the above used graph wrapper is to consider the 
marci@335
    34
  /// original graph with reversed orientation. 
marci@335
    35
  /// This techniques gives rise to an elegant code, and 
marci@335
    36
  /// based on stable graph wrappers, complex algorithms can be 
marci@335
    37
  /// implemented easily. 
marci@335
    38
  /// In flow, circulation and bipartite matching problems, the residual 
marci@335
    39
  /// graph is of particualar significance. Combining a wrapper impleneting 
marci@335
    40
  /// this, shortest path algorithms and mimimum mean cycle algorithms, 
marci@335
    41
  /// a range of weighted and cardinality optimization algorithms can be 
marci@335
    42
  /// obtained. For lack of space, for other examples, 
marci@335
    43
  /// the interested user is referred to the detailed domumentation of graph 
marci@335
    44
  /// wrappers. 
marci@335
    45
  /// The behavior of graph wrappers are very different. Some of them keep 
marci@335
    46
  /// capabilities of the original graph while in other cases this would be 
marci@335
    47
  /// meaningless. This means that the concepts that they are model of depend 
marci@335
    48
  /// on the graph wrapper, and the wrapped graph(s). 
marci@335
    49
  /// If an edge of \code rgw \endcode is deleted, this is carried out by 
marci@335
    50
  /// deleting the corresponding edge of \code g \endcode. But for a residual 
marci@335
    51
  /// graph, this operation has no sense. 
marci@335
    52
  /// Let we stand one more example here to simplify your work. 
marci@335
    53
  /// wrapper class
marci@335
    54
  /// \code template<typename Graph> class RevGraphWrapper; \endcode 
marci@335
    55
  /// has constructor 
marci@335
    56
  /// \code RevGraphWrapper(Graph& _g); \endcode. 
marci@335
    57
  /// This means that in a situation, 
marci@335
    58
  /// when a \code const ListGraph& \endcode reference to a graph is given, 
marci@335
    59
  /// then it have to be instatiated with Graph=const ListGraph.
marci@335
    60
  /// \code
marci@335
    61
  /// int algorithm1(const ListGraph& g) {
marci@335
    62
  ///   RevGraphWrapper<const ListGraph> rgw(g);
marci@335
    63
  ///   return algorithm2(rgw);
marci@335
    64
  /// }
marci@335
    65
  /// \endcode
marci@303
    66
  template<typename Graph>
marci@303
    67
  class GraphWrapper {
marci@212
    68
  protected:
marci@303
    69
    Graph* graph;
marci@212
    70
  
marci@212
    71
  public:
marci@311
    72
    typedef Graph BaseGraph;
marci@303
    73
    typedef Graph ParentGraph;
marci@212
    74
marci@303
    75
//     GraphWrapper() : graph(0) { }
marci@303
    76
    GraphWrapper(Graph& _graph) : graph(&_graph) { }
marci@303
    77
//     void setGraph(Graph& _graph) { graph=&_graph; }
marci@303
    78
//     Graph& getGraph() const { return *graph; }
marci@303
    79
 
marci@317
    80
//    typedef typename Graph::Node Node;
marci@317
    81
    class Node : public Graph::Node {
marci@317
    82
      friend class GraphWrapper<Graph>;
marci@265
    83
    public:
marci@317
    84
      Node() { }
marci@317
    85
      Node(const typename Graph::Node& _n) : Graph::Node(_n) { }
marci@317
    86
      Node(const Invalid& i) : Graph::Node(i) { }
marci@317
    87
    };
marci@317
    88
    class NodeIt { 
marci@317
    89
      friend class GraphWrapper<Graph>;
marci@317
    90
      typename Graph::NodeIt n;
marci@317
    91
     public:
marci@265
    92
      NodeIt() { }
marci@317
    93
      NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@317
    94
      NodeIt(const Invalid& i) : n(i) { }
marci@317
    95
      NodeIt(const GraphWrapper<Graph>& _G) : n(*(_G.graph)) { }
marci@317
    96
      operator Node() const { return Node(typename Graph::Node(n)); }
marci@265
    97
    };
marci@317
    98
//    typedef typename Graph::Edge Edge;
marci@317
    99
    class Edge : public Graph::Edge {
marci@317
   100
      friend class GraphWrapper<Graph>;
marci@317
   101
    public:
marci@317
   102
      Edge() { }
marci@317
   103
      Edge(const typename Graph::Edge& _e) : Graph::Edge(_e) { }
marci@317
   104
      Edge(const Invalid& i) : Graph::Edge(i) { }
marci@317
   105
    };
marci@317
   106
    class OutEdgeIt { 
marci@317
   107
      friend class GraphWrapper<Graph>;
marci@317
   108
      typename Graph::OutEdgeIt e;
marci@265
   109
    public:
marci@265
   110
      OutEdgeIt() { }
marci@317
   111
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317
   112
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@317
   113
      OutEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@317
   114
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317
   115
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265
   116
    };
marci@317
   117
    class InEdgeIt { 
marci@317
   118
      friend class GraphWrapper<Graph>;
marci@317
   119
      typename Graph::InEdgeIt e;
marci@265
   120
    public:
marci@265
   121
      InEdgeIt() { }
marci@317
   122
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317
   123
      InEdgeIt(const Invalid& i) : e(i) { }
marci@317
   124
      InEdgeIt(const GraphWrapper<Graph>& _G, const Node& _n) : 
marci@317
   125
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317
   126
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265
   127
    };
marci@303
   128
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317
   129
    class EdgeIt { 
marci@317
   130
      friend class GraphWrapper<Graph>;
marci@317
   131
      typename Graph::EdgeIt e;
marci@265
   132
    public:
marci@265
   133
      EdgeIt() { }
marci@317
   134
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317
   135
      EdgeIt(const Invalid& i) : e(i) { }
marci@317
   136
      EdgeIt(const GraphWrapper<Graph>& _G) : e(*(_G.graph)) { }
marci@317
   137
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@265
   138
    };
marci@303
   139
   
marci@303
   140
    NodeIt& first(NodeIt& i) const { 
marci@317
   141
      i=NodeIt(*this); return i;
marci@265
   142
    }
marci@303
   143
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   144
      i=OutEdgeIt(*this, p); return i;
marci@303
   145
    }
marci@303
   146
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   147
      i=InEdgeIt(*this, p); return i;
marci@303
   148
    }
marci@311
   149
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   150
      i=EdgeIt(*this); return i;
marci@311
   151
    }
marci@338
   152
marci@317
   153
    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@317
   154
    OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
marci@317
   155
    InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
marci@317
   156
    EdgeIt& next(EdgeIt& i) const { graph->next(i.e); return i; }    
marci@212
   157
marci@317
   158
    Node head(const Edge& e) const { 
marci@317
   159
      return Node(graph->head(static_cast<typename Graph::Edge>(e))); }
marci@317
   160
    Node tail(const Edge& e) const { 
marci@317
   161
      return Node(graph->tail(static_cast<typename Graph::Edge>(e))); }
marci@212
   162
marci@317
   163
    bool valid(const Node& n) const { 
marci@317
   164
      return graph->valid(static_cast<typename Graph::Node>(n)); }
marci@317
   165
    bool valid(const Edge& e) const { 
marci@317
   166
      return graph->valid(static_cast<typename Graph::Edge>(e)); }
marci@212
   167
marci@303
   168
    int nodeNum() const { return graph->nodeNum(); }
marci@303
   169
    int edgeNum() const { return graph->edgeNum(); }
marci@212
   170
  
marci@317
   171
    Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317
   172
    Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317
   173
    Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@317
   174
    Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@212
   175
  
marci@317
   176
    Node addNode() const { return Node(graph->addNode()); }
marci@212
   177
    Edge addEdge(const Node& tail, const Node& head) const { 
marci@317
   178
      return Edge(graph->addEdge(tail, head)); }
marci@317
   179
marci@317
   180
    void erase(const Node& i) const { graph->erase(i); }
marci@317
   181
    void erase(const Edge& i) const { graph->erase(i); }
marci@212
   182
  
marci@303
   183
    void clear() const { graph->clear(); }
marci@212
   184
    
marci@303
   185
    template<typename T> class NodeMap : public Graph::NodeMap<T> { 
marci@212
   186
    public:
marci@303
   187
      NodeMap(const GraphWrapper<Graph>& _G) :  
marci@303
   188
	Graph::NodeMap<T>(*(_G.graph)) { }
marci@303
   189
      NodeMap(const GraphWrapper<Graph>& _G, T a) : 
marci@303
   190
	Graph::NodeMap<T>(*(_G.graph), a) { }
marci@212
   191
    };
marci@212
   192
marci@303
   193
    template<typename T> class EdgeMap : public Graph::EdgeMap<T> { 
marci@212
   194
    public:
marci@303
   195
      EdgeMap(const GraphWrapper<Graph>& _G) :  
marci@303
   196
	Graph::EdgeMap<T>(*(_G.graph)) { }
marci@303
   197
      EdgeMap(const GraphWrapper<Graph>& _G, T a) : 
marci@303
   198
	Graph::EdgeMap<T>(*(_G.graph), a) { }
marci@212
   199
    };
marci@212
   200
  };
marci@212
   201
marci@338
   202
  /// A graph wrapper which reverses the orientation of the edges.
marci@303
   203
marci@338
   204
  /// A graph wrapper which reverses the orientation of the edges.
marci@303
   205
  template<typename Graph>
marci@303
   206
  class RevGraphWrapper : public GraphWrapper<Graph> {
marci@230
   207
  public:
marci@338
   208
marci@338
   209
    RevGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@338
   210
marci@303
   211
    typedef typename GraphWrapper<Graph>::Node Node;
marci@303
   212
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@303
   213
    //If Graph::OutEdgeIt is not defined
marci@279
   214
    //and we do not want to use RevGraphWrapper::InEdgeIt,
marci@338
   215
    //the typdef techinque does not work.
marci@338
   216
    //Unfortunately all the typedefs are instantiated in templates.
marci@338
   217
    //typedef typename GraphWrapper<Graph>::OutEdgeIt InEdgeIt;
marci@338
   218
    //typedef typename GraphWrapper<Graph>::InEdgeIt OutEdgeIt;
marci@237
   219
marci@338
   220
    class OutEdgeIt { 
marci@338
   221
      friend class GraphWrapper<Graph>;
marci@338
   222
      friend class RevGraphWrapper<Graph>;
marci@338
   223
      typename Graph::OutEdgeIt e;
marci@338
   224
    public:
marci@338
   225
      OutEdgeIt() { }
marci@338
   226
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@338
   227
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@338
   228
      OutEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@338
   229
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@338
   230
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@338
   231
    };
marci@338
   232
    class InEdgeIt { 
marci@338
   233
      friend class GraphWrapper<Graph>;
marci@338
   234
      friend class RevGraphWrapper<Graph>;
marci@338
   235
      typename Graph::InEdgeIt e;
marci@338
   236
    public:
marci@338
   237
      InEdgeIt() { }
marci@338
   238
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@338
   239
      InEdgeIt(const Invalid& i) : e(i) { }
marci@338
   240
      InEdgeIt(const RevGraphWrapper<Graph>& _G, const Node& _n) : 
marci@338
   241
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@338
   242
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@338
   243
    };
marci@238
   244
marci@338
   245
    using GraphWrapper<Graph>::first;
marci@338
   246
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@338
   247
      i=OutEdgeIt(*this, p); return i;
marci@338
   248
    }
marci@338
   249
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@338
   250
      i=InEdgeIt(*this, p); return i;
marci@338
   251
    }
marci@338
   252
marci@338
   253
    using GraphWrapper<Graph>::next;
marci@338
   254
    OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
marci@338
   255
    InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
marci@338
   256
marci@338
   257
    Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@338
   258
    Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@338
   259
    Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@338
   260
    Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@76
   261
  };
marci@76
   262
marci@335
   263
  /// Wrapper for hiding nodes and edges from a graph.
marci@335
   264
  
marci@335
   265
  /// This wrapper shows a graph with filtered node-set and 
marci@335
   266
  /// edge-set. The quick brown fox iterators jumps over 
marci@335
   267
  /// the lazy dog nodes or edges if the values for them are false 
marci@335
   268
  /// in the bool maps. 
marci@311
   269
  template<typename Graph, typename NodeFilterMap, 
marci@311
   270
	   typename EdgeFilterMap>
marci@303
   271
  class SubGraphWrapper : public GraphWrapper<Graph> {
marci@263
   272
  protected:
marci@311
   273
    NodeFilterMap* node_filter_map;
marci@311
   274
    EdgeFilterMap* edge_filter_map;
marci@263
   275
  public:
marci@338
   276
marci@311
   277
    SubGraphWrapper(Graph& _graph, NodeFilterMap& _node_filter_map, 
marci@311
   278
		    EdgeFilterMap& _edge_filter_map) : 
marci@311
   279
      GraphWrapper<Graph>(_graph), node_filter_map(&_node_filter_map), 
marci@311
   280
      edge_filter_map(&_edge_filter_map) { }  
marci@263
   281
marci@317
   282
    typedef typename GraphWrapper<Graph>::Node Node;
marci@317
   283
    class NodeIt { 
marci@317
   284
      friend class GraphWrapper<Graph>;
marci@317
   285
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   286
      typename Graph::NodeIt n;
marci@317
   287
     public:
marci@311
   288
      NodeIt() { }
marci@317
   289
      NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@317
   290
      NodeIt(const Invalid& i) : n(i) { }
marci@311
   291
      NodeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@317
   292
	n(*(_G.graph)) { 
marci@317
   293
	while (_G.graph->valid(n) && !(*(_G.node_filter_map))[n]) 
marci@317
   294
	  _G.graph->next(n);
marci@311
   295
      }
marci@317
   296
      operator Node() const { return Node(typename Graph::Node(n)); }
marci@311
   297
    };
marci@317
   298
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317
   299
    class OutEdgeIt { 
marci@317
   300
      friend class GraphWrapper<Graph>;
marci@317
   301
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   302
      typename Graph::OutEdgeIt e;
marci@311
   303
    public:
marci@311
   304
      OutEdgeIt() { }
marci@317
   305
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317
   306
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@317
   307
      OutEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@317
   308
		const Node& _n) : 
marci@317
   309
	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@317
   310
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317
   311
	  _G.graph->next(e);
marci@311
   312
      }
marci@317
   313
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   314
    };
marci@317
   315
    class InEdgeIt { 
marci@317
   316
      friend class GraphWrapper<Graph>;
marci@317
   317
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   318
      typename Graph::InEdgeIt e;
marci@311
   319
    public:
marci@311
   320
      InEdgeIt() { }
marci@317
   321
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317
   322
      InEdgeIt(const Invalid& i) : e(i) { }
marci@311
   323
      InEdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G, 
marci@317
   324
	       const Node& _n) : 
marci@317
   325
	e(*(_G.graph), typename Graph::Node(_n)) { 
marci@317
   326
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317
   327
	  _G.graph->next(e);
marci@311
   328
      }
marci@317
   329
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   330
    };
marci@317
   331
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317
   332
    class EdgeIt { 
marci@317
   333
      friend class GraphWrapper<Graph>;
marci@317
   334
      friend class SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>;
marci@317
   335
      typename Graph::EdgeIt e;
marci@311
   336
    public:
marci@311
   337
      EdgeIt() { }
marci@317
   338
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317
   339
      EdgeIt(const Invalid& i) : e(i) { }
marci@311
   340
      EdgeIt(const SubGraphWrapper<Graph, NodeFilterMap, EdgeFilterMap>& _G) : 
marci@317
   341
	e(*(_G.graph)) { 
marci@317
   342
      	while (_G.graph->valid(e) && !(*(_G.edge_filter_map))[e]) 
marci@317
   343
	  _G.graph->next(e);
marci@311
   344
      }
marci@317
   345
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   346
    };
marci@317
   347
marci@317
   348
    NodeIt& first(NodeIt& i) const { 
marci@317
   349
      i=NodeIt(*this); return i;
marci@263
   350
    }
marci@317
   351
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   352
      i=OutEdgeIt(*this, p); return i;
marci@311
   353
    }
marci@317
   354
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   355
      i=InEdgeIt(*this, p); return i;
marci@311
   356
    }
marci@317
   357
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   358
      i=EdgeIt(*this); return i;
marci@263
   359
    }
marci@263
   360
    
marci@311
   361
    NodeIt& next(NodeIt& i) const {
marci@317
   362
      graph->next(i.n); 
marci@317
   363
      while (graph->valid(i) && !(*node_filter_map)[i.n]) { graph->next(i.n); }
marci@311
   364
      return i;
marci@311
   365
    }
marci@311
   366
    OutEdgeIt& next(OutEdgeIt& i) const {
marci@317
   367
      graph->next(i.e); 
marci@317
   368
      while (graph->valid(i) && !(*edge_filter_map)[i.e]) { graph->next(i.e); }
marci@311
   369
      return i;
marci@311
   370
    }
marci@311
   371
    InEdgeIt& next(InEdgeIt& i) const {
marci@317
   372
      graph->next(i.e); 
marci@317
   373
      while (graph->valid(i) && !(*edge_filter_map)[i.e]) { graph->next(i.e); }
marci@311
   374
      return i;
marci@311
   375
    }
marci@311
   376
    EdgeIt& next(EdgeIt& i) const {
marci@317
   377
      graph->next(i.e); 
marci@317
   378
      while (graph->valid(i) && !(*edge_filter_map)[i.e]) { graph->next(i.e); }
marci@311
   379
      return i;
marci@311
   380
    }
marci@311
   381
marci@323
   382
    Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@323
   383
    Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@323
   384
    Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@323
   385
    Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@323
   386
marci@323
   387
    void hide(const Node& n) const { node_filter_map->set(n, false); }
marci@323
   388
    void hide(const Edge& e) const { edge_filter_map->set(e, false); }
marci@323
   389
marci@323
   390
    void unHide(const Node& n) const { node_filter_map->set(n, true); }
marci@323
   391
    void unHide(const Edge& e) const { edge_filter_map->set(e, true); }
marci@323
   392
marci@323
   393
    bool hidden(const Node& n) const { return (*node_filter_map)[n]; }
marci@323
   394
    bool hidden(const Edge& e) const { return (*edge_filter_map)[e]; }
marci@263
   395
  };
marci@155
   396
marci@338
   397
  /// A wrapper for getting an undirected graph by forgetting the orientation of a directed one.
marci@317
   398
marci@338
   399
  /// A wrapper for getting an undirected graph by forgetting the orientation of a directed one.
marci@303
   400
  template<typename Graph>
marci@303
   401
  class UndirGraphWrapper : public GraphWrapper<Graph> {
marci@303
   402
  public:
marci@303
   403
    typedef typename GraphWrapper<Graph>::Node Node;
marci@303
   404
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@317
   405
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317
   406
    typedef typename GraphWrapper<Graph>::EdgeIt EdgeIt;
marci@236
   407
marci@303
   408
    UndirGraphWrapper(Graph& _graph) : GraphWrapper<Graph>(_graph) { }  
marci@158
   409
marci@317
   410
    class OutEdgeIt {
marci@303
   411
      friend class UndirGraphWrapper<Graph>;
marci@158
   412
      bool out_or_in; //true iff out
marci@317
   413
      typename Graph::OutEdgeIt out;
marci@317
   414
      typename Graph::InEdgeIt in;
marci@158
   415
    public:
marci@317
   416
      OutEdgeIt() { }
marci@317
   417
      OutEdgeIt(const Invalid& i) : Edge(i) { }
marci@317
   418
      OutEdgeIt(const UndirGraphWrapper<Graph>& _G, const Node& _n) {
marci@317
   419
	out_or_in=true; _G.graph->first(out, _n);
marci@317
   420
	if (!(_G.graph->valid(out))) { out_or_in=false; _G.graph->first(in, _n);	}
marci@174
   421
      } 
marci@317
   422
      operator Edge() const { 
marci@317
   423
	if (out_or_in) return Edge(out); else return Edge(in); 
marci@158
   424
      }
marci@158
   425
    };
marci@158
   426
marci@317
   427
//FIXME InEdgeIt
marci@238
   428
    typedef OutEdgeIt InEdgeIt; 
marci@238
   429
marci@338
   430
    using GraphWrapper<Graph>::first;
marci@338
   431
//     NodeIt& first(NodeIt& i) const { 
marci@338
   432
//       i=NodeIt(*this); return i;
marci@338
   433
//     }
marci@317
   434
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   435
      i=OutEdgeIt(*this, p); return i;
marci@317
   436
    }
marci@317
   437
//FIXME
marci@317
   438
//     InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   439
//       i=InEdgeIt(*this, p); return i;
marci@317
   440
//     }
marci@338
   441
//     EdgeIt& first(EdgeIt& i) const { 
marci@338
   442
//       i=EdgeIt(*this); return i;
marci@338
   443
//     }
marci@238
   444
marci@338
   445
    using GraphWrapper<Graph>::next;
marci@338
   446
//     NodeIt& next(NodeIt& n) const {
marci@338
   447
//       GraphWrapper<Graph>::next(n);
marci@338
   448
//       return n;
marci@338
   449
//     }
marci@158
   450
    OutEdgeIt& next(OutEdgeIt& e) const {
marci@158
   451
      if (e.out_or_in) {
marci@317
   452
	typename Graph::Node n=graph->tail(e.out);
marci@303
   453
	graph->next(e.out);
marci@303
   454
	if (!graph->valid(e.out)) { e.out_or_in=false; graph->first(e.in, n); }
marci@158
   455
      } else {
marci@303
   456
	graph->next(e.in);
marci@158
   457
      }
marci@158
   458
      return e;
marci@158
   459
    }
marci@317
   460
    //FIXME InEdgeIt
marci@338
   461
//     EdgeIt& next(EdgeIt& e) const {
marci@338
   462
//       GraphWrapper<Graph>::next(n);
marci@338
   463
// //      graph->next(e.e);
marci@338
   464
//       return e;
marci@338
   465
//     }
marci@238
   466
marci@238
   467
    Node aNode(const OutEdgeIt& e) const { 
marci@303
   468
      if (e.out_or_in) return graph->tail(e); else return graph->head(e); }
marci@238
   469
    Node bNode(const OutEdgeIt& e) const { 
marci@303
   470
      if (e.out_or_in) return graph->head(e); else return graph->tail(e); }
marci@338
   471
  };
marci@158
   472
  
marci@338
   473
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@238
   474
marci@338
   475
  /// A wrapper for composing the residual graph for directed flow and circulation problems.
marci@330
   476
  template<typename Graph, typename Number, 
marci@330
   477
	   typename CapacityMap, typename FlowMap>
marci@311
   478
  class ResGraphWrapper : public GraphWrapper<Graph> {
marci@199
   479
  protected:
marci@330
   480
    const CapacityMap* capacity;
marci@155
   481
    FlowMap* flow;
marci@155
   482
  public:
marci@168
   483
marci@330
   484
    ResGraphWrapper(Graph& _graph, const CapacityMap& _capacity, 
marci@330
   485
		    FlowMap& _flow) : 
marci@330
   486
      GraphWrapper<Graph>(_graph), capacity(&_capacity), flow(&_flow) { }
marci@168
   487
marci@174
   488
    class Edge; 
marci@155
   489
    class OutEdgeIt; 
marci@174
   490
    friend class Edge; 
marci@155
   491
    friend class OutEdgeIt; 
marci@76
   492
marci@311
   493
    typedef typename GraphWrapper<Graph>::Node Node;
marci@311
   494
    typedef typename GraphWrapper<Graph>::NodeIt NodeIt;
marci@317
   495
    class Edge : public Graph::Edge {
marci@330
   496
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@155
   497
    protected:
marci@317
   498
      bool forward; //true, iff forward
marci@317
   499
//      typename Graph::Edge e;
marci@155
   500
    public:
marci@317
   501
      Edge() { }
marci@317
   502
      Edge(const typename Graph::Edge& _e, bool _forward) : 
marci@317
   503
	Graph::Edge(_e), forward(_forward) { }
marci@317
   504
      Edge(const Invalid& i) : Graph::Edge(i), forward(false) { }
marci@317
   505
//the unique invalid iterator
marci@174
   506
      friend bool operator==(const Edge& u, const Edge& v) { 
marci@317
   507
	return (v.forward==u.forward && 
marci@317
   508
		static_cast<typename Graph::Edge>(u)==
marci@317
   509
		static_cast<typename Graph::Edge>(v));
marci@174
   510
      } 
marci@174
   511
      friend bool operator!=(const Edge& u, const Edge& v) { 
marci@317
   512
	return (v.forward!=u.forward || 
marci@317
   513
		static_cast<typename Graph::Edge>(u)!=
marci@317
   514
		static_cast<typename Graph::Edge>(v));
marci@174
   515
      } 
marci@155
   516
    };
marci@338
   517
marci@317
   518
    class OutEdgeIt {
marci@330
   519
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317
   520
    protected:
marci@317
   521
      typename Graph::OutEdgeIt out;
marci@317
   522
      typename Graph::InEdgeIt in;
marci@317
   523
      bool forward;
marci@155
   524
    public:
marci@155
   525
      OutEdgeIt() { }
marci@168
   526
      //FIXME
marci@317
   527
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@317
   528
      OutEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@317
   529
//the unique invalid iterator
marci@330
   530
      OutEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@317
   531
	forward=true;
marci@303
   532
	resG.graph->first(out, v);
marci@317
   533
	while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@303
   534
	if (!resG.graph->valid(out)) {
marci@317
   535
	  forward=false;
marci@303
   536
	  resG.graph->first(in, v);
marci@317
   537
	  while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@155
   538
	}
marci@155
   539
      }
marci@317
   540
      operator Edge() const { 
marci@317
   541
//	Edge e;
marci@317
   542
//	e.forward=this->forward;
marci@317
   543
//	if (this->forward) e=out; else e=in;
marci@317
   544
//	return e;
marci@317
   545
	if (this->forward) 
marci@317
   546
	  return Edge(out, this->forward); 
marci@317
   547
	else 
marci@317
   548
	  return Edge(in, this->forward);
marci@317
   549
      }
marci@317
   550
    };
marci@263
   551
marci@317
   552
    class InEdgeIt {
marci@330
   553
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317
   554
    protected:
marci@317
   555
      typename Graph::OutEdgeIt out;
marci@317
   556
      typename Graph::InEdgeIt in;
marci@317
   557
      bool forward;
marci@317
   558
    public:
marci@317
   559
      InEdgeIt() { }
marci@317
   560
      //FIXME
marci@317
   561
//      OutEdgeIt(const Edge& e) : Edge(e) { }
marci@317
   562
      InEdgeIt(const Invalid& i) : out(i), in(i), forward(false) { }
marci@317
   563
//the unique invalid iterator
marci@330
   564
      InEdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG, Node v) { 
marci@317
   565
	forward=true;
marci@317
   566
	resG.graph->first(in, v);
marci@317
   567
	while( resG.graph->valid(in) && !(resG.resCap(*this)>0) ) { resG.graph->next(in); }
marci@317
   568
	if (!resG.graph->valid(in)) {
marci@317
   569
	  forward=false;
marci@317
   570
	  resG.graph->first(out, v);
marci@317
   571
	  while( resG.graph->valid(out) && !(resG.resCap(*this)>0) ) { resG.graph->next(out); }
marci@317
   572
	}
marci@317
   573
      }
marci@317
   574
      operator Edge() const { 
marci@317
   575
//	Edge e;
marci@317
   576
//	e.forward=this->forward;
marci@317
   577
//	if (this->forward) e=out; else e=in;
marci@317
   578
//	return e;
marci@317
   579
	if (this->forward) 
marci@317
   580
	  return Edge(in, this->forward); 
marci@317
   581
	else 
marci@317
   582
	  return Edge(out, this->forward);
marci@317
   583
      }
marci@317
   584
    };
marci@317
   585
marci@317
   586
    class EdgeIt {
marci@330
   587
      friend class ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>;
marci@317
   588
    protected:
marci@317
   589
      typename Graph::EdgeIt e;
marci@317
   590
      bool forward;
marci@155
   591
    public:
marci@174
   592
      EdgeIt() { }
marci@317
   593
      EdgeIt(const Invalid& i) : e(i), forward(false) { }
marci@330
   594
      EdgeIt(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& resG) { 
marci@317
   595
	forward=true;
marci@317
   596
	resG.graph->first(e);
marci@317
   597
	while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@317
   598
	if (!resG.graph->valid(e)) {
marci@317
   599
	  forward=false;
marci@317
   600
	  resG.graph->first(e);
marci@317
   601
	  while (resG.graph->valid(e) && !(resG.resCap(*this)>0)) resG.graph->next(e);
marci@155
   602
	}
marci@155
   603
      }
marci@317
   604
      operator Edge() const { 
marci@317
   605
	return Edge(e, this->forward);
marci@317
   606
      }
marci@317
   607
    };
marci@155
   608
marci@338
   609
    using GraphWrapper<Graph>::first;
marci@338
   610
//     NodeIt& first(NodeIt& i) const { 
marci@338
   611
//       i=NodeIt(*this); return i;
marci@338
   612
//     }
marci@311
   613
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   614
      i=OutEdgeIt(*this, p); return i;
marci@311
   615
    }
marci@317
   616
//    FIXME not tested
marci@317
   617
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   618
      i=InEdgeIt(*this, p); return i;
marci@317
   619
    }
marci@317
   620
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   621
      i=EdgeIt(*this); return i;
marci@155
   622
    }
marci@338
   623
  
marci@338
   624
    using GraphWrapper<Graph>::next;
marci@338
   625
//    NodeIt& next(NodeIt& n) const { GraphWrapper<Graph>::next(n); return n; }
marci@155
   626
    OutEdgeIt& next(OutEdgeIt& e) const { 
marci@317
   627
      if (e.forward) {
marci@303
   628
	Node v=graph->aNode(e.out);
marci@303
   629
	graph->next(e.out);
marci@317
   630
	while( graph->valid(e.out) && !(resCap(e)>0) ) { graph->next(e.out); }
marci@303
   631
	if (!graph->valid(e.out)) {
marci@317
   632
	  e.forward=false;
marci@303
   633
	  graph->first(e.in, v); 
marci@317
   634
	  while( graph->valid(e.in) && !(resCap(e)>0) ) { graph->next(e.in); }
marci@155
   635
	}
marci@155
   636
      } else {
marci@303
   637
	graph->next(e.in);
marci@317
   638
	while( graph->valid(e.in) && !(resCap(e)>0) ) { graph->next(e.in); } 
marci@155
   639
      }
marci@155
   640
      return e;
marci@155
   641
    }
marci@317
   642
//     FIXME Not tested
marci@317
   643
    InEdgeIt& next(InEdgeIt& e) const { 
marci@317
   644
      if (e.forward) {
marci@317
   645
	Node v=graph->aNode(e.in);
marci@317
   646
	graph->next(e.in);
marci@317
   647
	while( graph->valid(e.in) && !(resCap(e)>0) ) { graph->next(e.in); }
marci@317
   648
	if (!graph->valid(e.in)) {
marci@317
   649
	  e.forward=false;
marci@317
   650
	  graph->first(e.out, v); 
marci@317
   651
	  while( graph->valid(e.out) && !(resCap(e)>0) ) { graph->next(e.out); }
marci@317
   652
	}
marci@317
   653
      } else {
marci@303
   654
	graph->next(e.out);
marci@317
   655
	while( graph->valid(e.out) && !(resCap(e)>0) ) { graph->next(e.out); } 
marci@317
   656
      }
marci@317
   657
      return e;
marci@317
   658
    }
marci@317
   659
    EdgeIt& next(EdgeIt& e) const {
marci@317
   660
      if (e.forward) {
marci@317
   661
	graph->next(e.e);
marci@317
   662
	while( graph->valid(e.e) && !(resCap(e)>0) ) { graph->next(e.e); }
marci@317
   663
	if (!graph->valid(e.e)) {
marci@317
   664
	  e.forward=false;
marci@317
   665
	  graph->first(e.e); 
marci@317
   666
	  while( graph->valid(e.e) && !(resCap(e)>0) ) { graph->next(e.e); }
marci@155
   667
	}
marci@317
   668
      } else {
marci@317
   669
	graph->next(e.e);
marci@317
   670
	while( graph->valid(e.e) && !(resCap(e)>0) ) { graph->next(e.e); } 
marci@155
   671
      }
marci@317
   672
      return e;
marci@317
   673
    }
marci@76
   674
marci@174
   675
    Node tail(Edge e) const { 
marci@317
   676
      return ((e.forward) ? graph->tail(e) : graph->head(e)); }
marci@174
   677
    Node head(Edge e) const { 
marci@317
   678
      return ((e.forward) ? graph->head(e) : graph->tail(e)); }
marci@76
   679
marci@174
   680
    Node aNode(OutEdgeIt e) const { 
marci@317
   681
      return ((e.forward) ? graph->aNode(e.out) : graph->aNode(e.in)); }
marci@174
   682
    Node bNode(OutEdgeIt e) const { 
marci@317
   683
      return ((e.forward) ? graph->bNode(e.out) : graph->bNode(e.in)); }
marci@76
   684
marci@338
   685
//    int nodeNum() const { return graph->nodeNum(); }
marci@263
   686
    //FIXME
marci@338
   687
    void edgeNum() const { }
marci@303
   688
    //int edgeNum() const { return graph->edgeNum(); }
marci@263
   689
marci@263
   690
marci@317
   691
//    int id(Node v) const { return graph->id(v); }
marci@155
   692
marci@317
   693
    bool valid(Node n) const { return GraphWrapper<Graph>::valid(n); }
marci@174
   694
    bool valid(Edge e) const { 
marci@317
   695
      return graph->valid(e);
marci@317
   696
	//return e.forward ? graph->valid(e.out) : graph->valid(e.in); 
marci@317
   697
    }
marci@155
   698
marci@174
   699
    void augment(const Edge& e, Number a) const {
marci@317
   700
      if (e.forward)  
marci@303
   701
// 	flow->set(e.out, flow->get(e.out)+a);
marci@317
   702
	flow->set(e, (*flow)[e]+a);
marci@168
   703
      else  
marci@303
   704
// 	flow->set(e.in, flow->get(e.in)-a);
marci@317
   705
	flow->set(e, (*flow)[e]-a);
marci@168
   706
    }
marci@168
   707
marci@269
   708
    Number resCap(const Edge& e) const { 
marci@317
   709
      if (e.forward) 
marci@303
   710
//	return (capacity->get(e.out)-flow->get(e.out)); 
marci@317
   711
	return ((*capacity)[e]-(*flow)[e]); 
marci@168
   712
      else 
marci@303
   713
//	return (flow->get(e.in)); 
marci@317
   714
	return ((*flow)[e]); 
marci@168
   715
    }
marci@168
   716
marci@317
   717
//     Number resCap(typename Graph::OutEdgeIt out) const { 
marci@317
   718
// //      return (capacity->get(out)-flow->get(out)); 
marci@317
   719
//       return ((*capacity)[out]-(*flow)[out]); 
marci@317
   720
//     }
marci@168
   721
    
marci@317
   722
//     Number resCap(typename Graph::InEdgeIt in) const { 
marci@317
   723
// //      return (flow->get(in)); 
marci@317
   724
//       return ((*flow)[in]); 
marci@317
   725
//     }
marci@168
   726
marci@155
   727
    template <typename T>
marci@155
   728
    class EdgeMap {
marci@303
   729
      typename Graph::EdgeMap<T> forward_map, backward_map; 
marci@155
   730
    public:
marci@330
   731
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G) : forward_map(*(_G.graph)), backward_map(*(_G.graph)) { }
marci@330
   732
      EdgeMap(const ResGraphWrapper<Graph, Number, CapacityMap, FlowMap>& _G, T a) : forward_map(*(_G.graph), a), backward_map(*(_G.graph), a) { }
marci@174
   733
      void set(Edge e, T a) { 
marci@317
   734
	if (e.forward) 
marci@155
   735
	  forward_map.set(e.out, a); 
marci@155
   736
	else 
marci@155
   737
	  backward_map.set(e.in, a); 
marci@155
   738
      }
marci@303
   739
      T operator[](Edge e) const { 
marci@317
   740
	if (e.forward) 
marci@303
   741
	  return forward_map[e.out]; 
marci@155
   742
	else 
marci@303
   743
	  return backward_map[e.in]; 
marci@155
   744
      }
marci@303
   745
//       T get(Edge e) const { 
marci@303
   746
// 	if (e.out_or_in) 
marci@303
   747
// 	  return forward_map.get(e.out); 
marci@303
   748
// 	else 
marci@303
   749
// 	  return backward_map.get(e.in); 
marci@303
   750
//       }
marci@155
   751
    };
marci@168
   752
  };
marci@168
   753
marci@338
   754
  /// ErasingFirstGraphWrapper for blocking flows.
marci@317
   755
marci@338
   756
  /// ErasingFirstGraphWrapper for blocking flows.
marci@303
   757
  template<typename Graph, typename FirstOutEdgesMap>
marci@303
   758
  class ErasingFirstGraphWrapper : public GraphWrapper<Graph> {
marci@269
   759
  protected:
marci@269
   760
    FirstOutEdgesMap* first_out_edges;
marci@269
   761
  public:
marci@303
   762
    ErasingFirstGraphWrapper(Graph& _graph, 
marci@303
   763
			     FirstOutEdgesMap& _first_out_edges) : 
marci@303
   764
      GraphWrapper<Graph>(_graph), first_out_edges(&_first_out_edges) { }  
marci@269
   765
marci@317
   766
    typedef typename GraphWrapper<Graph>::Node Node;
marci@338
   767
//     class NodeIt { 
marci@338
   768
//       friend class GraphWrapper<Graph>;
marci@338
   769
//       friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@338
   770
//       typename Graph::NodeIt n;
marci@338
   771
//      public:
marci@338
   772
//       NodeIt() { }
marci@338
   773
//       NodeIt(const typename Graph::NodeIt& _n) : n(_n) { }
marci@338
   774
//       NodeIt(const Invalid& i) : n(i) { }
marci@338
   775
//       NodeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@338
   776
// 	n(*(_G.graph)) { }
marci@338
   777
//       operator Node() const { return Node(typename Graph::Node(n)); }
marci@338
   778
//     };
marci@317
   779
    typedef typename GraphWrapper<Graph>::Edge Edge;
marci@317
   780
    class OutEdgeIt { 
marci@317
   781
      friend class GraphWrapper<Graph>;
marci@317
   782
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317
   783
//      typedef typename Graph::OutEdgeIt GraphOutEdgeIt;
marci@317
   784
      typename Graph::OutEdgeIt e;
marci@311
   785
    public:
marci@311
   786
      OutEdgeIt() { }
marci@317
   787
      OutEdgeIt(const typename Graph::OutEdgeIt& _e) : e(_e) { }
marci@317
   788
      OutEdgeIt(const Invalid& i) : e(i) { }
marci@311
   789
      OutEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@317
   790
		const Node& _n) : 
marci@317
   791
	e((*_G.first_out_edges)[_n]) { }
marci@317
   792
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   793
    };
marci@317
   794
    class InEdgeIt { 
marci@317
   795
      friend class GraphWrapper<Graph>;
marci@317
   796
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317
   797
//      typedef typename Graph::InEdgeIt GraphInEdgeIt;
marci@317
   798
      typename Graph::InEdgeIt e;
marci@311
   799
    public:
marci@311
   800
      InEdgeIt() { }
marci@317
   801
      InEdgeIt(const typename Graph::InEdgeIt& _e) : e(_e) { }
marci@317
   802
      InEdgeIt(const Invalid& i) : e(i) { }
marci@311
   803
      InEdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G, 
marci@317
   804
	       const Node& _n) : 
marci@317
   805
	e(*(_G.graph), typename Graph::Node(_n)) { }
marci@317
   806
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   807
    };
marci@311
   808
    //typedef typename Graph::SymEdgeIt SymEdgeIt;
marci@317
   809
    class EdgeIt { 
marci@317
   810
      friend class GraphWrapper<Graph>;
marci@317
   811
      friend class ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>;
marci@317
   812
//      typedef typename Graph::EdgeIt GraphEdgeIt;
marci@317
   813
      typename Graph::EdgeIt e;
marci@311
   814
    public:
marci@311
   815
      EdgeIt() { }
marci@317
   816
      EdgeIt(const typename Graph::EdgeIt& _e) : e(_e) { }
marci@317
   817
      EdgeIt(const Invalid& i) : e(i) { }
marci@311
   818
      EdgeIt(const ErasingFirstGraphWrapper<Graph, FirstOutEdgesMap>& _G) : 
marci@317
   819
	e(*(_G.graph)) { }
marci@317
   820
      operator Edge() const { return Edge(typename Graph::Edge(e)); }
marci@311
   821
    };
marci@311
   822
marci@338
   823
    using GraphWrapper<Graph>::first;
marci@338
   824
//     NodeIt& first(NodeIt& i) const { 
marci@338
   825
//       i=NodeIt(*this); return i;
marci@338
   826
//     }
marci@317
   827
    OutEdgeIt& first(OutEdgeIt& i, const Node& p) const { 
marci@317
   828
      i=OutEdgeIt(*this, p); return i;
marci@269
   829
    }
marci@317
   830
    InEdgeIt& first(InEdgeIt& i, const Node& p) const { 
marci@317
   831
      i=InEdgeIt(*this, p); return i;
marci@311
   832
    }
marci@317
   833
    EdgeIt& first(EdgeIt& i) const { 
marci@317
   834
      i=EdgeIt(*this); return i;
marci@311
   835
    }
marci@311
   836
marci@338
   837
    using GraphWrapper<Graph>::next;
marci@338
   838
//    NodeIt& next(NodeIt& i) const { graph->next(i.n); return i; }
marci@317
   839
    OutEdgeIt& next(OutEdgeIt& i) const { graph->next(i.e); return i; }
marci@317
   840
    InEdgeIt& next(InEdgeIt& i) const { graph->next(i.e); return i; }
marci@317
   841
    EdgeIt& next(EdgeIt& i) const { graph->next(i.e); return i; }    
marci@317
   842
    
marci@317
   843
    Node aNode(const OutEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317
   844
    Node aNode(const InEdgeIt& e) const { return Node(graph->aNode(e.e)); }
marci@317
   845
    Node bNode(const OutEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@317
   846
    Node bNode(const InEdgeIt& e) const { return Node(graph->bNode(e.e)); }
marci@311
   847
marci@269
   848
    void erase(const OutEdgeIt& e) const {
marci@269
   849
      OutEdgeIt f=e;
marci@269
   850
      this->next(f);
marci@317
   851
      first_out_edges->set(this->tail(e), f.e);
marci@269
   852
    }
marci@269
   853
  };
marci@269
   854
alpar@105
   855
} //namespace hugo
marci@76
   856
marci@259
   857
#endif //HUGO_GRAPH_WRAPPER_H
marci@76
   858