lemon/edge_set.h
author deba
Thu, 06 Apr 2006 09:33:29 +0000
changeset 2039 dacc4ce9474d
parent 1999 2ff283124dfc
child 2076 10681ee9d8ae
permissions -rw-r--r--
Commiting The DynamicAsymMatrixMap from Nagy Jano
+ MatrixMapTraits
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