lemon/edge_set.h
author deba
Mon, 03 Apr 2006 09:45:23 +0000
changeset 2031 080d51024ac5
parent 1999 2ff283124dfc
child 2076 10681ee9d8ae
permissions -rw-r--r--
Correcting the structure of the graph's and adaptor's map.
The template assign operators and map iterators can be used for adaptors also.

Some bugfix in the adaptors

New class SwapBpUGraphAdaptor which swaps the two nodeset of the graph.
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@2031
   209
deba@1842
   210
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@2031
   211
deba@1842
   212
      explicit NodeMap(const ListEdgeSetBase<Graph>& edgeset) 
deba@2031
   213
	: Parent(*edgeset.graph) {}
deba@2031
   214
deba@1842
   215
      NodeMap(const ListEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@2031
   216
	: Parent(*edgeset.graph, value) {}
deba@2031
   217
deba@2031
   218
      NodeMap& operator=(const NodeMap& cmap) {
deba@2031
   219
        return operator=<NodeMap>(cmap);
deba@2031
   220
      }
deba@2031
   221
deba@2031
   222
      template <typename CMap>
deba@2031
   223
      NodeMap& operator=(const CMap& cmap) {
deba@2031
   224
        Parent::operator=(cmap);
deba@2031
   225
        return *this;
deba@2031
   226
      }
deba@1842
   227
    };
deba@1842
   228
deba@1842
   229
  };
deba@1842
   230
deba@1866
   231
  /// \ingroup semi_adaptors
deba@1842
   232
  ///
deba@1842
   233
  /// \brief Graph using a node set of another graph and an
deba@1842
   234
  /// own edge set.
deba@1842
   235
  ///
deba@1842
   236
  /// This structure can be used to establish another graph over a node set
deba@1842
   237
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   238
  /// original graph.
deba@1842
   239
  ///
deba@1842
   240
  /// \param _Graph The type of the graph which shares its node set with 
deba@1842
   241
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1842
   242
  /// "StaticGraph" concept.
deba@1842
   243
  ///
deba@1842
   244
  /// In the edge extension and removing it conforms to the 
deba@1962
   245
  /// \ref concept::ErasableGraph "ErasableGraph" concept.
deba@1842
   246
  template <typename _Graph>
deba@1979
   247
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
deba@1842
   248
deba@1842
   249
  public:
deba@1842
   250
deba@1979
   251
    typedef EdgeSetExtender<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>
deba@1979
   339
  class ListUEdgeSet 
deba@1979
   340
    : public UEdgeSetExtender<UGraphBaseExtender<ListEdgeSetBase<_Graph> > > {
deba@1842
   341
deba@1842
   342
  public:
deba@1842
   343
deba@1979
   344
    typedef UEdgeSetExtender<UGraphBaseExtender<
deba@1979
   345
      ListEdgeSetBase<_Graph> > > Parent;
deba@1842
   346
    
deba@1842
   347
    typedef typename Parent::Node Node;
deba@1842
   348
    typedef typename Parent::Edge Edge;
deba@1842
   349
    
deba@1842
   350
    typedef _Graph Graph;
deba@1842
   351
deba@1842
   352
deba@1842
   353
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   354
deba@1842
   355
    void eraseNode(const Node& node) {
deba@1842
   356
      Edge edge;
deba@1842
   357
      Parent::firstOut(edge, node);
deba@1842
   358
      while (edge != INVALID ) {
deba@1842
   359
	erase(edge);
deba@1842
   360
	Parent::firstOut(edge, node);
deba@1842
   361
      } 
deba@1842
   362
deba@1842
   363
    }
deba@1842
   364
    
deba@1842
   365
    void clearNodes() {
deba@1842
   366
      Parent::clear();
deba@1842
   367
    }
deba@1842
   368
deba@1842
   369
    class NodesImpl : public NodesImplBase {
deba@1842
   370
    public:
deba@1842
   371
      typedef NodesImplBase Parent;
deba@1842
   372
      
klao@1909
   373
      NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
deba@1842
   374
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   375
deba@1962
   376
      virtual ~NodesImpl() {}
deba@1842
   377
      
deba@1842
   378
    protected:
deba@1842
   379
deba@1842
   380
      virtual void erase(const Node& node) {
deba@1842
   381
	_edgeset.eraseNode(node);
deba@1842
   382
	Parent::erase(node);
deba@1842
   383
      }
deba@1866
   384
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   385
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1866
   386
	  _edgeset.eraseNode(nodes[i]);
deba@1866
   387
	}
deba@1866
   388
	Parent::erase(nodes);
deba@1866
   389
      }
deba@1842
   390
      virtual void clear() {
deba@1842
   391
	_edgeset.clearNodes();
deba@1842
   392
	Parent::clear();
deba@1842
   393
      }
deba@1842
   394
deba@1842
   395
    private:
klao@1909
   396
      ListUEdgeSet& _edgeset;
deba@1842
   397
    };
deba@1842
   398
deba@1842
   399
    NodesImpl nodes;
deba@1842
   400
    
deba@1842
   401
  public:
deba@1842
   402
deba@1842
   403
    /// \brief Constructor of the adaptor.
deba@1842
   404
    /// 
deba@1842
   405
    /// Constructor of the adaptor.
klao@1909
   406
    ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   407
      Parent::initalize(graph, nodes);
deba@1842
   408
    }
deba@1842
   409
    
deba@1842
   410
  };
deba@1842
   411
deba@1962
   412
  template <typename _Graph>
deba@1962
   413
  class SmartEdgeSetBase {
deba@1962
   414
  public:
deba@1962
   415
deba@1962
   416
    typedef _Graph Graph;
deba@1962
   417
    typedef typename Graph::Node Node;
deba@1962
   418
    typedef typename Graph::NodeIt NodeIt;
deba@1962
   419
deba@1962
   420
  protected:
deba@1962
   421
deba@1962
   422
    struct NodeT {
deba@1962
   423
      int first_out, first_in;
deba@1962
   424
      NodeT() : first_out(-1), first_in(-1) {}
deba@1962
   425
    };
deba@1962
   426
deba@1990
   427
    typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
deba@1962
   428
deba@1962
   429
    NodesImplBase* nodes;
deba@1962
   430
deba@1962
   431
    struct EdgeT {
deba@1962
   432
      Node source, target;
deba@1962
   433
      int next_out, next_in;
deba@1962
   434
      EdgeT() {}
deba@1962
   435
    };
deba@1962
   436
deba@1962
   437
    std::vector<EdgeT> edges;
deba@1962
   438
deba@1962
   439
    const Graph* graph;
deba@1962
   440
deba@1962
   441
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1962
   442
      graph = &_graph;
deba@1962
   443
      nodes = &_nodes;
deba@1962
   444
    }
deba@1962
   445
    
deba@1962
   446
  public:
deba@1962
   447
deba@1962
   448
    class Edge {
deba@1962
   449
      friend class SmartEdgeSetBase<Graph>;
deba@1962
   450
    protected:
deba@1962
   451
      Edge(int _id) : id(_id) {}
deba@1962
   452
      int id;
deba@1962
   453
    public:
deba@1962
   454
      Edge() {}
deba@1962
   455
      Edge(Invalid) : id(-1) {}
deba@1962
   456
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1962
   457
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1962
   458
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1962
   459
    };
deba@1962
   460
deba@1962
   461
    SmartEdgeSetBase() {} 
deba@1962
   462
deba@1962
   463
    Edge addEdge(const Node& source, const Node& target) {
deba@1962
   464
      int n = edges.size();
deba@1962
   465
      edges.push_back(EdgeT());
deba@1962
   466
      edges[n].next_in = (*nodes)[target].first_in;
deba@1962
   467
      (*nodes)[target].first_in = n;
deba@1962
   468
      edges[n].next_out = (*nodes)[source].first_out;
deba@1962
   469
      (*nodes)[source].first_out = n;
deba@1962
   470
      edges[n].source = source;
deba@1962
   471
      edges[n].target = target;
deba@1962
   472
      return Edge(n);
deba@1962
   473
    }
deba@1962
   474
deba@1962
   475
    void clear() {
deba@1962
   476
      Node node;
deba@1962
   477
      for (first(node); node != INVALID; next(node)) {
deba@1962
   478
        (*nodes)[node].first_in = -1;
deba@1962
   479
        (*nodes)[node].first_out = -1;
deba@1962
   480
      }
deba@1962
   481
      edges.clear();
deba@1962
   482
    }
deba@1962
   483
deba@1962
   484
    void first(Node& node) const {
deba@1962
   485
      graph->first(node);
deba@1962
   486
    }
deba@1962
   487
deba@1962
   488
    void next(Node& node) const {
deba@1962
   489
      graph->next(node);
deba@1962
   490
    }
deba@1962
   491
deba@1962
   492
    void first(Edge& edge) const {
deba@1962
   493
      edge.id = edges.size() - 1;
deba@1962
   494
    }
deba@1962
   495
deba@1962
   496
    void next(Edge& edge) const {
deba@1962
   497
      --edge.id;
deba@1962
   498
    }
deba@1962
   499
deba@1962
   500
    void firstOut(Edge& edge, const Node& node) const {
deba@1962
   501
      edge.id = (*nodes)[node].first_out;    
deba@1962
   502
    }
deba@1962
   503
    
deba@1962
   504
    void nextOut(Edge& edge) const {
deba@1962
   505
      edge.id = edges[edge.id].next_out;        
deba@1962
   506
    }
deba@1962
   507
deba@1962
   508
    void firstIn(Edge& edge, const Node& node) const {
deba@1962
   509
      edge.id = (*nodes)[node].first_in;          
deba@1962
   510
    }
deba@1962
   511
deba@1962
   512
    void nextIn(Edge& edge) const {
deba@1962
   513
      edge.id = edges[edge.id].next_in;    
deba@1962
   514
    }
deba@1962
   515
deba@1962
   516
    int id(const Node& node) const { return graph->id(node); }
deba@1962
   517
    int id(const Edge& edge) const { return edge.id; }
deba@1962
   518
deba@1962
   519
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@1962
   520
    Edge edgeFromId(int id) const { return Edge(id); }
deba@1962
   521
deba@1962
   522
    int maxNodeId() const { return graph->maxNodeId(); };
deba@1962
   523
    int maxEdgeId() const { return edges.size() - 1; }
deba@1962
   524
deba@1962
   525
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1962
   526
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1962
   527
deba@1990
   528
    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
deba@1990
   529
deba@1990
   530
    NodeNotifier& getNotifier(Node) const {
deba@1990
   531
      return graph->getNotifier(Node());
deba@1990
   532
    } 
deba@1990
   533
deba@1962
   534
    template <typename _Value>
deba@1962
   535
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1962
   536
    public:
deba@2031
   537
deba@1962
   538
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@2031
   539
deba@1962
   540
      explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset) 
deba@1962
   541
	: Parent(*edgeset.graph) { }
deba@2031
   542
deba@1962
   543
      NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1962
   544
	: Parent(*edgeset.graph, value) { }
deba@2031
   545
deba@2031
   546
      NodeMap& operator=(const NodeMap& cmap) {
deba@2031
   547
        return operator=<NodeMap>(cmap);
deba@2031
   548
      }
deba@2031
   549
deba@2031
   550
      template <typename CMap>
deba@2031
   551
      NodeMap& operator=(const CMap& cmap) {
deba@2031
   552
        Parent::operator=(cmap);
deba@2031
   553
        return *this;
deba@2031
   554
      }
deba@1962
   555
    };
deba@1962
   556
deba@1962
   557
  };
deba@1962
   558
deba@1962
   559
deba@1962
   560
  /// \ingroup semi_adaptors
deba@1962
   561
  ///
deba@1962
   562
  /// \brief Graph using a node set of another graph and an
deba@1962
   563
  /// own edge set.
deba@1962
   564
  ///
deba@1962
   565
  /// This structure can be used to establish another graph over a node set
deba@1962
   566
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   567
  /// original graph.
deba@1962
   568
  ///
deba@1962
   569
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   570
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   571
  /// "StaticGraph" concept.
deba@1962
   572
  ///
deba@1962
   573
  /// In the edge extension and removing it conforms to the 
deba@1962
   574
  /// \ref concept::ExtendableGraph "ExtendableGraph" concept.
deba@1962
   575
  template <typename _Graph>
deba@1979
   576
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
deba@1962
   577
deba@1962
   578
  public:
deba@1962
   579
deba@1979
   580
    typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
deba@1962
   581
    
deba@1962
   582
    typedef typename Parent::Node Node;
deba@1962
   583
    typedef typename Parent::Edge Edge;
deba@1962
   584
    
deba@1962
   585
    typedef _Graph Graph;
deba@1962
   586
deba@1962
   587
    class UnsupportedOperation : public LogicError {
deba@1962
   588
    public:
deba@1962
   589
      virtual const char* exceptionName() const {
deba@1962
   590
        return "lemon::SmartEdgeSet::UnsupportedOperation";
deba@1962
   591
      }
deba@1962
   592
    };
deba@1962
   593
    
deba@1962
   594
deba@1962
   595
deba@1962
   596
  protected:
deba@1962
   597
deba@1962
   598
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   599
deba@1999
   600
    void eraseNode(const Node& node) {
deba@1999
   601
      if (Parent::InEdgeIt(*this, node) == INVALID &&
deba@1999
   602
          Parent::OutEdgeIt(*this, node) == INVALID) {
deba@1999
   603
        return;
deba@1999
   604
      }
deba@1962
   605
      throw UnsupportedOperation();
deba@1962
   606
    }
deba@1962
   607
    
deba@1962
   608
    void clearNodes() {
deba@1962
   609
      Parent::clear();
deba@1962
   610
    }
deba@1962
   611
deba@1962
   612
    class NodesImpl : public NodesImplBase {
deba@1962
   613
    public:
deba@1962
   614
      typedef NodesImplBase Parent;
deba@1962
   615
      
deba@1962
   616
      NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
deba@1962
   617
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   618
deba@1962
   619
      virtual ~NodesImpl() {}
deba@1962
   620
      
deba@1962
   621
    protected:
deba@1962
   622
deba@1962
   623
      virtual void erase(const Node& node) {
deba@1962
   624
	_edgeset.eraseNode(node);
deba@1962
   625
	Parent::erase(node);
deba@1962
   626
      }
deba@1962
   627
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   628
        for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   629
          _edgeset.eraseNode(nodes[i]);
deba@1962
   630
        }
deba@1962
   631
	Parent::erase(nodes);
deba@1962
   632
      }
deba@1962
   633
      virtual void clear() {
deba@1962
   634
	_edgeset.clearNodes();
deba@1962
   635
	Parent::clear();
deba@1962
   636
      }
deba@1962
   637
deba@1962
   638
    private:
deba@1962
   639
      SmartEdgeSet& _edgeset;
deba@1962
   640
    };
deba@1962
   641
deba@1962
   642
    NodesImpl nodes;
deba@1962
   643
    
deba@1962
   644
  public:
deba@1962
   645
deba@1962
   646
    /// \brief Constructor of the adaptor.
deba@1962
   647
    /// 
deba@1962
   648
    /// Constructor of the adaptor.
deba@1962
   649
    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   650
      Parent::initalize(graph, nodes);
deba@1962
   651
    }
deba@1962
   652
    
deba@1962
   653
  };
deba@1962
   654
deba@1962
   655
  /// \ingroup semi_adaptors
deba@1962
   656
  ///
deba@1962
   657
  /// \brief Graph using a node set of another graph and an
deba@1962
   658
  /// own uedge set.
deba@1962
   659
  ///
deba@1962
   660
  /// This structure can be used to establish another graph over a node set
deba@1962
   661
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   662
  /// original graph.
deba@1962
   663
  ///
deba@1962
   664
  /// \param _Graph The type of the graph which shares its node set with 
deba@1962
   665
  /// this class. Its interface must conform to the \ref concept::StaticGraph
deba@1962
   666
  /// "StaticGraph" concept.
deba@1962
   667
  ///
deba@1962
   668
  /// In the edge extension and removing it conforms to the 
deba@1962
   669
  /// \ref concept::ExtendableUGraph "ExtendableUGraph" concept.
deba@1962
   670
  template <typename _Graph>
deba@1979
   671
  class SmartUEdgeSet 
deba@1979
   672
    : public UEdgeSetExtender<UGraphBaseExtender<SmartEdgeSetBase<_Graph> > > {
deba@1962
   673
deba@1962
   674
  public:
deba@1962
   675
deba@1979
   676
    typedef UEdgeSetExtender<UGraphBaseExtender<
deba@1979
   677
      SmartEdgeSetBase<_Graph> > > Parent;
deba@1962
   678
    
deba@1962
   679
    typedef typename Parent::Node Node;
deba@1962
   680
    typedef typename Parent::Edge Edge;
deba@1962
   681
    
deba@1962
   682
    typedef _Graph Graph;
deba@1962
   683
deba@1962
   684
    class UnsupportedOperation : public LogicError {
deba@1962
   685
    public:
deba@1962
   686
      virtual const char* exceptionName() const {
deba@1962
   687
        return "lemon::SmartUEdgeSet::UnsupportedOperation";
deba@1962
   688
      }
deba@1962
   689
    };
deba@1962
   690
deba@1962
   691
  protected:
deba@1962
   692
deba@1962
   693
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   694
deba@1999
   695
    void eraseNode(const Node& node) {
deba@2031
   696
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
deba@1999
   697
        return;
deba@1999
   698
      }
deba@1962
   699
      throw UnsupportedOperation();
deba@1962
   700
    }
deba@1962
   701
    
deba@1962
   702
    void clearNodes() {
deba@1962
   703
      Parent::clear();
deba@1962
   704
    }
deba@1962
   705
deba@1962
   706
    class NodesImpl : public NodesImplBase {
deba@1962
   707
    public:
deba@1962
   708
      typedef NodesImplBase Parent;
deba@1962
   709
      
deba@1962
   710
      NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
deba@1962
   711
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   712
deba@1962
   713
      virtual ~NodesImpl() {}
deba@1962
   714
      
deba@1962
   715
    protected:
deba@1962
   716
deba@1962
   717
      virtual void erase(const Node& node) {
deba@1962
   718
	_edgeset.eraseNode(node);
deba@1962
   719
	Parent::erase(node);
deba@1962
   720
      }
deba@1962
   721
      virtual void erase(const std::vector<Node>& nodes) {
deba@1962
   722
	for (int i = 0; i < (int)nodes.size(); ++i) {
deba@1962
   723
	  _edgeset.eraseNode(nodes[i]);
deba@1962
   724
	}
deba@1962
   725
	Parent::erase(nodes);
deba@1962
   726
      }
deba@1962
   727
      virtual void clear() {
deba@1962
   728
	_edgeset.clearNodes();
deba@1962
   729
	Parent::clear();
deba@1962
   730
      }
deba@1962
   731
deba@1962
   732
    private:
deba@1962
   733
      SmartUEdgeSet& _edgeset;
deba@1962
   734
    };
deba@1962
   735
deba@1962
   736
    NodesImpl nodes;
deba@1962
   737
    
deba@1962
   738
  public:
deba@1962
   739
deba@1962
   740
    /// \brief Constructor of the adaptor.
deba@1962
   741
    /// 
deba@1962
   742
    /// Constructor of the adaptor.
deba@1962
   743
    SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   744
      Parent::initalize(graph, nodes);
deba@1962
   745
    }
deba@1962
   746
    
deba@1962
   747
  };
deba@1962
   748
deba@1842
   749
}
deba@1842
   750
deba@1842
   751
#endif