lemon/edge_set.h
author deba
Fri, 29 Sep 2006 11:23:54 +0000
changeset 2222 a24939ee343c
parent 2192 d6e4efb477d8
child 2224 f973894da54e
permissions -rw-r--r--
findEdge extension also for the BpUGraphs
proper handling of loop edges in the UGraph::findUEdge
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@2111
   241
  /// this class. Its interface must conform to the \ref concept::Graph
deba@2111
   242
  /// "Graph" concept.
deba@1842
   243
  ///
deba@1842
   244
  /// In the edge extension and removing it conforms to the 
deba@2111
   245
  /// \ref concept::Graph "Graph" 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@2111
   333
  /// this class. Its interface must conform to the \ref concept::Graph
deba@2111
   334
  /// "Graph" concept.
deba@1842
   335
  ///
deba@1842
   336
  /// In the edge extension and removing it conforms to the 
deba@2111
   337
  /// \ref concept::UGraph "UGraph" concept.
deba@1842
   338
  template <typename _Graph>
deba@1979
   339
  class ListUEdgeSet 
deba@2076
   340
    : public UEdgeSetExtender<UndirGraphExtender<ListEdgeSetBase<_Graph> > > {
deba@1842
   341
deba@1842
   342
  public:
deba@1842
   343
deba@2076
   344
    typedef UEdgeSetExtender<UndirGraphExtender<
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@2111
   570
  /// this class. Its interface must conform to the \ref concept::Graph
deba@2111
   571
  /// "Graph" concept.
deba@1962
   572
  ///
deba@1962
   573
  /// In the edge extension and removing it conforms to the 
deba@2111
   574
  /// \ref concept::Graph "Graph" 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
  protected:
deba@1962
   588
deba@1962
   589
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   590
deba@1999
   591
    void eraseNode(const Node& node) {
deba@1999
   592
      if (Parent::InEdgeIt(*this, node) == INVALID &&
deba@1999
   593
          Parent::OutEdgeIt(*this, node) == INVALID) {
deba@1999
   594
        return;
deba@1999
   595
      }
deba@2191
   596
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@1962
   597
    }
deba@1962
   598
    
deba@1962
   599
    void clearNodes() {
deba@1962
   600
      Parent::clear();
deba@1962
   601
    }
deba@1962
   602
deba@1962
   603
    class NodesImpl : public NodesImplBase {
deba@1962
   604
    public:
deba@1962
   605
      typedef NodesImplBase Parent;
deba@1962
   606
      
deba@1962
   607
      NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
deba@1962
   608
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   609
deba@1962
   610
      virtual ~NodesImpl() {}
deba@1962
   611
      
deba@2193
   612
      bool attached() const {
deba@2193
   613
        return Parent::attached();
deba@2193
   614
      }
deba@2193
   615
deba@1962
   616
    protected:
deba@1962
   617
deba@1962
   618
      virtual void erase(const Node& node) {
deba@2191
   619
        try {
deba@2191
   620
          _edgeset.eraseNode(node);
deba@2191
   621
          Parent::erase(node);
deba@2191
   622
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
   623
          Parent::clear();
deba@2193
   624
          throw;
deba@2191
   625
        }
deba@1962
   626
      }
deba@1962
   627
      virtual void erase(const std::vector<Node>& nodes) {
deba@2191
   628
        try {
deba@2191
   629
          for (int i = 0; i < (int)nodes.size(); ++i) {
deba@2191
   630
            _edgeset.eraseNode(nodes[i]);
deba@2191
   631
          }
deba@2191
   632
          Parent::erase(nodes);
deba@2191
   633
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
   634
          Parent::clear();
deba@2193
   635
          throw;
deba@1962
   636
        }
deba@1962
   637
      }
deba@1962
   638
      virtual void clear() {
deba@1962
   639
	_edgeset.clearNodes();
deba@1962
   640
	Parent::clear();
deba@1962
   641
      }
deba@1962
   642
deba@1962
   643
    private:
deba@1962
   644
      SmartEdgeSet& _edgeset;
deba@1962
   645
    };
deba@1962
   646
deba@1962
   647
    NodesImpl nodes;
deba@1962
   648
    
deba@1962
   649
  public:
deba@1962
   650
deba@1962
   651
    /// \brief Constructor of the adaptor.
deba@1962
   652
    /// 
deba@1962
   653
    /// Constructor of the adaptor.
deba@1962
   654
    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   655
      Parent::initalize(graph, nodes);
deba@1962
   656
    }
deba@2193
   657
deba@2193
   658
    bool valid() const {
deba@2193
   659
      return nodes.attached();
deba@2193
   660
    }
deba@1962
   661
    
deba@1962
   662
  };
deba@1962
   663
deba@1962
   664
  /// \ingroup semi_adaptors
deba@1962
   665
  ///
deba@1962
   666
  /// \brief Graph using a node set of another graph and an
deba@1962
   667
  /// own uedge set.
deba@1962
   668
  ///
deba@1962
   669
  /// This structure can be used to establish another graph over a node set
deba@1962
   670
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   671
  /// original graph.
deba@1962
   672
  ///
deba@1962
   673
  /// \param _Graph The type of the graph which shares its node set with 
deba@2111
   674
  /// this class. Its interface must conform to the \ref concept::Graph
deba@2111
   675
  /// "Graph" concept.
deba@1962
   676
  ///
deba@1962
   677
  /// In the edge extension and removing it conforms to the 
deba@2111
   678
  /// \ref concept::UGraph "UGraph" concept.
deba@1962
   679
  template <typename _Graph>
deba@1979
   680
  class SmartUEdgeSet 
deba@2076
   681
    : public UEdgeSetExtender<UndirGraphExtender<SmartEdgeSetBase<_Graph> > > {
deba@1962
   682
deba@1962
   683
  public:
deba@1962
   684
deba@2076
   685
    typedef UEdgeSetExtender<UndirGraphExtender<
deba@1979
   686
      SmartEdgeSetBase<_Graph> > > Parent;
deba@1962
   687
    
deba@1962
   688
    typedef typename Parent::Node Node;
deba@1962
   689
    typedef typename Parent::Edge Edge;
deba@1962
   690
    
deba@1962
   691
    typedef _Graph Graph;
deba@1962
   692
deba@1962
   693
  protected:
deba@1962
   694
deba@1962
   695
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   696
deba@1999
   697
    void eraseNode(const Node& node) {
deba@2031
   698
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
deba@1999
   699
        return;
deba@1999
   700
      }
deba@2191
   701
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@1962
   702
    }
deba@1962
   703
    
deba@1962
   704
    void clearNodes() {
deba@1962
   705
      Parent::clear();
deba@1962
   706
    }
deba@1962
   707
deba@1962
   708
    class NodesImpl : public NodesImplBase {
deba@1962
   709
    public:
deba@1962
   710
      typedef NodesImplBase Parent;
deba@1962
   711
      
deba@1962
   712
      NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
deba@1962
   713
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   714
deba@1962
   715
      virtual ~NodesImpl() {}
deba@2193
   716
deba@2193
   717
      bool attached() const {
deba@2193
   718
        return Parent::attached();
deba@2193
   719
      }
deba@1962
   720
      
deba@1962
   721
    protected:
deba@1962
   722
deba@1962
   723
      virtual void erase(const Node& node) {
deba@2191
   724
        try {
deba@2191
   725
          _edgeset.eraseNode(node);
deba@2191
   726
          Parent::erase(node);
deba@2191
   727
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
   728
          Parent::clear();
deba@2192
   729
          throw;
deba@2191
   730
        }
deba@1962
   731
      }
deba@1962
   732
      virtual void erase(const std::vector<Node>& nodes) {
deba@2191
   733
        try {
deba@2191
   734
          for (int i = 0; i < (int)nodes.size(); ++i) {
deba@2191
   735
            _edgeset.eraseNode(nodes[i]);
deba@2191
   736
          }
deba@2191
   737
          Parent::erase(nodes);
deba@2191
   738
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
   739
          Parent::clear();
deba@2192
   740
          throw;
deba@2191
   741
        }
deba@1962
   742
      }
deba@1962
   743
      virtual void clear() {
deba@1962
   744
	_edgeset.clearNodes();
deba@1962
   745
	Parent::clear();
deba@1962
   746
      }
deba@1962
   747
deba@1962
   748
    private:
deba@1962
   749
      SmartUEdgeSet& _edgeset;
deba@1962
   750
    };
deba@1962
   751
deba@1962
   752
    NodesImpl nodes;
deba@1962
   753
    
deba@1962
   754
  public:
deba@1962
   755
deba@1962
   756
    /// \brief Constructor of the adaptor.
deba@1962
   757
    /// 
deba@1962
   758
    /// Constructor of the adaptor.
deba@1962
   759
    SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   760
      Parent::initalize(graph, nodes);
deba@1962
   761
    }
deba@2193
   762
deba@2193
   763
    bool valid() const {
deba@2193
   764
      return nodes.attached();
deba@2193
   765
    }
deba@1962
   766
    
deba@1962
   767
  };
deba@1962
   768
deba@1842
   769
}
deba@1842
   770
deba@1842
   771
#endif