lemon/edge_set.h
author deba
Mon, 06 Feb 2006 16:58:39 +0000
changeset 1962 c1c3a0fae8a1
parent 1956 a055123339d5
child 1979 c2992fd74dad
permissions -rw-r--r--
Bug fixes in ListEdgeSet
Added SmartEdgeSet
deba@1842
     1
/* -*- C++ -*-
deba@1842
     2
 *
alpar@1956
     3
 * This file is a part of LEMON, a generic C++ optimization library
alpar@1956
     4
 *
alpar@1956
     5
 * Copyright (C) 2003-2006
alpar@1956
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@1842
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@1842
     8
 *
deba@1842
     9
 * Permission to use, modify and distribute this software is granted
deba@1842
    10
 * provided that this copyright notice appears in all copies. For
deba@1842
    11
 * precise terms see the accompanying LICENSE file.
deba@1842
    12
 *
deba@1842
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@1842
    14
 * express or implied, and with no claim as to its suitability for any
deba@1842
    15
 * purpose.
deba@1842
    16
 *
deba@1842
    17
 */
deba@1842
    18
deba@1842
    19
#ifndef LEMON_EDGE_SET_H
deba@1842
    20
#define LEMON_EDGE_SET_H
deba@1842
    21
deba@1962
    22
#include <lemon/bits/erasable_graph_extender.h>
deba@1962
    23
#include <lemon/bits/clearable_graph_extender.h>
deba@1962
    24
#include <lemon/bits/extendable_graph_extender.h>
deba@1962
    25
#include <lemon/bits/iterable_graph_extender.h>
deba@1962
    26
#include <lemon/bits/alteration_notifier.h>
deba@1962
    27
#include <lemon/bits/default_map.h>
deba@1962
    28
#include <lemon/bits/graph_extender.h>
deba@1962
    29
deba@1842
    30
/// \ingroup graphs
deba@1842
    31
/// \file
deba@1842
    32
/// \brief EdgeSet classes.
deba@1842
    33
///
deba@1842
    34
/// Graphs which use another graph's node-set as own. 
deba@1842
    35
deba@1842
    36
namespace lemon {
deba@1842
    37
deba@1842
    38
  template <typename _Graph>
deba@1842
    39
  class ListEdgeSetBase {
deba@1842
    40
  public:
deba@1842
    41
deba@1842
    42
    typedef _Graph Graph;
deba@1842
    43
    typedef typename Graph::Node Node;
deba@1842
    44
    typedef typename Graph::NodeIt NodeIt;
deba@1842
    45
deba@1842
    46
  protected:
deba@1842
    47
deba@1842
    48
    struct NodeT {
deba@1842
    49
      int first_out, first_in;
deba@1842
    50
      NodeT() : first_out(-1), first_in(-1) {}
deba@1842
    51
    };
deba@1842
    52
deba@1842
    53
    typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
deba@1842
    54
deba@1842
    55
    NodesImplBase* nodes;
deba@1842
    56
deba@1842
    57
    struct EdgeT {
deba@1842
    58
      Node source, target;
deba@1842
    59
      int next_out, next_in;
deba@1842
    60
      int prev_out, prev_in;
deba@1842
    61
      EdgeT() : prev_out(-1), prev_in(-1) {}
deba@1842
    62
    };
deba@1842
    63
deba@1842
    64
    std::vector<EdgeT> edges;
deba@1842
    65
deba@1842
    66
    int first_edge;
deba@1842
    67
    int first_free_edge;
deba@1842
    68
deba@1842
    69
    const Graph* graph;
deba@1842
    70
deba@1842
    71
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1842
    72
      graph = &_graph;
deba@1842
    73
      nodes = &_nodes;
deba@1842
    74
    }
deba@1842
    75
    
deba@1842
    76
  public:
deba@1842
    77
deba@1842
    78
    class Edge {
deba@1842
    79
      friend class ListEdgeSetBase<Graph>;
deba@1842
    80
    protected:
deba@1842
    81
      Edge(int _id) : id(_id) {}
deba@1842
    82
      int id;
deba@1842
    83
    public:
deba@1842
    84
      Edge() {}
deba@1842
    85
      Edge(Invalid) : id(-1) {}
deba@1842
    86
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1842
    87
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1842
    88
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1842
    89
    };
deba@1842
    90
deba@1842
    91
    ListEdgeSetBase() : first_edge(-1), first_free_edge(-1) {} 
deba@1842
    92
deba@1842
    93
    Edge addEdge(const Node& source, const Node& target) {
deba@1842
    94
      int n;
deba@1842
    95
      if (first_free_edge == -1) {
deba@1842
    96
	n = edges.size();
deba@1842
    97
	edges.push_back(EdgeT());
deba@1842
    98
      } else {
deba@1842
    99
	n = first_free_edge;
deba@1842
   100
	first_free_edge = edges[first_free_edge].next_in;
deba@1842
   101
      }
deba@1842
   102
      edges[n].next_in = (*nodes)[target].first_in;
deba@1962
   103
      if ((*nodes)[target].first_in != -1) {
deba@1962
   104
        edges[(*nodes)[target].first_in].prev_in = n;
deba@1962
   105
      }
deba@1842
   106
      (*nodes)[target].first_in = n;
deba@1842
   107
      edges[n].next_out = (*nodes)[source].first_out;
deba@1962
   108
      if ((*nodes)[source].first_out != -1) {
deba@1962
   109
        edges[(*nodes)[source].first_out].prev_out = n;
deba@1962
   110
      }
deba@1842
   111
      (*nodes)[source].first_out = n;
deba@1842
   112
      edges[n].source = source;
deba@1842
   113
      edges[n].target = target;
deba@1842
   114
      return Edge(n);
deba@1842
   115
    }
deba@1842
   116
deba@1842
   117
    void erase(const Edge& edge) {
deba@1842
   118
      int n = edge.id;
deba@1842
   119
      if (edges[n].prev_in != -1) {
deba@1842
   120
	edges[edges[n].prev_in].next_in = edges[n].next_in;
deba@1842
   121
      } else {
deba@1842
   122
	(*nodes)[edges[n].target].first_in = edges[n].next_in;
deba@1842
   123
      }
deba@1842
   124
      if (edges[n].next_in != -1) {
deba@1842
   125
	edges[edges[n].next_in].prev_in = edges[n].prev_in;
deba@1842
   126
      }
deba@1842
   127
deba@1842
   128
      if (edges[n].prev_out != -1) {
deba@1842
   129
	edges[edges[n].prev_out].next_out = edges[n].next_out;
deba@1842
   130
      } else {
deba@1842
   131
	(*nodes)[edges[n].source].first_out = edges[n].next_out;
deba@1842
   132
      }
deba@1842
   133
      if (edges[n].next_out != -1) {
deba@1842
   134
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
deba@1842
   135
      }
deba@1842
   136
           
deba@1842
   137
    }
deba@1842
   138
deba@1842
   139
    void clear() {
deba@1962
   140
      Node node;
deba@1962
   141
      for (first(node); node != INVALID; next(node)) {
deba@1962
   142
        (*nodes)[node].first_in = -1;
deba@1962
   143
        (*nodes)[node].first_out = -1;
deba@1962
   144
      }
deba@1842
   145
      edges.clear();
deba@1842
   146
      first_edge = -1;
deba@1842
   147
      first_free_edge = -1;
deba@1842
   148
    }
deba@1842
   149
deba@1842
   150
    void first(Node& node) const {
deba@1842
   151
      graph->first(node);
deba@1842
   152
    }
deba@1842
   153
deba@1842
   154
    void next(Node& node) const {
deba@1842
   155
      graph->next(node);
deba@1842
   156
    }
deba@1842
   157
deba@1842
   158
    void first(Edge& edge) const {
deba@1842
   159
      Node node;
deba@1842
   160
      for (first(node); node != INVALID && (*nodes)[node].first_in == -1; 
deba@1842
   161
	   next(node));
deba@1842
   162
      edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
deba@1842
   163
    }
deba@1842
   164
deba@1842
   165
    void next(Edge& edge) const {
deba@1842
   166
      if (edges[edge.id].next_in != -1) {
deba@1842
   167
	edge.id = edges[edge.id].next_in;
deba@1842
   168
      } else {
deba@1842
   169
	Node node = edges[edge.id].target;
deba@1842
   170
	for (next(node); node != INVALID && (*nodes)[node].first_in == -1; 
deba@1842
   171
	     next(node));
deba@1842
   172
	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_in;
deba@1842
   173
      }      
deba@1842
   174
    }
deba@1842
   175
deba@1842
   176
    void firstOut(Edge& edge, const Node& node) const {
deba@1842
   177
      edge.id = (*nodes)[node].first_out;    
deba@1842
   178
    }
deba@1842
   179
    
deba@1842
   180
    void nextOut(Edge& edge) const {
deba@1842
   181
      edge.id = edges[edge.id].next_out;        
deba@1842
   182
    }
deba@1842
   183
deba@1842
   184
    void firstIn(Edge& edge, const Node& node) const {
deba@1842
   185
      edge.id = (*nodes)[node].first_in;          
deba@1842
   186
    }
deba@1842
   187
deba@1842
   188
    void nextIn(Edge& edge) const {
deba@1842
   189
      edge.id = edges[edge.id].next_in;    
deba@1842
   190
    }
deba@1842
   191
deba@1842
   192
    int id(const Node& node) const { return graph->id(node); }
deba@1842
   193
    int id(const Edge& edge) const { return edge.id; }
deba@1842
   194
deba@1962
   195
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@1842
   196
    Edge edgeFromId(int id) const { return Edge(id); }
deba@1842
   197
deba@1962
   198
    int maxNodeId() const { return graph->maxNodeId(); };
deba@1842
   199
    int maxEdgeId() const { return edges.size() - 1; }
deba@1842
   200
deba@1842
   201
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1842
   202
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1842
   203
deba@1842
   204
    template <typename _Value>
deba@1842
   205
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1842
   206
    public:
deba@1842
   207
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@1842
   208
      explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset) 
deba@1842
   209
	: Parent(*edgeset.graph) { }
deba@1842
   210
      NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1842
   211
	: Parent(*edgeset.graph, value) { }
deba@1842
   212
    };
deba@1842
   213
deba@1842
   214
  };
deba@1842
   215
deba@1866
   216
  /// \ingroup semi_adaptors
deba@1842
   217
  ///
deba@1842
   218
  /// \brief Graph using a node set of another graph and an
deba@1842
   219
  /// own edge set.
deba@1842
   220
  ///
deba@1842
   221
  /// This structure can be used to establish another graph over a node set
deba@1842
   222
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   223
  /// original graph.
deba@1842
   224
  ///
deba@1842
   225
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   226
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   227
  /// "StaticGraph" concept.
deba@1842
   228
  ///
deba@1842
   229
  /// In the edge extension and removing it conforms to the 
deba@1962
   230
  /// \ref concept::ErasableGraph "ErasableGraph" concept.
deba@1842
   231
  template <typename _Graph>
deba@1842
   232
  class ListEdgeSet :
deba@1842
   233
    public ErasableEdgeSetExtender<
deba@1842
   234
    ClearableEdgeSetExtender<
deba@1842
   235
    ExtendableEdgeSetExtender<
deba@1842
   236
    MappableEdgeSetExtender<
deba@1842
   237
    IterableGraphExtender<
deba@1842
   238
    AlterableEdgeSetExtender<
deba@1842
   239
    GraphExtender<
deba@1842
   240
    ListEdgeSetBase<_Graph> > > > > > > > {
deba@1842
   241
deba@1842
   242
  public:
deba@1842
   243
deba@1842
   244
    typedef ErasableEdgeSetExtender<
deba@1842
   245
      ClearableEdgeSetExtender<
deba@1842
   246
      ExtendableEdgeSetExtender<
deba@1842
   247
      MappableEdgeSetExtender<
deba@1842
   248
      IterableGraphExtender<
deba@1842
   249
      AlterableEdgeSetExtender<
deba@1842
   250
      GraphExtender<
deba@1842
   251
      ListEdgeSetBase<_Graph> > > > > > > > Parent;
deba@1842
   252
    
deba@1842
   253
    typedef typename Parent::Node Node;
deba@1842
   254
    typedef typename Parent::Edge Edge;
deba@1842
   255
    
deba@1842
   256
    typedef _Graph Graph;
deba@1842
   257
deba@1842
   258
deba@1842
   259
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   260
deba@1842
   261
    void eraseNode(const Node& node) {
deba@1842
   262
      Edge edge;
deba@1842
   263
      Parent::firstOut(edge, node);
deba@1842
   264
      while (edge != INVALID ) {
deba@1842
   265
	erase(edge);
deba@1842
   266
	Parent::firstOut(edge, node);
deba@1842
   267
      } 
deba@1842
   268
deba@1842
   269
      Parent::firstIn(edge, node);
deba@1842
   270
      while (edge != INVALID ) {
deba@1842
   271
	erase(edge);
deba@1842
   272
	Parent::firstIn(edge, node);
deba@1842
   273
      }
deba@1842
   274
    }
deba@1842
   275
    
deba@1842
   276
    void clearNodes() {
deba@1842
   277
      Parent::clear();
deba@1842
   278
    }
deba@1842
   279
deba@1842
   280
    class NodesImpl : public NodesImplBase {
deba@1842
   281
    public:
deba@1842
   282
      typedef NodesImplBase Parent;
deba@1842
   283
      
deba@1842
   284
      NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
deba@1842
   285
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   286
deba@1962
   287
      virtual ~NodesImpl() {}
deba@1842
   288
      
deba@1842
   289
    protected:
deba@1842
   290
deba@1842
   291
      virtual void erase(const Node& node) {
deba@1842
   292
	_edgeset.eraseNode(node);
deba@1842
   293
	Parent::erase(node);
deba@1842
   294
      }
deba@1962
   295
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   296
        for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   297
          _edgeset.eraseNode(nodes[i]);
deba@1962
   298
        }
deba@1962
   299
	Parent::erase(nodes);
deba@1962
   300
      }
deba@1842
   301
      virtual void clear() {
deba@1842
   302
	_edgeset.clearNodes();
deba@1842
   303
	Parent::clear();
deba@1842
   304
      }
deba@1842
   305
deba@1842
   306
    private:
deba@1842
   307
      ListEdgeSet& _edgeset;
deba@1842
   308
    };
deba@1842
   309
deba@1842
   310
    NodesImpl nodes;
deba@1842
   311
    
deba@1842
   312
  public:
deba@1842
   313
deba@1842
   314
    /// \brief Constructor of the adaptor.
deba@1842
   315
    /// 
deba@1842
   316
    /// Constructor of the adaptor.
deba@1842
   317
    ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   318
      Parent::initalize(graph, nodes);
deba@1842
   319
    }
deba@1842
   320
    
deba@1842
   321
  };
deba@1842
   322
deba@1866
   323
  /// \ingroup semi_adaptors
deba@1842
   324
  ///
deba@1842
   325
  /// \brief Graph using a node set of another graph and an
klao@1909
   326
  /// own uedge set.
deba@1842
   327
  ///
deba@1842
   328
  /// This structure can be used to establish another graph over a node set
deba@1842
   329
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   330
  /// original graph.
deba@1842
   331
  ///
deba@1842
   332
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   333
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   334
  /// "StaticGraph" concept.
deba@1842
   335
  ///
deba@1842
   336
  /// In the edge extension and removing it conforms to the 
deba@1962
   337
  /// \ref concept::ErasableUGraph "ErasableUGraph" concept.
deba@1842
   338
  template <typename _Graph>
klao@1909
   339
  class ListUEdgeSet :
klao@1909
   340
    public ErasableUEdgeSetExtender<
klao@1909
   341
    ClearableUEdgeSetExtender<
klao@1909
   342
    ExtendableUEdgeSetExtender<
klao@1909
   343
    MappableUEdgeSetExtender<
klao@1909
   344
    IterableUGraphExtender<
klao@1909
   345
    AlterableUEdgeSetExtender<
klao@1909
   346
    UGraphExtender<
deba@1842
   347
    ListEdgeSetBase<_Graph> > > > > > > > {
deba@1842
   348
deba@1842
   349
  public:
deba@1842
   350
klao@1909
   351
    typedef ErasableUEdgeSetExtender<
klao@1909
   352
      ClearableUEdgeSetExtender<
klao@1909
   353
      ExtendableUEdgeSetExtender<
klao@1909
   354
      MappableUEdgeSetExtender<
klao@1909
   355
      IterableUGraphExtender<
klao@1909
   356
      AlterableUEdgeSetExtender<
klao@1909
   357
      UGraphExtender<
deba@1842
   358
      ListEdgeSetBase<_Graph> > > > > > > > Parent;
deba@1842
   359
    
deba@1842
   360
    typedef typename Parent::Node Node;
deba@1842
   361
    typedef typename Parent::Edge Edge;
deba@1842
   362
    
deba@1842
   363
    typedef _Graph Graph;
deba@1842
   364
deba@1842
   365
deba@1842
   366
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   367
deba@1842
   368
    void eraseNode(const Node& node) {
deba@1842
   369
      Edge edge;
deba@1842
   370
      Parent::firstOut(edge, node);
deba@1842
   371
      while (edge != INVALID ) {
deba@1842
   372
	erase(edge);
deba@1842
   373
	Parent::firstOut(edge, node);
deba@1842
   374
      } 
deba@1842
   375
deba@1842
   376
    }
deba@1842
   377
    
deba@1842
   378
    void clearNodes() {
deba@1842
   379
      Parent::clear();
deba@1842
   380
    }
deba@1842
   381
deba@1842
   382
    class NodesImpl : public NodesImplBase {
deba@1842
   383
    public:
deba@1842
   384
      typedef NodesImplBase Parent;
deba@1842
   385
      
klao@1909
   386
      NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
deba@1842
   387
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   388
deba@1962
   389
      virtual ~NodesImpl() {}
deba@1842
   390
      
deba@1842
   391
    protected:
deba@1842
   392
deba@1842
   393
      virtual void erase(const Node& node) {
deba@1842
   394
	_edgeset.eraseNode(node);
deba@1842
   395
	Parent::erase(node);
deba@1842
   396
      }
deba@1866
   397
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   398
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1866
   399
	  _edgeset.eraseNode(nodes[i]);
deba@1866
   400
	}
deba@1866
   401
	Parent::erase(nodes);
deba@1866
   402
      }
deba@1842
   403
      virtual void clear() {
deba@1842
   404
	_edgeset.clearNodes();
deba@1842
   405
	Parent::clear();
deba@1842
   406
      }
deba@1842
   407
deba@1842
   408
    private:
klao@1909
   409
      ListUEdgeSet& _edgeset;
deba@1842
   410
    };
deba@1842
   411
deba@1842
   412
    NodesImpl nodes;
deba@1842
   413
    
deba@1842
   414
  public:
deba@1842
   415
deba@1842
   416
    /// \brief Constructor of the adaptor.
deba@1842
   417
    /// 
deba@1842
   418
    /// Constructor of the adaptor.
klao@1909
   419
    ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   420
      Parent::initalize(graph, nodes);
deba@1842
   421
    }
deba@1842
   422
    
deba@1842
   423
  };
deba@1842
   424
deba@1962
   425
  template <typename _Graph>
deba@1962
   426
  class SmartEdgeSetBase {
deba@1962
   427
  public:
deba@1962
   428
deba@1962
   429
    typedef _Graph Graph;
deba@1962
   430
    typedef typename Graph::Node Node;
deba@1962
   431
    typedef typename Graph::NodeIt NodeIt;
deba@1962
   432
deba@1962
   433
  protected:
deba@1962
   434
deba@1962
   435
    struct NodeT {
deba@1962
   436
      int first_out, first_in;
deba@1962
   437
      NodeT() : first_out(-1), first_in(-1) {}
deba@1962
   438
    };
deba@1962
   439
deba@1962
   440
    typedef typename Graph::template NodeMap<NodeT> NodesImplBase;
deba@1962
   441
deba@1962
   442
    NodesImplBase* nodes;
deba@1962
   443
deba@1962
   444
    struct EdgeT {
deba@1962
   445
      Node source, target;
deba@1962
   446
      int next_out, next_in;
deba@1962
   447
      EdgeT() {}
deba@1962
   448
    };
deba@1962
   449
deba@1962
   450
    std::vector<EdgeT> edges;
deba@1962
   451
deba@1962
   452
    const Graph* graph;
deba@1962
   453
deba@1962
   454
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1962
   455
      graph = &_graph;
deba@1962
   456
      nodes = &_nodes;
deba@1962
   457
    }
deba@1962
   458
    
deba@1962
   459
  public:
deba@1962
   460
deba@1962
   461
    class Edge {
deba@1962
   462
      friend class SmartEdgeSetBase<Graph>;
deba@1962
   463
    protected:
deba@1962
   464
      Edge(int _id) : id(_id) {}
deba@1962
   465
      int id;
deba@1962
   466
    public:
deba@1962
   467
      Edge() {}
deba@1962
   468
      Edge(Invalid) : id(-1) {}
deba@1962
   469
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1962
   470
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1962
   471
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1962
   472
    };
deba@1962
   473
deba@1962
   474
    SmartEdgeSetBase() {} 
deba@1962
   475
deba@1962
   476
    Edge addEdge(const Node& source, const Node& target) {
deba@1962
   477
      int n = edges.size();
deba@1962
   478
      edges.push_back(EdgeT());
deba@1962
   479
      edges[n].next_in = (*nodes)[target].first_in;
deba@1962
   480
      (*nodes)[target].first_in = n;
deba@1962
   481
      edges[n].next_out = (*nodes)[source].first_out;
deba@1962
   482
      (*nodes)[source].first_out = n;
deba@1962
   483
      edges[n].source = source;
deba@1962
   484
      edges[n].target = target;
deba@1962
   485
      return Edge(n);
deba@1962
   486
    }
deba@1962
   487
deba@1962
   488
    void clear() {
deba@1962
   489
      Node node;
deba@1962
   490
      for (first(node); node != INVALID; next(node)) {
deba@1962
   491
        (*nodes)[node].first_in = -1;
deba@1962
   492
        (*nodes)[node].first_out = -1;
deba@1962
   493
      }
deba@1962
   494
      edges.clear();
deba@1962
   495
    }
deba@1962
   496
deba@1962
   497
    void first(Node& node) const {
deba@1962
   498
      graph->first(node);
deba@1962
   499
    }
deba@1962
   500
deba@1962
   501
    void next(Node& node) const {
deba@1962
   502
      graph->next(node);
deba@1962
   503
    }
deba@1962
   504
deba@1962
   505
    void first(Edge& edge) const {
deba@1962
   506
      edge.id = edges.size() - 1;
deba@1962
   507
    }
deba@1962
   508
deba@1962
   509
    void next(Edge& edge) const {
deba@1962
   510
      --edge.id;
deba@1962
   511
    }
deba@1962
   512
deba@1962
   513
    void firstOut(Edge& edge, const Node& node) const {
deba@1962
   514
      edge.id = (*nodes)[node].first_out;    
deba@1962
   515
    }
deba@1962
   516
    
deba@1962
   517
    void nextOut(Edge& edge) const {
deba@1962
   518
      edge.id = edges[edge.id].next_out;        
deba@1962
   519
    }
deba@1962
   520
deba@1962
   521
    void firstIn(Edge& edge, const Node& node) const {
deba@1962
   522
      edge.id = (*nodes)[node].first_in;          
deba@1962
   523
    }
deba@1962
   524
deba@1962
   525
    void nextIn(Edge& edge) const {
deba@1962
   526
      edge.id = edges[edge.id].next_in;    
deba@1962
   527
    }
deba@1962
   528
deba@1962
   529
    int id(const Node& node) const { return graph->id(node); }
deba@1962
   530
    int id(const Edge& edge) const { return edge.id; }
deba@1962
   531
deba@1962
   532
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@1962
   533
    Edge edgeFromId(int id) const { return Edge(id); }
deba@1962
   534
deba@1962
   535
    int maxNodeId() const { return graph->maxNodeId(); };
deba@1962
   536
    int maxEdgeId() const { return edges.size() - 1; }
deba@1962
   537
deba@1962
   538
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1962
   539
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1962
   540
deba@1962
   541
    template <typename _Value>
deba@1962
   542
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1962
   543
    public:
deba@1962
   544
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@1962
   545
      explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset) 
deba@1962
   546
	: Parent(*edgeset.graph) { }
deba@1962
   547
      NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1962
   548
	: Parent(*edgeset.graph, value) { }
deba@1962
   549
    };
deba@1962
   550
deba@1962
   551
  };
deba@1962
   552
deba@1962
   553
deba@1962
   554
  /// \ingroup semi_adaptors
deba@1962
   555
  ///
deba@1962
   556
  /// \brief Graph using a node set of another graph and an
deba@1962
   557
  /// own edge set.
deba@1962
   558
  ///
deba@1962
   559
  /// This structure can be used to establish another graph over a node set
deba@1962
   560
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   561
  /// original graph.
deba@1962
   562
  ///
deba@1962
   563
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   564
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   565
  /// "StaticGraph" concept.
deba@1962
   566
  ///
deba@1962
   567
  /// In the edge extension and removing it conforms to the 
deba@1962
   568
  /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
deba@1962
   569
  template <typename _Graph>
deba@1962
   570
  class SmartEdgeSet :
deba@1962
   571
    public ClearableEdgeSetExtender<
deba@1962
   572
    ExtendableEdgeSetExtender<
deba@1962
   573
    MappableEdgeSetExtender<
deba@1962
   574
    IterableGraphExtender<
deba@1962
   575
    AlterableEdgeSetExtender<
deba@1962
   576
    GraphExtender<
deba@1962
   577
    SmartEdgeSetBase<_Graph> > > > > > > {
deba@1962
   578
deba@1962
   579
  public:
deba@1962
   580
deba@1962
   581
    typedef ClearableEdgeSetExtender<
deba@1962
   582
      ExtendableEdgeSetExtender<
deba@1962
   583
      MappableEdgeSetExtender<
deba@1962
   584
      IterableGraphExtender<
deba@1962
   585
      AlterableEdgeSetExtender<
deba@1962
   586
      GraphExtender<
deba@1962
   587
      SmartEdgeSetBase<_Graph> > > > > > > Parent;
deba@1962
   588
    
deba@1962
   589
    typedef typename Parent::Node Node;
deba@1962
   590
    typedef typename Parent::Edge Edge;
deba@1962
   591
    
deba@1962
   592
    typedef _Graph Graph;
deba@1962
   593
deba@1962
   594
    class UnsupportedOperation : public LogicError {
deba@1962
   595
    public:
deba@1962
   596
      virtual const char* exceptionName() const {
deba@1962
   597
        return "lemon::SmartEdgeSet::UnsupportedOperation";
deba@1962
   598
      }
deba@1962
   599
    };
deba@1962
   600
    
deba@1962
   601
deba@1962
   602
deba@1962
   603
  protected:
deba@1962
   604
deba@1962
   605
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   606
deba@1962
   607
    void eraseNode(const Node&) {
deba@1962
   608
      throw UnsupportedOperation();
deba@1962
   609
    }
deba@1962
   610
    
deba@1962
   611
    void clearNodes() {
deba@1962
   612
      Parent::clear();
deba@1962
   613
    }
deba@1962
   614
deba@1962
   615
    class NodesImpl : public NodesImplBase {
deba@1962
   616
    public:
deba@1962
   617
      typedef NodesImplBase Parent;
deba@1962
   618
      
deba@1962
   619
      NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
deba@1962
   620
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   621
deba@1962
   622
      virtual ~NodesImpl() {}
deba@1962
   623
      
deba@1962
   624
    protected:
deba@1962
   625
deba@1962
   626
      virtual void erase(const Node& node) {
deba@1962
   627
	_edgeset.eraseNode(node);
deba@1962
   628
	Parent::erase(node);
deba@1962
   629
      }
deba@1962
   630
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   631
        for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   632
          _edgeset.eraseNode(nodes[i]);
deba@1962
   633
        }
deba@1962
   634
	Parent::erase(nodes);
deba@1962
   635
      }
deba@1962
   636
      virtual void clear() {
deba@1962
   637
	_edgeset.clearNodes();
deba@1962
   638
	Parent::clear();
deba@1962
   639
      }
deba@1962
   640
deba@1962
   641
    private:
deba@1962
   642
      SmartEdgeSet& _edgeset;
deba@1962
   643
    };
deba@1962
   644
deba@1962
   645
    NodesImpl nodes;
deba@1962
   646
    
deba@1962
   647
  public:
deba@1962
   648
deba@1962
   649
    /// \brief Constructor of the adaptor.
deba@1962
   650
    /// 
deba@1962
   651
    /// Constructor of the adaptor.
deba@1962
   652
    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   653
      Parent::initalize(graph, nodes);
deba@1962
   654
    }
deba@1962
   655
    
deba@1962
   656
  };
deba@1962
   657
deba@1962
   658
  /// \ingroup semi_adaptors
deba@1962
   659
  ///
deba@1962
   660
  /// \brief Graph using a node set of another graph and an
deba@1962
   661
  /// own uedge set.
deba@1962
   662
  ///
deba@1962
   663
  /// This structure can be used to establish another graph over a node set
deba@1962
   664
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   665
  /// original graph.
deba@1962
   666
  ///
deba@1962
   667
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   668
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   669
  /// "StaticGraph" concept.
deba@1962
   670
  ///
deba@1962
   671
  /// In the edge extension and removing it conforms to the 
deba@1962
   672
  /// \ref concept::ExtendableUGraph "ExtendableUGraph" concept.
deba@1962
   673
  template <typename _Graph>
deba@1962
   674
  class SmartUEdgeSet :
deba@1962
   675
    public ClearableUEdgeSetExtender<
deba@1962
   676
    ExtendableUEdgeSetExtender<
deba@1962
   677
    MappableUEdgeSetExtender<
deba@1962
   678
    IterableUGraphExtender<
deba@1962
   679
    AlterableUEdgeSetExtender<
deba@1962
   680
    UGraphExtender<
deba@1962
   681
    SmartEdgeSetBase<_Graph> > > > > > > {
deba@1962
   682
deba@1962
   683
  public:
deba@1962
   684
deba@1962
   685
    typedef ClearableUEdgeSetExtender<
deba@1962
   686
      ExtendableUEdgeSetExtender<
deba@1962
   687
      MappableUEdgeSetExtender<
deba@1962
   688
      IterableUGraphExtender<
deba@1962
   689
      AlterableUEdgeSetExtender<
deba@1962
   690
      UGraphExtender<
deba@1962
   691
      SmartEdgeSetBase<_Graph> > > > > > > Parent;
deba@1962
   692
    
deba@1962
   693
    typedef typename Parent::Node Node;
deba@1962
   694
    typedef typename Parent::Edge Edge;
deba@1962
   695
    
deba@1962
   696
    typedef _Graph Graph;
deba@1962
   697
deba@1962
   698
    class UnsupportedOperation : public LogicError {
deba@1962
   699
    public:
deba@1962
   700
      virtual const char* exceptionName() const {
deba@1962
   701
        return "lemon::SmartUEdgeSet::UnsupportedOperation";
deba@1962
   702
      }
deba@1962
   703
    };
deba@1962
   704
deba@1962
   705
  protected:
deba@1962
   706
deba@1962
   707
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   708
deba@1962
   709
    void eraseNode(const Node&) {
deba@1962
   710
      throw UnsupportedOperation();
deba@1962
   711
    }
deba@1962
   712
    
deba@1962
   713
    void clearNodes() {
deba@1962
   714
      Parent::clear();
deba@1962
   715
    }
deba@1962
   716
deba@1962
   717
    class NodesImpl : public NodesImplBase {
deba@1962
   718
    public:
deba@1962
   719
      typedef NodesImplBase Parent;
deba@1962
   720
      
deba@1962
   721
      NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
deba@1962
   722
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   723
deba@1962
   724
      virtual ~NodesImpl() {}
deba@1962
   725
      
deba@1962
   726
    protected:
deba@1962
   727
deba@1962
   728
      virtual void erase(const Node& node) {
deba@1962
   729
	_edgeset.eraseNode(node);
deba@1962
   730
	Parent::erase(node);
deba@1962
   731
      }
deba@1962
   732
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   733
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   734
	  _edgeset.eraseNode(nodes[i]);
deba@1962
   735
	}
deba@1962
   736
	Parent::erase(nodes);
deba@1962
   737
      }
deba@1962
   738
      virtual void clear() {
deba@1962
   739
	_edgeset.clearNodes();
deba@1962
   740
	Parent::clear();
deba@1962
   741
      }
deba@1962
   742
deba@1962
   743
    private:
deba@1962
   744
      SmartUEdgeSet& _edgeset;
deba@1962
   745
    };
deba@1962
   746
deba@1962
   747
    NodesImpl nodes;
deba@1962
   748
    
deba@1962
   749
  public:
deba@1962
   750
deba@1962
   751
    /// \brief Constructor of the adaptor.
deba@1962
   752
    /// 
deba@1962
   753
    /// Constructor of the adaptor.
deba@1962
   754
    SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   755
      Parent::initalize(graph, nodes);
deba@1962
   756
    }
deba@1962
   757
    
deba@1962
   758
  };
deba@1962
   759
deba@1842
   760
}
deba@1842
   761
deba@1842
   762
#endif