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