lemon/edge_set.h
author alpar
Wed, 15 Mar 2006 09:44:17 +0000
changeset 2006 00d59f733817
parent 1990 15fb7a4ea6be
child 2031 080d51024ac5
permissions -rw-r--r--
Spellcheck
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@1999
   574
    void eraseNode(const Node& node) {
deba@1999
   575
      if (Parent::InEdgeIt(*this, node) == INVALID &&
deba@1999
   576
          Parent::OutEdgeIt(*this, node) == INVALID) {
deba@1999
   577
        return;
deba@1999
   578
      }
deba@1962
   579
      throw UnsupportedOperation();
deba@1962
   580
    }
deba@1962
   581
    
deba@1962
   582
    void clearNodes() {
deba@1962
   583
      Parent::clear();
deba@1962
   584
    }
deba@1962
   585
deba@1962
   586
    class NodesImpl : public NodesImplBase {
deba@1962
   587
    public:
deba@1962
   588
      typedef NodesImplBase Parent;
deba@1962
   589
      
deba@1962
   590
      NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
deba@1962
   591
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   592
deba@1962
   593
      virtual ~NodesImpl() {}
deba@1962
   594
      
deba@1962
   595
    protected:
deba@1962
   596
deba@1962
   597
      virtual void erase(const Node& node) {
deba@1962
   598
	_edgeset.eraseNode(node);
deba@1962
   599
	Parent::erase(node);
deba@1962
   600
      }
deba@1962
   601
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   602
        for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   603
          _edgeset.eraseNode(nodes[i]);
deba@1962
   604
        }
deba@1962
   605
	Parent::erase(nodes);
deba@1962
   606
      }
deba@1962
   607
      virtual void clear() {
deba@1962
   608
	_edgeset.clearNodes();
deba@1962
   609
	Parent::clear();
deba@1962
   610
      }
deba@1962
   611
deba@1962
   612
    private:
deba@1962
   613
      SmartEdgeSet& _edgeset;
deba@1962
   614
    };
deba@1962
   615
deba@1962
   616
    NodesImpl nodes;
deba@1962
   617
    
deba@1962
   618
  public:
deba@1962
   619
deba@1962
   620
    /// \brief Constructor of the adaptor.
deba@1962
   621
    /// 
deba@1962
   622
    /// Constructor of the adaptor.
deba@1962
   623
    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   624
      Parent::initalize(graph, nodes);
deba@1962
   625
    }
deba@1962
   626
    
deba@1962
   627
  };
deba@1962
   628
deba@1962
   629
  /// \ingroup semi_adaptors
deba@1962
   630
  ///
deba@1962
   631
  /// \brief Graph using a node set of another graph and an
deba@1962
   632
  /// own uedge set.
deba@1962
   633
  ///
deba@1962
   634
  /// This structure can be used to establish another graph over a node set
deba@1962
   635
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   636
  /// original graph.
deba@1962
   637
  ///
deba@1962
   638
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   639
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   640
  /// "StaticGraph" concept.
deba@1962
   641
  ///
deba@1962
   642
  /// In the edge extension and removing it conforms to the 
deba@1962
   643
  /// \ref concept::ExtendableUGraph "ExtendableUGraph" concept.
deba@1962
   644
  template <typename _Graph>
deba@1979
   645
  class SmartUEdgeSet 
deba@1979
   646
    : public UEdgeSetExtender<UGraphBaseExtender<SmartEdgeSetBase<_Graph> > > {
deba@1962
   647
deba@1962
   648
  public:
deba@1962
   649
deba@1979
   650
    typedef UEdgeSetExtender<UGraphBaseExtender<
deba@1979
   651
      SmartEdgeSetBase<_Graph> > > Parent;
deba@1962
   652
    
deba@1962
   653
    typedef typename Parent::Node Node;
deba@1962
   654
    typedef typename Parent::Edge Edge;
deba@1962
   655
    
deba@1962
   656
    typedef _Graph Graph;
deba@1962
   657
deba@1962
   658
    class UnsupportedOperation : public LogicError {
deba@1962
   659
    public:
deba@1962
   660
      virtual const char* exceptionName() const {
deba@1962
   661
        return "lemon::SmartUEdgeSet::UnsupportedOperation";
deba@1962
   662
      }
deba@1962
   663
    };
deba@1962
   664
deba@1962
   665
  protected:
deba@1962
   666
deba@1962
   667
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   668
deba@1999
   669
    void eraseNode(const Node& node) {
deba@1999
   670
      if (Parent::IncEdgeIt(*this, node) == INVALID) {
deba@1999
   671
        return;
deba@1999
   672
      }
deba@1962
   673
      throw UnsupportedOperation();
deba@1962
   674
    }
deba@1962
   675
    
deba@1962
   676
    void clearNodes() {
deba@1962
   677
      Parent::clear();
deba@1962
   678
    }
deba@1962
   679
deba@1962
   680
    class NodesImpl : public NodesImplBase {
deba@1962
   681
    public:
deba@1962
   682
      typedef NodesImplBase Parent;
deba@1962
   683
      
deba@1962
   684
      NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
deba@1962
   685
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   686
deba@1962
   687
      virtual ~NodesImpl() {}
deba@1962
   688
      
deba@1962
   689
    protected:
deba@1962
   690
deba@1962
   691
      virtual void erase(const Node& node) {
deba@1962
   692
	_edgeset.eraseNode(node);
deba@1962
   693
	Parent::erase(node);
deba@1962
   694
      }
deba@1962
   695
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   696
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   697
	  _edgeset.eraseNode(nodes[i]);
deba@1962
   698
	}
deba@1962
   699
	Parent::erase(nodes);
deba@1962
   700
      }
deba@1962
   701
      virtual void clear() {
deba@1962
   702
	_edgeset.clearNodes();
deba@1962
   703
	Parent::clear();
deba@1962
   704
      }
deba@1962
   705
deba@1962
   706
    private:
deba@1962
   707
      SmartUEdgeSet& _edgeset;
deba@1962
   708
    };
deba@1962
   709
deba@1962
   710
    NodesImpl nodes;
deba@1962
   711
    
deba@1962
   712
  public:
deba@1962
   713
deba@1962
   714
    /// \brief Constructor of the adaptor.
deba@1962
   715
    /// 
deba@1962
   716
    /// Constructor of the adaptor.
deba@1962
   717
    SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   718
      Parent::initalize(graph, nodes);
deba@1962
   719
    }
deba@1962
   720
    
deba@1962
   721
  };
deba@1962
   722
deba@1842
   723
}
deba@1842
   724
deba@1842
   725
#endif