lemon/bits/iterable_graph_extender.h
author marci
Tue, 06 Dec 2005 11:59:44 +0000
changeset 1850 50d1d6acfcc2
parent 1704 467d7927a901
child 1909 2d806130e700
permissions -rw-r--r--
Bugfix
klao@946
     1
// -*- c++ -*-
klao@946
     2
#ifndef LEMON_ITERABLE_GRAPH_EXTENDER_H
klao@946
     3
#define LEMON_ITERABLE_GRAPH_EXTENDER_H
klao@946
     4
klao@946
     5
#include <lemon/invalid.h>
alpar@1448
     6
#include <lemon/utility.h>
klao@946
     7
klao@946
     8
namespace lemon {
klao@946
     9
  
klao@946
    10
  template <typename _Base>
klao@946
    11
  class IterableGraphExtender : public _Base {
klao@962
    12
  public:
klao@946
    13
alpar@1448
    14
    /// Indicates that the graph is undirected.
alpar@1448
    15
alpar@1448
    16
    ///\todo Better name?
alpar@1448
    17
    ///
alpar@1448
    18
    ///\bug Should it be here?
alpar@1448
    19
    typedef False UndirTag;
alpar@1448
    20
klao@946
    21
    typedef _Base Parent;
klao@946
    22
    typedef IterableGraphExtender<_Base> Graph;
klao@946
    23
klao@946
    24
    typedef typename Parent::Node Node;
klao@946
    25
    typedef typename Parent::Edge Edge;
klao@946
    26
klao@946
    27
klao@946
    28
    class NodeIt : public Node { 
klao@946
    29
      const Graph* graph;
klao@946
    30
    public:
klao@946
    31
klao@946
    32
      NodeIt() {}
klao@946
    33
klao@946
    34
      NodeIt(Invalid i) : Node(i) { }
klao@946
    35
klao@962
    36
      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
klao@946
    37
	_graph.first(*static_cast<Node*>(this));
klao@946
    38
      }
klao@946
    39
klao@946
    40
      NodeIt(const Graph& _graph, const Node& node) 
klao@946
    41
	: Node(node), graph(&_graph) {}
klao@946
    42
klao@946
    43
      NodeIt& operator++() { 
klao@946
    44
	graph->next(*this);
klao@946
    45
	return *this; 
klao@946
    46
      }
klao@946
    47
klao@946
    48
    };
klao@946
    49
klao@946
    50
klao@946
    51
    class EdgeIt : public Edge { 
klao@946
    52
      const Graph* graph;
klao@946
    53
    public:
klao@946
    54
klao@946
    55
      EdgeIt() { }
klao@946
    56
klao@946
    57
      EdgeIt(Invalid i) : Edge(i) { }
klao@946
    58
klao@962
    59
      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
klao@946
    60
	_graph.first(*static_cast<Edge*>(this));
klao@946
    61
      }
klao@946
    62
klao@946
    63
      EdgeIt(const Graph& _graph, const Edge& e) : 
klao@946
    64
	Edge(e), graph(&_graph) { }
klao@946
    65
klao@946
    66
      EdgeIt& operator++() { 
klao@946
    67
	graph->next(*this);
klao@946
    68
	return *this; 
klao@946
    69
      }
klao@946
    70
klao@946
    71
    };
klao@946
    72
klao@946
    73
klao@946
    74
    class OutEdgeIt : public Edge { 
klao@946
    75
      const Graph* graph;
klao@946
    76
    public:
klao@946
    77
klao@946
    78
      OutEdgeIt() { }
klao@946
    79
klao@946
    80
      OutEdgeIt(Invalid i) : Edge(i) { }
klao@946
    81
klao@946
    82
      OutEdgeIt(const Graph& _graph, const Node& node) 
klao@962
    83
	: graph(&_graph) {
klao@946
    84
	_graph.firstOut(*this, node);
klao@946
    85
      }
klao@946
    86
klao@946
    87
      OutEdgeIt(const Graph& _graph, const Edge& edge) 
klao@946
    88
	: Edge(edge), graph(&_graph) {}
klao@946
    89
klao@946
    90
      OutEdgeIt& operator++() { 
klao@946
    91
	graph->nextOut(*this);
klao@946
    92
	return *this; 
klao@946
    93
      }
klao@946
    94
klao@946
    95
    };
klao@946
    96
klao@946
    97
klao@946
    98
    class InEdgeIt : public Edge { 
klao@946
    99
      const Graph* graph;
klao@946
   100
    public:
klao@946
   101
klao@946
   102
      InEdgeIt() { }
klao@946
   103
klao@946
   104
      InEdgeIt(Invalid i) : Edge(i) { }
klao@946
   105
klao@946
   106
      InEdgeIt(const Graph& _graph, const Node& node) 
klao@962
   107
	: graph(&_graph) {
klao@946
   108
	_graph.firstIn(*this, node);
klao@946
   109
      }
klao@946
   110
klao@946
   111
      InEdgeIt(const Graph& _graph, const Edge& edge) : 
klao@946
   112
	Edge(edge), graph(&_graph) {}
klao@946
   113
klao@946
   114
      InEdgeIt& operator++() { 
klao@946
   115
	graph->nextIn(*this);
klao@946
   116
	return *this; 
klao@946
   117
      }
klao@946
   118
klao@946
   119
    };
klao@946
   120
deba@1627
   121
    /// \brief Base node of the iterator
klao@1158
   122
    ///
klao@1158
   123
    /// Returns the base node (ie. the source in this case) of the iterator
klao@1158
   124
    Node baseNode(const OutEdgeIt &e) const {
deba@1564
   125
      return Parent::source((Edge)e);
klao@1158
   126
    }
deba@1627
   127
    /// \brief Running node of the iterator
klao@1158
   128
    ///
klao@1158
   129
    /// Returns the running node (ie. the target in this case) of the
klao@1158
   130
    /// iterator
klao@1158
   131
    Node runningNode(const OutEdgeIt &e) const {
deba@1564
   132
      return Parent::target((Edge)e);
klao@1158
   133
    }
klao@1158
   134
deba@1627
   135
    /// \brief Base node of the iterator
klao@1158
   136
    ///
klao@1158
   137
    /// Returns the base node (ie. the target in this case) of the iterator
klao@1158
   138
    Node baseNode(const InEdgeIt &e) const {
deba@1564
   139
      return Parent::target((Edge)e);
klao@1158
   140
    }
deba@1627
   141
    /// \brief Running node of the iterator
klao@1158
   142
    ///
klao@1158
   143
    /// Returns the running node (ie. the source in this case) of the
klao@1158
   144
    /// iterator
klao@1158
   145
    Node runningNode(const InEdgeIt &e) const {
deba@1564
   146
      return Parent::source((Edge)e);
klao@1158
   147
    }
klao@1158
   148
klao@946
   149
    using Parent::first;
klao@946
   150
deba@1627
   151
    /// \brief The opposite node on the given edge.
deba@1627
   152
    ///
deba@1627
   153
    /// Gives back the opposite on the given edge.
deba@1627
   154
    Node oppositeNode(const Node& n, const Edge& e) const {
deba@1627
   155
      if (Parent::source(e) == n) {
deba@1627
   156
	return Parent::target(e);
deba@1627
   157
      } else {
deba@1627
   158
	return Parent::source(e);
deba@1627
   159
      }
deba@1627
   160
    }
deba@1627
   161
klao@946
   162
  private:
klao@946
   163
klao@1230
   164
    // void first(NodeIt &) const;
klao@1230
   165
    // void first(EdgeIt &) const;
klao@1230
   166
    // void first(OutEdgeIt &) const;
klao@1230
   167
    // void first(InEdgeIt &) const;
klao@946
   168
klao@946
   169
  };
klao@1158
   170
klao@1158
   171
klao@1158
   172
klao@1158
   173
klao@1158
   174
klao@946
   175
  
klao@962
   176
  template <typename _Base>
klao@962
   177
  class IterableUndirGraphExtender : public IterableGraphExtender<_Base> {
klao@962
   178
  public:
klao@962
   179
alpar@1448
   180
    /// Indicates that the graph is undirected.
alpar@1448
   181
alpar@1448
   182
    ///\todo Better name?
alpar@1448
   183
    ///
alpar@1448
   184
    ///\bug Should it be here?
alpar@1448
   185
    ///\bug Should be tested in the concept checker whether it is defined
alpar@1448
   186
    ///correctly.
alpar@1448
   187
    typedef True UndirTag;
alpar@1448
   188
klao@962
   189
    typedef IterableGraphExtender<_Base> Parent;
klao@962
   190
    typedef IterableUndirGraphExtender<_Base> Graph;
klao@1021
   191
    typedef typename Parent::Node Node;
deba@1627
   192
    typedef typename Parent::Edge Edge;
klao@962
   193
    typedef typename Parent::UndirEdge UndirEdge;
klao@962
   194
klao@1230
   195
    class UndirEdgeIt : public Parent::UndirEdge { 
klao@962
   196
      const Graph* graph;
klao@962
   197
    public:
klao@962
   198
klao@962
   199
      UndirEdgeIt() { }
klao@962
   200
klao@962
   201
      UndirEdgeIt(Invalid i) : UndirEdge(i) { }
klao@962
   202
klao@962
   203
      explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
klao@962
   204
	_graph.first(*static_cast<UndirEdge*>(this));
klao@962
   205
      }
klao@962
   206
klao@962
   207
      UndirEdgeIt(const Graph& _graph, const UndirEdge& e) : 
klao@962
   208
	UndirEdge(e), graph(&_graph) { }
klao@962
   209
klao@962
   210
      UndirEdgeIt& operator++() { 
klao@962
   211
	graph->next(*this);
klao@962
   212
	return *this; 
klao@962
   213
      }
klao@962
   214
klao@962
   215
    };
klao@962
   216
klao@1230
   217
    class IncEdgeIt : public Parent::UndirEdge { 
klao@1021
   218
      const Graph* graph;
deba@1704
   219
      bool direction;
klao@1021
   220
      friend class IterableUndirGraphExtender;
klao@1021
   221
    public:
klao@1021
   222
klao@1030
   223
      IncEdgeIt() { }
klao@1021
   224
deba@1704
   225
      IncEdgeIt(Invalid i) : UndirEdge(i), direction(false) { }
klao@1021
   226
deba@1704
   227
      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
deba@1704
   228
	_graph.firstInc(*this, direction, n);
klao@1021
   229
      }
klao@1021
   230
klao@1158
   231
      IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
deba@1704
   232
	: graph(&_graph), UndirEdge(ue) {
deba@1704
   233
	direction = (_graph.source(ue) == n);
klao@1158
   234
      }
klao@1021
   235
klao@1030
   236
      IncEdgeIt& operator++() {
deba@1704
   237
	graph->nextInc(*this, direction);
klao@1021
   238
	return *this; 
klao@1021
   239
      }
klao@1021
   240
    };
klao@1021
   241
klao@1158
   242
    using Parent::baseNode;
klao@1158
   243
    using Parent::runningNode;
klao@1158
   244
klao@1158
   245
    /// Base node of the iterator
klao@1158
   246
    ///
klao@1158
   247
    /// Returns the base node of the iterator
klao@1158
   248
    Node baseNode(const IncEdgeIt &e) const {
deba@1704
   249
      return e.direction ? source(e) : target(e);
klao@1021
   250
    }
klao@1158
   251
    /// Running node of the iterator
klao@1158
   252
    ///
klao@1158
   253
    /// Returns the running node of the iterator
klao@1158
   254
    Node runningNode(const IncEdgeIt &e) const {
deba@1704
   255
      return e.direction ? target(e) : source(e);
klao@1021
   256
    }
klao@1021
   257
deba@1627
   258
    /// \brief The opposite node on the given undirected edge.
deba@1627
   259
    ///
deba@1627
   260
    /// Gives back the opposite on the given undirected edge.
deba@1627
   261
    Node oppositeNode(const Node& n, const UndirEdge& e) const {
deba@1627
   262
      if (Parent::source(e) == n) {
deba@1627
   263
	return Parent::target(e);
deba@1627
   264
      } else {
deba@1627
   265
	return Parent::source(e);
deba@1627
   266
      }
deba@1627
   267
    }
deba@1627
   268
klao@962
   269
  };
deba@1820
   270
deba@1820
   271
deba@1820
   272
  template <typename _Base>
deba@1820
   273
  class IterableUndirBipartiteGraphExtender : public _Base {
deba@1820
   274
  public:
deba@1820
   275
    typedef _Base Parent;
deba@1820
   276
    typedef IterableUndirBipartiteGraphExtender Graph;
deba@1820
   277
   
deba@1820
   278
    typedef typename Parent::Node Node;
deba@1820
   279
    typedef typename Parent::UpperNode UpperNode;
deba@1820
   280
    typedef typename Parent::LowerNode LowerNode;
deba@1820
   281
    typedef typename Parent::Edge Edge;
deba@1820
   282
    typedef typename Parent::UndirEdge UndirEdge;
deba@1820
   283
  
deba@1820
   284
    class NodeIt : public Node { 
deba@1820
   285
      const Graph* graph;
deba@1820
   286
    public:
deba@1820
   287
    
deba@1820
   288
      NodeIt() { }
deba@1820
   289
    
deba@1820
   290
      NodeIt(Invalid i) : Node(INVALID) { }
deba@1820
   291
    
deba@1820
   292
      explicit NodeIt(const Graph& _graph) : graph(&_graph) {
deba@1820
   293
	graph->first(static_cast<Node&>(*this));
deba@1820
   294
      }
deba@1820
   295
deba@1820
   296
      NodeIt(const Graph& _graph, const Node& node) 
deba@1820
   297
	: Node(node), graph(&_graph) { }
deba@1820
   298
    
deba@1820
   299
      NodeIt& operator++() { 
deba@1820
   300
	graph->next(*this);
deba@1820
   301
	return *this; 
deba@1820
   302
      }
deba@1820
   303
deba@1820
   304
    };
deba@1820
   305
deba@1820
   306
    class UpperNodeIt : public Node { 
deba@1820
   307
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   308
      const Graph* graph;
deba@1820
   309
    public:
deba@1820
   310
    
deba@1820
   311
      UpperNodeIt() { }
deba@1820
   312
    
deba@1820
   313
      UpperNodeIt(Invalid i) : Node(INVALID) { }
deba@1820
   314
    
deba@1820
   315
      explicit UpperNodeIt(const Graph& _graph) : graph(&_graph) {
deba@1820
   316
	graph->firstUpper(static_cast<Node&>(*this));
deba@1820
   317
      }
deba@1820
   318
deba@1820
   319
      UpperNodeIt(const Graph& _graph, const Node& node) 
deba@1820
   320
	: Node(node), graph(&_graph) {}
deba@1820
   321
    
deba@1820
   322
      UpperNodeIt& operator++() { 
deba@1820
   323
	graph->nextUpper(*this);
deba@1820
   324
	return *this; 
deba@1820
   325
      }
deba@1820
   326
    };
deba@1820
   327
deba@1820
   328
    class LowerNodeIt : public Node { 
deba@1820
   329
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   330
      const Graph* graph;
deba@1820
   331
    public:
deba@1820
   332
    
deba@1820
   333
      LowerNodeIt() { }
deba@1820
   334
    
deba@1820
   335
      LowerNodeIt(Invalid i) : Node(INVALID) { }
deba@1820
   336
    
deba@1820
   337
      explicit LowerNodeIt(const Graph& _graph) : graph(&_graph) {
deba@1820
   338
	graph->firstLower(static_cast<Node&>(*this));
deba@1820
   339
      }
deba@1820
   340
deba@1820
   341
      LowerNodeIt(const Graph& _graph, const Node& node) 
deba@1820
   342
	: Node(node), graph(&_graph) {}
deba@1820
   343
    
deba@1820
   344
      LowerNodeIt& operator++() { 
deba@1820
   345
	graph->nextLower(*this);
deba@1820
   346
	return *this; 
deba@1820
   347
      }
deba@1820
   348
    };
deba@1820
   349
deba@1820
   350
    class EdgeIt : public Edge { 
deba@1820
   351
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   352
      const Graph* graph;
deba@1820
   353
    public:
deba@1820
   354
    
deba@1820
   355
      EdgeIt() { }
deba@1820
   356
    
deba@1820
   357
      EdgeIt(Invalid i) : Edge(INVALID) { }
deba@1820
   358
    
deba@1820
   359
      explicit EdgeIt(const Graph& _graph) : graph(&_graph) {
deba@1820
   360
	graph->first(static_cast<Edge&>(*this));
deba@1820
   361
      }
deba@1820
   362
deba@1820
   363
      EdgeIt(const Graph& _graph, const Edge& edge) 
deba@1820
   364
	: Edge(edge), graph(&_graph) { }
deba@1820
   365
    
deba@1820
   366
      EdgeIt& operator++() { 
deba@1820
   367
	graph->next(*this);
deba@1820
   368
	return *this; 
deba@1820
   369
      }
deba@1820
   370
deba@1820
   371
    };
deba@1820
   372
deba@1820
   373
    class UndirEdgeIt : public UndirEdge { 
deba@1820
   374
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   375
      const Graph* graph;
deba@1820
   376
    public:
deba@1820
   377
    
deba@1820
   378
      UndirEdgeIt() { }
deba@1820
   379
    
deba@1820
   380
      UndirEdgeIt(Invalid i) : UndirEdge(INVALID) { }
deba@1820
   381
    
deba@1820
   382
      explicit UndirEdgeIt(const Graph& _graph) : graph(&_graph) {
deba@1820
   383
	graph->first(static_cast<UndirEdge&>(*this));
deba@1820
   384
      }
deba@1820
   385
deba@1820
   386
      UndirEdgeIt(const Graph& _graph, const UndirEdge& edge) 
deba@1820
   387
	: UndirEdge(edge), graph(&_graph) { }
deba@1820
   388
    
deba@1820
   389
      UndirEdgeIt& operator++() { 
deba@1820
   390
	graph->next(*this);
deba@1820
   391
	return *this; 
deba@1820
   392
      }
deba@1820
   393
    };
deba@1820
   394
deba@1820
   395
    class OutEdgeIt : public Edge { 
deba@1820
   396
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   397
      const Graph* graph;
deba@1820
   398
    public:
deba@1820
   399
    
deba@1820
   400
      OutEdgeIt() { }
deba@1820
   401
    
deba@1820
   402
      OutEdgeIt(Invalid i) : Edge(i) { }
deba@1820
   403
    
deba@1820
   404
      OutEdgeIt(const Graph& _graph, const Node& node) 
deba@1820
   405
	: graph(&_graph) {
deba@1820
   406
	graph->firstOut(*this, node);
deba@1820
   407
      }
deba@1820
   408
    
deba@1820
   409
      OutEdgeIt(const Graph& _graph, const Edge& edge) 
deba@1820
   410
	: Edge(edge), graph(&_graph) {}
deba@1820
   411
    
deba@1820
   412
      OutEdgeIt& operator++() { 
deba@1820
   413
	graph->nextOut(*this);
deba@1820
   414
	return *this; 
deba@1820
   415
      }
deba@1820
   416
deba@1820
   417
    };
deba@1820
   418
deba@1820
   419
deba@1820
   420
    class InEdgeIt : public Edge { 
deba@1820
   421
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   422
      const Graph* graph;
deba@1820
   423
    public:
deba@1820
   424
    
deba@1820
   425
      InEdgeIt() { }
deba@1820
   426
    
deba@1820
   427
      InEdgeIt(Invalid i) : Edge(i) { }
deba@1820
   428
    
deba@1820
   429
      InEdgeIt(const Graph& _graph, const Node& node) 
deba@1820
   430
	: graph(&_graph) {
deba@1820
   431
	graph->firstIn(*this, node);
deba@1820
   432
      }
deba@1820
   433
    
deba@1820
   434
      InEdgeIt(const Graph& _graph, const Edge& edge) : 
deba@1820
   435
	Edge(edge), graph(&_graph) {}
deba@1820
   436
    
deba@1820
   437
      InEdgeIt& operator++() { 
deba@1820
   438
	graph->nextIn(*this);
deba@1820
   439
	return *this; 
deba@1820
   440
      }
deba@1820
   441
deba@1820
   442
    };
deba@1820
   443
  
deba@1820
   444
    /// \brief Base node of the iterator
deba@1820
   445
    ///
deba@1820
   446
    /// Returns the base node (ie. the source in this case) of the iterator
deba@1820
   447
    Node baseNode(const OutEdgeIt &e) const {
deba@1820
   448
      return Parent::source((Edge&)e);
deba@1820
   449
    }
deba@1820
   450
    /// \brief Running node of the iterator
deba@1820
   451
    ///
deba@1820
   452
    /// Returns the running node (ie. the target in this case) of the
deba@1820
   453
    /// iterator
deba@1820
   454
    Node runningNode(const OutEdgeIt &e) const {
deba@1820
   455
      return Parent::target((Edge&)e);
deba@1820
   456
    }
deba@1820
   457
  
deba@1820
   458
    /// \brief Base node of the iterator
deba@1820
   459
    ///
deba@1820
   460
    /// Returns the base node (ie. the target in this case) of the iterator
deba@1820
   461
    Node baseNode(const InEdgeIt &e) const {
deba@1820
   462
      return Parent::target((Edge&)e);
deba@1820
   463
    }
deba@1820
   464
    /// \brief Running node of the iterator
deba@1820
   465
    ///
deba@1820
   466
    /// Returns the running node (ie. the source in this case) of the
deba@1820
   467
    /// iterator
deba@1820
   468
    Node runningNode(const InEdgeIt &e) const {
deba@1820
   469
      return Parent::source((Edge&)e);
deba@1820
   470
    }
deba@1820
   471
  
deba@1820
   472
    class IncEdgeIt : public Parent::UndirEdge { 
deba@1820
   473
      friend class IterableUndirBipartiteGraphExtender;
deba@1820
   474
      const Graph* graph;
deba@1820
   475
      bool direction;
deba@1820
   476
    public:
deba@1820
   477
    
deba@1820
   478
      IncEdgeIt() { }
deba@1820
   479
    
deba@1820
   480
      IncEdgeIt(Invalid i) : UndirEdge(i), direction(true) { }
deba@1820
   481
    
deba@1820
   482
      IncEdgeIt(const Graph& _graph, const Node &n) : graph(&_graph) {
deba@1820
   483
	graph->firstInc(*this, direction, n);
deba@1820
   484
      }
deba@1820
   485
deba@1820
   486
      IncEdgeIt(const Graph& _graph, const UndirEdge &ue, const Node &n)
deba@1820
   487
	: graph(&_graph), UndirEdge(ue) {
deba@1820
   488
	direction = (graph->source(ue) == n);
deba@1820
   489
      }
deba@1820
   490
deba@1820
   491
      IncEdgeIt& operator++() {
deba@1820
   492
	graph->nextInc(*this, direction);
deba@1820
   493
	return *this; 
deba@1820
   494
      }
deba@1820
   495
    };
deba@1820
   496
  
deba@1820
   497
deba@1820
   498
    /// Base node of the iterator
deba@1820
   499
    ///
deba@1820
   500
    /// Returns the base node of the iterator
deba@1820
   501
    Node baseNode(const IncEdgeIt &e) const {
deba@1820
   502
      return e.direction ? source(e) : target(e);
deba@1820
   503
    }
deba@1820
   504
deba@1820
   505
    /// Running node of the iterator
deba@1820
   506
    ///
deba@1820
   507
    /// Returns the running node of the iterator
deba@1820
   508
    Node runningNode(const IncEdgeIt &e) const {
deba@1820
   509
      return e.direction ? target(e) : source(e);
deba@1820
   510
    }
deba@1820
   511
  
deba@1820
   512
  };
deba@1820
   513
klao@946
   514
}
klao@946
   515
klao@946
   516
#endif // LEMON_GRAPH_EXTENDER_H