lemon/edge_set.h
author hegyi
Tue, 08 Apr 2008 11:39:40 +0000
changeset 2602 1c7790d9e025
parent 2498 290e43cddc1a
child 2618 6aa6fcaeaea5
permissions -rw-r--r--
Rel.07 NEWS - 3. round
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@2553
     5
 * Copyright (C) 2003-2008
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@2224
    26
/// \ingroup semi_adaptors
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@2386
    89
    Edge addEdge(const Node& u, const Node& v) {
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@2386
    98
      edges[n].next_in = (*nodes)[v].first_in;
deba@2386
    99
      if ((*nodes)[v].first_in != -1) {
deba@2386
   100
        edges[(*nodes)[v].first_in].prev_in = n;
deba@1962
   101
      }
deba@2386
   102
      (*nodes)[v].first_in = n;
deba@2386
   103
      edges[n].next_out = (*nodes)[u].first_out;
deba@2386
   104
      if ((*nodes)[u].first_out != -1) {
deba@2386
   105
        edges[(*nodes)[u].first_out].prev_out = n;
deba@1962
   106
      }
deba@2386
   107
      (*nodes)[u].first_out = n;
deba@2386
   108
      edges[n].source = u;
deba@2386
   109
      edges[n].target = v;
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@2386
   191
    Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
deba@2386
   192
    Edge edgeFromId(int ix) const { return Edge(ix); }
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@2384
   202
    NodeNotifier& notifier(Node) const {
deba@2384
   203
      return graph->notifier(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 
alpar@2260
   241
  /// this class. Its interface must conform to the \ref concepts::Graph
deba@2111
   242
  /// "Graph" concept.
deba@1842
   243
  ///
deba@1842
   244
  template <typename _Graph>
deba@1979
   245
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<_Graph> > {
deba@1842
   246
deba@1842
   247
  public:
deba@1842
   248
deba@1979
   249
    typedef EdgeSetExtender<ListEdgeSetBase<_Graph> > Parent;
deba@1842
   250
    
deba@1842
   251
    typedef typename Parent::Node Node;
deba@1842
   252
    typedef typename Parent::Edge Edge;
deba@1842
   253
    
deba@1842
   254
    typedef _Graph Graph;
deba@1842
   255
deba@1842
   256
deba@1842
   257
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   258
deba@1842
   259
    void eraseNode(const Node& node) {
deba@1842
   260
      Edge edge;
deba@1842
   261
      Parent::firstOut(edge, node);
deba@1842
   262
      while (edge != INVALID ) {
deba@1842
   263
	erase(edge);
deba@1842
   264
	Parent::firstOut(edge, node);
deba@1842
   265
      } 
deba@1842
   266
deba@1842
   267
      Parent::firstIn(edge, node);
deba@1842
   268
      while (edge != INVALID ) {
deba@1842
   269
	erase(edge);
deba@1842
   270
	Parent::firstIn(edge, node);
deba@1842
   271
      }
deba@1842
   272
    }
deba@1842
   273
    
deba@1842
   274
    void clearNodes() {
deba@1842
   275
      Parent::clear();
deba@1842
   276
    }
deba@1842
   277
deba@1842
   278
    class NodesImpl : public NodesImplBase {
deba@1842
   279
    public:
deba@1842
   280
      typedef NodesImplBase Parent;
deba@1842
   281
      
deba@1842
   282
      NodesImpl(const Graph& graph, ListEdgeSet& edgeset) 
deba@1842
   283
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   284
deba@1962
   285
      virtual ~NodesImpl() {}
deba@1842
   286
      
deba@1842
   287
    protected:
deba@1842
   288
deba@1842
   289
      virtual void erase(const Node& node) {
deba@1842
   290
	_edgeset.eraseNode(node);
deba@1842
   291
	Parent::erase(node);
deba@1842
   292
      }
deba@1962
   293
      virtual void erase(const std::vector<Node>& nodes) {
deba@2386
   294
        for (int i = 0; i < int(nodes.size()); ++i) {
deba@1962
   295
          _edgeset.eraseNode(nodes[i]);
deba@1962
   296
        }
deba@1962
   297
	Parent::erase(nodes);
deba@1962
   298
      }
deba@1842
   299
      virtual void clear() {
deba@1842
   300
	_edgeset.clearNodes();
deba@1842
   301
	Parent::clear();
deba@1842
   302
      }
deba@1842
   303
deba@1842
   304
    private:
deba@1842
   305
      ListEdgeSet& _edgeset;
deba@1842
   306
    };
deba@1842
   307
deba@1842
   308
    NodesImpl nodes;
deba@1842
   309
    
deba@1842
   310
  public:
deba@1842
   311
deba@1842
   312
    /// \brief Constructor of the adaptor.
deba@1842
   313
    /// 
deba@1842
   314
    /// Constructor of the adaptor.
deba@1842
   315
    ListEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   316
      Parent::initalize(graph, nodes);
deba@1842
   317
    }
deba@1842
   318
    
deba@1842
   319
  };
deba@1842
   320
deba@2498
   321
  template <typename _Graph>
deba@2498
   322
  class ListUEdgeSetBase {
deba@2498
   323
  public:
deba@2498
   324
deba@2498
   325
    typedef _Graph Graph;
deba@2498
   326
    typedef typename Graph::Node Node;
deba@2498
   327
    typedef typename Graph::NodeIt NodeIt;
deba@2498
   328
deba@2498
   329
  protected:
deba@2498
   330
deba@2498
   331
    struct NodeT {
deba@2498
   332
      int first_out;
deba@2498
   333
      NodeT() : first_out(-1) {}
deba@2498
   334
    };
deba@2498
   335
deba@2498
   336
    typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
deba@2498
   337
deba@2498
   338
    NodesImplBase* nodes;
deba@2498
   339
deba@2498
   340
    struct EdgeT {
deba@2498
   341
      Node target;
deba@2498
   342
      int prev_out, next_out;
deba@2498
   343
      EdgeT() : prev_out(-1), next_out(-1) {}
deba@2498
   344
    };
deba@2498
   345
deba@2498
   346
    std::vector<EdgeT> edges;
deba@2498
   347
deba@2498
   348
    int first_edge;
deba@2498
   349
    int first_free_edge;
deba@2498
   350
deba@2498
   351
    const Graph* graph;
deba@2498
   352
deba@2498
   353
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@2498
   354
      graph = &_graph;
deba@2498
   355
      nodes = &_nodes;
deba@2498
   356
    }
deba@2498
   357
    
deba@2498
   358
  public:
deba@2498
   359
deba@2498
   360
    class UEdge {
deba@2498
   361
      friend class ListUEdgeSetBase;
deba@2498
   362
    protected:
deba@2498
   363
deba@2498
   364
      int id;
deba@2498
   365
      explicit UEdge(int _id) { id = _id;}
deba@2498
   366
deba@2498
   367
    public:
deba@2498
   368
      UEdge() {}
deba@2498
   369
      UEdge (Invalid) { id = -1; }
deba@2498
   370
      bool operator==(const UEdge& edge) const {return id == edge.id;}
deba@2498
   371
      bool operator!=(const UEdge& edge) const {return id != edge.id;}
deba@2498
   372
      bool operator<(const UEdge& edge) const {return id < edge.id;}
deba@2498
   373
    };
deba@2498
   374
deba@2498
   375
    class Edge {
deba@2498
   376
      friend class ListUEdgeSetBase;
deba@2498
   377
    protected:
deba@2498
   378
      Edge(int _id) : id(_id) {}
deba@2498
   379
      int id;
deba@2498
   380
    public:
deba@2498
   381
      operator UEdge() const { return uEdgeFromId(id / 2); }
deba@2498
   382
deba@2498
   383
      Edge() {}
deba@2498
   384
      Edge(Invalid) : id(-1) {}
deba@2498
   385
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@2498
   386
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@2498
   387
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@2498
   388
    };
deba@2498
   389
deba@2498
   390
    ListUEdgeSetBase() : first_edge(-1), first_free_edge(-1) {} 
deba@2498
   391
deba@2498
   392
    UEdge addEdge(const Node& u, const Node& v) {
deba@2498
   393
      int n;
deba@2498
   394
deba@2498
   395
      if (first_free_edge == -1) {
deba@2498
   396
	n = edges.size();
deba@2498
   397
	edges.push_back(EdgeT());
deba@2498
   398
	edges.push_back(EdgeT());
deba@2498
   399
      } else {
deba@2498
   400
	n = first_free_edge;
deba@2498
   401
	first_free_edge = edges[n].next_out;
deba@2498
   402
      }
deba@2498
   403
      
deba@2498
   404
      edges[n].target = u;
deba@2498
   405
      edges[n | 1].target = v;
deba@2498
   406
deba@2498
   407
      edges[n].next_out = (*nodes)[v].first_out;
deba@2498
   408
      if ((*nodes)[v].first_out != -1) {
deba@2498
   409
	edges[(*nodes)[v].first_out].prev_out = n;
deba@2498
   410
      }
deba@2498
   411
      (*nodes)[v].first_out = n;
deba@2498
   412
      edges[n].prev_out = -1;
deba@2498
   413
      
deba@2498
   414
      if ((*nodes)[u].first_out != -1) {
deba@2498
   415
	edges[(*nodes)[u].first_out].prev_out = (n | 1);
deba@2498
   416
      }
deba@2498
   417
      edges[n | 1].next_out = (*nodes)[u].first_out;
deba@2498
   418
      (*nodes)[u].first_out = (n | 1);
deba@2498
   419
      edges[n | 1].prev_out = -1;
deba@2498
   420
deba@2498
   421
      return UEdge(n / 2);
deba@2498
   422
    }
deba@2498
   423
deba@2498
   424
    void erase(const UEdge& edge) {
deba@2498
   425
      int n = edge.id * 2;
deba@2498
   426
      
deba@2498
   427
      if (edges[n].next_out != -1) {
deba@2498
   428
	edges[edges[n].next_out].prev_out = edges[n].prev_out;
deba@2498
   429
      } 
deba@2498
   430
deba@2498
   431
      if (edges[n].prev_out != -1) {
deba@2498
   432
	edges[edges[n].prev_out].next_out = edges[n].next_out;
deba@2498
   433
      } else {
deba@2498
   434
	(*nodes)[edges[n | 1].target].first_out = edges[n].next_out;
deba@2498
   435
      }
deba@2498
   436
deba@2498
   437
      if (edges[n | 1].next_out != -1) {
deba@2498
   438
	edges[edges[n | 1].next_out].prev_out = edges[n | 1].prev_out;
deba@2498
   439
      } 
deba@2498
   440
deba@2498
   441
      if (edges[n | 1].prev_out != -1) {
deba@2498
   442
	edges[edges[n | 1].prev_out].next_out = edges[n | 1].next_out;
deba@2498
   443
      } else {
deba@2498
   444
	(*nodes)[edges[n].target].first_out = edges[n | 1].next_out;
deba@2498
   445
      }
deba@2498
   446
      
deba@2498
   447
      edges[n].next_out = first_free_edge;
deba@2498
   448
      first_free_edge = n;      
deba@2498
   449
           
deba@2498
   450
    }
deba@2498
   451
deba@2498
   452
    void clear() {
deba@2498
   453
      Node node;
deba@2498
   454
      for (first(node); node != INVALID; next(node)) {
deba@2498
   455
        (*nodes)[node].first_out = -1;
deba@2498
   456
      }
deba@2498
   457
      edges.clear();
deba@2498
   458
      first_edge = -1;
deba@2498
   459
      first_free_edge = -1;
deba@2498
   460
    }
deba@2498
   461
deba@2498
   462
    void first(Node& node) const {
deba@2498
   463
      graph->first(node);
deba@2498
   464
    }
deba@2498
   465
deba@2498
   466
    void next(Node& node) const {
deba@2498
   467
      graph->next(node);
deba@2498
   468
    }
deba@2498
   469
deba@2498
   470
    void first(Edge& edge) const {
deba@2498
   471
      Node node;
deba@2498
   472
      first(node);
deba@2498
   473
      while (node != INVALID && (*nodes)[node].first_out == -1) {
deba@2498
   474
        next(node);
deba@2498
   475
      }
deba@2498
   476
      edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
deba@2498
   477
    }
deba@2498
   478
deba@2498
   479
    void next(Edge& edge) const {
deba@2498
   480
      if (edges[edge.id].next_out != -1) {
deba@2498
   481
	edge.id = edges[edge.id].next_out;
deba@2498
   482
      } else {
deba@2498
   483
	Node node = edges[edge.id ^ 1].target;
deba@2498
   484
	next(node);
deba@2498
   485
        while(node != INVALID && (*nodes)[node].first_out == -1) {
deba@2498
   486
          next(node);
deba@2498
   487
        }
deba@2498
   488
	edge.id = (node == INVALID) ? -1 : (*nodes)[node].first_out;
deba@2498
   489
      }      
deba@2498
   490
    }
deba@2498
   491
deba@2498
   492
    void first(UEdge& uedge) const {
deba@2498
   493
      Node node;
deba@2498
   494
      first(node);
deba@2498
   495
      while (node != INVALID) {
deba@2498
   496
        uedge.id = (*nodes)[node].first_out;
deba@2498
   497
        while ((uedge.id & 1) != 1) {
deba@2498
   498
          uedge.id = edges[uedge.id].next_out;
deba@2498
   499
        }
deba@2498
   500
        if (uedge.id != -1) {
deba@2498
   501
          uedge.id /= 2;
deba@2498
   502
          return;
deba@2498
   503
        } 
deba@2498
   504
        next(node);
deba@2498
   505
      }
deba@2498
   506
      uedge.id = -1;
deba@2498
   507
    }
deba@2498
   508
deba@2498
   509
    void next(UEdge& uedge) const {
deba@2498
   510
      Node node = edges[uedge.id * 2].target;
deba@2498
   511
      uedge.id = edges[(uedge.id * 2) | 1].next_out;
deba@2498
   512
      while ((uedge.id & 1) != 1) {
deba@2498
   513
        uedge.id = edges[uedge.id].next_out;
deba@2498
   514
      }
deba@2498
   515
      if (uedge.id != -1) {
deba@2498
   516
        uedge.id /= 2;
deba@2498
   517
        return;
deba@2498
   518
      } 
deba@2498
   519
      next(node);
deba@2498
   520
      while (node != INVALID) {
deba@2498
   521
        uedge.id = (*nodes)[node].first_out;
deba@2498
   522
        while ((uedge.id & 1) != 1) {
deba@2498
   523
          uedge.id = edges[uedge.id].next_out;
deba@2498
   524
        }
deba@2498
   525
        if (uedge.id != -1) {
deba@2498
   526
          uedge.id /= 2;
deba@2498
   527
          return;
deba@2498
   528
        } 
deba@2498
   529
	next(node);
deba@2498
   530
      }
deba@2498
   531
      uedge.id = -1;
deba@2498
   532
    }
deba@2498
   533
deba@2498
   534
    void firstOut(Edge& edge, const Node& node) const {
deba@2498
   535
      edge.id = (*nodes)[node].first_out;
deba@2498
   536
    }
deba@2498
   537
    
deba@2498
   538
    void nextOut(Edge& edge) const {
deba@2498
   539
      edge.id = edges[edge.id].next_out;        
deba@2498
   540
    }
deba@2498
   541
deba@2498
   542
    void firstIn(Edge& edge, const Node& node) const {
deba@2498
   543
      edge.id = (((*nodes)[node].first_out) ^ 1);
deba@2498
   544
      if (edge.id == -2) edge.id = -1;
deba@2498
   545
    }
deba@2498
   546
deba@2498
   547
    void nextIn(Edge& edge) const {
deba@2498
   548
      edge.id = ((edges[edge.id ^ 1].next_out) ^ 1);
deba@2498
   549
      if (edge.id == -2) edge.id = -1;
deba@2498
   550
    }
deba@2498
   551
deba@2498
   552
    void firstInc(UEdge &edge, bool& dir, const Node& node) const {
deba@2498
   553
      int de = (*nodes)[node].first_out;
deba@2498
   554
      if (de != -1 ) {
deba@2498
   555
        edge.id = de / 2;
deba@2498
   556
        dir = ((de & 1) == 1);
deba@2498
   557
      } else {
deba@2498
   558
        edge.id = -1;
deba@2498
   559
        dir = true;
deba@2498
   560
      }
deba@2498
   561
    }
deba@2498
   562
    void nextInc(UEdge &edge, bool& dir) const {
deba@2498
   563
      int de = (edges[(edge.id * 2) | (dir ? 1 : 0)].next_out);
deba@2498
   564
      if (de != -1 ) {
deba@2498
   565
        edge.id = de / 2;
deba@2498
   566
        dir = ((de & 1) == 1);
deba@2498
   567
      } else {
deba@2498
   568
        edge.id = -1;
deba@2498
   569
        dir = true;
deba@2498
   570
      }
deba@2498
   571
    }
deba@2498
   572
deba@2498
   573
    static bool direction(Edge edge) {
deba@2498
   574
      return (edge.id & 1) == 1;
deba@2498
   575
    }
deba@2498
   576
deba@2498
   577
    static Edge direct(UEdge uedge, bool dir) {
deba@2498
   578
      return Edge(uedge.id * 2 + (dir ? 1 : 0));
deba@2498
   579
    }
deba@2498
   580
deba@2498
   581
    int id(const Node& node) const { return graph->id(node); }
deba@2498
   582
    static int id(Edge e) { return e.id; }
deba@2498
   583
    static int id(UEdge e) { return e.id; }
deba@2498
   584
deba@2498
   585
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@2498
   586
    static Edge edgeFromId(int id) { return Edge(id);}
deba@2498
   587
    static UEdge uEdgeFromId(int id) { return UEdge(id);}
deba@2498
   588
deba@2498
   589
    int maxNodeId() const { return graph->maxNodeId(); };
deba@2498
   590
    int maxUEdgeId() const { return edges.size() / 2 - 1; }
deba@2498
   591
    int maxEdgeId() const { return edges.size()-1; }
deba@2498
   592
deba@2498
   593
    Node source(Edge e) const { return edges[e.id ^ 1].target; }
deba@2498
   594
    Node target(Edge e) const { return edges[e.id].target; }
deba@2498
   595
deba@2498
   596
    Node source(UEdge e) const { return edges[2 * e.id].target; }
deba@2498
   597
    Node target(UEdge e) const { return edges[2 * e.id + 1].target; }
deba@2498
   598
deba@2498
   599
    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
deba@2498
   600
deba@2498
   601
    NodeNotifier& notifier(Node) const {
deba@2498
   602
      return graph->notifier(Node());
deba@2498
   603
    } 
deba@2498
   604
deba@2498
   605
    template <typename _Value>
deba@2498
   606
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@2498
   607
    public:
deba@2498
   608
deba@2498
   609
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@2498
   610
deba@2498
   611
      explicit NodeMap(const ListUEdgeSetBase<Graph>& edgeset) 
deba@2498
   612
	: Parent(*edgeset.graph) {}
deba@2498
   613
deba@2498
   614
      NodeMap(const ListUEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@2498
   615
	: Parent(*edgeset.graph, value) {}
deba@2498
   616
deba@2498
   617
      NodeMap& operator=(const NodeMap& cmap) {
deba@2498
   618
        return operator=<NodeMap>(cmap);
deba@2498
   619
      }
deba@2498
   620
deba@2498
   621
      template <typename CMap>
deba@2498
   622
      NodeMap& operator=(const CMap& cmap) {
deba@2498
   623
        Parent::operator=(cmap);
deba@2498
   624
        return *this;
deba@2498
   625
      }
deba@2498
   626
    };
deba@2498
   627
deba@2498
   628
  };
deba@2498
   629
deba@1866
   630
  /// \ingroup semi_adaptors
deba@1842
   631
  ///
deba@1842
   632
  /// \brief Graph using a node set of another graph and an
klao@1909
   633
  /// own uedge set.
deba@1842
   634
  ///
deba@1842
   635
  /// This structure can be used to establish another graph over a node set
deba@1842
   636
  /// of an existing one. The node iterator will go through the nodes of the
deba@1842
   637
  /// original graph.
deba@1842
   638
  ///
deba@1842
   639
  /// \param _Graph The type of the graph which shares its node set with 
alpar@2260
   640
  /// this class. Its interface must conform to the \ref concepts::Graph
deba@2111
   641
  /// "Graph" concept.
deba@1842
   642
  ///
deba@1842
   643
  /// In the edge extension and removing it conforms to the 
alpar@2260
   644
  /// \ref concepts::UGraph "UGraph" concept.
deba@1842
   645
  template <typename _Graph>
deba@2498
   646
  class ListUEdgeSet : public UEdgeSetExtender<ListUEdgeSetBase<_Graph> > {
deba@1842
   647
deba@1842
   648
  public:
deba@1842
   649
deba@2498
   650
    typedef UEdgeSetExtender<ListUEdgeSetBase<_Graph> > Parent;
deba@1842
   651
    
deba@1842
   652
    typedef typename Parent::Node Node;
deba@1842
   653
    typedef typename Parent::Edge Edge;
deba@1842
   654
    
deba@1842
   655
    typedef _Graph Graph;
deba@1842
   656
deba@1842
   657
deba@1842
   658
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1842
   659
deba@1842
   660
    void eraseNode(const Node& node) {
deba@1842
   661
      Edge edge;
deba@1842
   662
      Parent::firstOut(edge, node);
deba@1842
   663
      while (edge != INVALID ) {
deba@1842
   664
	erase(edge);
deba@1842
   665
	Parent::firstOut(edge, node);
deba@1842
   666
      } 
deba@1842
   667
deba@1842
   668
    }
deba@1842
   669
    
deba@1842
   670
    void clearNodes() {
deba@1842
   671
      Parent::clear();
deba@1842
   672
    }
deba@1842
   673
deba@1842
   674
    class NodesImpl : public NodesImplBase {
deba@1842
   675
    public:
deba@1842
   676
      typedef NodesImplBase Parent;
deba@1842
   677
      
klao@1909
   678
      NodesImpl(const Graph& graph, ListUEdgeSet& edgeset) 
deba@1842
   679
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   680
deba@1962
   681
      virtual ~NodesImpl() {}
deba@1842
   682
      
deba@1842
   683
    protected:
deba@1842
   684
deba@1842
   685
      virtual void erase(const Node& node) {
deba@1842
   686
	_edgeset.eraseNode(node);
deba@1842
   687
	Parent::erase(node);
deba@1842
   688
      }
deba@1866
   689
      virtual void erase(const std::vector<Node>& nodes) {
deba@2386
   690
	for (int i = 0; i < int(nodes.size()); ++i) {
deba@1866
   691
	  _edgeset.eraseNode(nodes[i]);
deba@1866
   692
	}
deba@1866
   693
	Parent::erase(nodes);
deba@1866
   694
      }
deba@1842
   695
      virtual void clear() {
deba@1842
   696
	_edgeset.clearNodes();
deba@1842
   697
	Parent::clear();
deba@1842
   698
      }
deba@1842
   699
deba@1842
   700
    private:
klao@1909
   701
      ListUEdgeSet& _edgeset;
deba@1842
   702
    };
deba@1842
   703
deba@1842
   704
    NodesImpl nodes;
deba@1842
   705
    
deba@1842
   706
  public:
deba@1842
   707
deba@1842
   708
    /// \brief Constructor of the adaptor.
deba@1842
   709
    /// 
deba@1842
   710
    /// Constructor of the adaptor.
klao@1909
   711
    ListUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1842
   712
      Parent::initalize(graph, nodes);
deba@1842
   713
    }
deba@1842
   714
    
deba@1842
   715
  };
deba@1842
   716
deba@1962
   717
  template <typename _Graph>
deba@1962
   718
  class SmartEdgeSetBase {
deba@1962
   719
  public:
deba@1962
   720
deba@1962
   721
    typedef _Graph Graph;
deba@1962
   722
    typedef typename Graph::Node Node;
deba@1962
   723
    typedef typename Graph::NodeIt NodeIt;
deba@1962
   724
deba@1962
   725
  protected:
deba@1962
   726
deba@1962
   727
    struct NodeT {
deba@1962
   728
      int first_out, first_in;
deba@1962
   729
      NodeT() : first_out(-1), first_in(-1) {}
deba@1962
   730
    };
deba@1962
   731
deba@1990
   732
    typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
deba@1962
   733
deba@1962
   734
    NodesImplBase* nodes;
deba@1962
   735
deba@1962
   736
    struct EdgeT {
deba@1962
   737
      Node source, target;
deba@1962
   738
      int next_out, next_in;
deba@1962
   739
      EdgeT() {}
deba@1962
   740
    };
deba@1962
   741
deba@1962
   742
    std::vector<EdgeT> edges;
deba@1962
   743
deba@1962
   744
    const Graph* graph;
deba@1962
   745
deba@1962
   746
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@1962
   747
      graph = &_graph;
deba@1962
   748
      nodes = &_nodes;
deba@1962
   749
    }
deba@1962
   750
    
deba@1962
   751
  public:
deba@1962
   752
deba@1962
   753
    class Edge {
deba@1962
   754
      friend class SmartEdgeSetBase<Graph>;
deba@1962
   755
    protected:
deba@1962
   756
      Edge(int _id) : id(_id) {}
deba@1962
   757
      int id;
deba@1962
   758
    public:
deba@1962
   759
      Edge() {}
deba@1962
   760
      Edge(Invalid) : id(-1) {}
deba@1962
   761
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@1962
   762
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@1962
   763
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@1962
   764
    };
deba@1962
   765
deba@1962
   766
    SmartEdgeSetBase() {} 
deba@1962
   767
deba@2386
   768
    Edge addEdge(const Node& u, const Node& v) {
deba@1962
   769
      int n = edges.size();
deba@1962
   770
      edges.push_back(EdgeT());
deba@2386
   771
      edges[n].next_in = (*nodes)[v].first_in;
deba@2386
   772
      (*nodes)[v].first_in = n;
deba@2386
   773
      edges[n].next_out = (*nodes)[u].first_out;
deba@2386
   774
      (*nodes)[u].first_out = n;
deba@2386
   775
      edges[n].source = u;
deba@2386
   776
      edges[n].target = v;
deba@1962
   777
      return Edge(n);
deba@1962
   778
    }
deba@1962
   779
deba@1962
   780
    void clear() {
deba@1962
   781
      Node node;
deba@1962
   782
      for (first(node); node != INVALID; next(node)) {
deba@1962
   783
        (*nodes)[node].first_in = -1;
deba@1962
   784
        (*nodes)[node].first_out = -1;
deba@1962
   785
      }
deba@1962
   786
      edges.clear();
deba@1962
   787
    }
deba@1962
   788
deba@1962
   789
    void first(Node& node) const {
deba@1962
   790
      graph->first(node);
deba@1962
   791
    }
deba@1962
   792
deba@1962
   793
    void next(Node& node) const {
deba@1962
   794
      graph->next(node);
deba@1962
   795
    }
deba@1962
   796
deba@1962
   797
    void first(Edge& edge) const {
deba@1962
   798
      edge.id = edges.size() - 1;
deba@1962
   799
    }
deba@1962
   800
deba@1962
   801
    void next(Edge& edge) const {
deba@1962
   802
      --edge.id;
deba@1962
   803
    }
deba@1962
   804
deba@1962
   805
    void firstOut(Edge& edge, const Node& node) const {
deba@1962
   806
      edge.id = (*nodes)[node].first_out;    
deba@1962
   807
    }
deba@1962
   808
    
deba@1962
   809
    void nextOut(Edge& edge) const {
deba@1962
   810
      edge.id = edges[edge.id].next_out;        
deba@1962
   811
    }
deba@1962
   812
deba@1962
   813
    void firstIn(Edge& edge, const Node& node) const {
deba@1962
   814
      edge.id = (*nodes)[node].first_in;          
deba@1962
   815
    }
deba@1962
   816
deba@1962
   817
    void nextIn(Edge& edge) const {
deba@1962
   818
      edge.id = edges[edge.id].next_in;    
deba@1962
   819
    }
deba@1962
   820
deba@1962
   821
    int id(const Node& node) const { return graph->id(node); }
deba@1962
   822
    int id(const Edge& edge) const { return edge.id; }
deba@1962
   823
deba@2386
   824
    Node nodeFromId(int ix) const { return graph->nodeFromId(ix); }
deba@2386
   825
    Edge edgeFromId(int ix) const { return Edge(ix); }
deba@1962
   826
deba@1962
   827
    int maxNodeId() const { return graph->maxNodeId(); };
deba@1962
   828
    int maxEdgeId() const { return edges.size() - 1; }
deba@1962
   829
deba@1962
   830
    Node source(const Edge& edge) const { return edges[edge.id].source;}
deba@1962
   831
    Node target(const Edge& edge) const { return edges[edge.id].target;}
deba@1962
   832
deba@1990
   833
    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
deba@1990
   834
deba@2384
   835
    NodeNotifier& notifier(Node) const {
deba@2384
   836
      return graph->notifier(Node());
deba@1990
   837
    } 
deba@1990
   838
deba@1962
   839
    template <typename _Value>
deba@1962
   840
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@1962
   841
    public:
deba@2031
   842
deba@1962
   843
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@2031
   844
deba@1962
   845
      explicit NodeMap(const SmartEdgeSetBase<Graph>& edgeset) 
deba@1962
   846
	: Parent(*edgeset.graph) { }
deba@2031
   847
deba@1962
   848
      NodeMap(const SmartEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@1962
   849
	: Parent(*edgeset.graph, value) { }
deba@2031
   850
deba@2031
   851
      NodeMap& operator=(const NodeMap& cmap) {
deba@2031
   852
        return operator=<NodeMap>(cmap);
deba@2031
   853
      }
deba@2031
   854
deba@2031
   855
      template <typename CMap>
deba@2031
   856
      NodeMap& operator=(const CMap& cmap) {
deba@2031
   857
        Parent::operator=(cmap);
deba@2031
   858
        return *this;
deba@2031
   859
      }
deba@1962
   860
    };
deba@1962
   861
deba@1962
   862
  };
deba@1962
   863
deba@1962
   864
deba@1962
   865
  /// \ingroup semi_adaptors
deba@1962
   866
  ///
deba@1962
   867
  /// \brief Graph using a node set of another graph and an
deba@1962
   868
  /// own edge set.
deba@1962
   869
  ///
deba@1962
   870
  /// This structure can be used to establish another graph over a node set
deba@1962
   871
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
   872
  /// original graph.
deba@1962
   873
  ///
deba@1962
   874
  /// \param _Graph The type of the graph which shares its node set with 
alpar@2260
   875
  /// this class. Its interface must conform to the \ref concepts::Graph
deba@2111
   876
  /// "Graph" concept.
deba@1962
   877
  ///
deba@1962
   878
  /// In the edge extension and removing it conforms to the 
alpar@2260
   879
  /// \ref concepts::Graph "Graph" concept.
deba@1962
   880
  template <typename _Graph>
deba@1979
   881
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<_Graph> > {
deba@1962
   882
deba@1962
   883
  public:
deba@1962
   884
deba@1979
   885
    typedef EdgeSetExtender<SmartEdgeSetBase<_Graph> > Parent;
deba@1962
   886
    
deba@1962
   887
    typedef typename Parent::Node Node;
deba@1962
   888
    typedef typename Parent::Edge Edge;
deba@1962
   889
    
deba@1962
   890
    typedef _Graph Graph;
deba@1962
   891
deba@1962
   892
  protected:
deba@1962
   893
deba@1962
   894
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
   895
deba@1999
   896
    void eraseNode(const Node& node) {
deba@1999
   897
      if (Parent::InEdgeIt(*this, node) == INVALID &&
deba@1999
   898
          Parent::OutEdgeIt(*this, node) == INVALID) {
deba@1999
   899
        return;
deba@1999
   900
      }
deba@2191
   901
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@1962
   902
    }
deba@1962
   903
    
deba@1962
   904
    void clearNodes() {
deba@1962
   905
      Parent::clear();
deba@1962
   906
    }
deba@1962
   907
deba@1962
   908
    class NodesImpl : public NodesImplBase {
deba@1962
   909
    public:
deba@1962
   910
      typedef NodesImplBase Parent;
deba@1962
   911
      
deba@1962
   912
      NodesImpl(const Graph& graph, SmartEdgeSet& edgeset) 
deba@1962
   913
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
   914
deba@1962
   915
      virtual ~NodesImpl() {}
deba@1962
   916
      
deba@2193
   917
      bool attached() const {
deba@2193
   918
        return Parent::attached();
deba@2193
   919
      }
deba@2193
   920
deba@1962
   921
    protected:
deba@1962
   922
deba@1962
   923
      virtual void erase(const Node& node) {
deba@2191
   924
        try {
deba@2191
   925
          _edgeset.eraseNode(node);
deba@2191
   926
          Parent::erase(node);
deba@2191
   927
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
   928
          Parent::clear();
deba@2193
   929
          throw;
deba@2191
   930
        }
deba@1962
   931
      }
deba@1962
   932
      virtual void erase(const std::vector<Node>& nodes) {
deba@2191
   933
        try {
deba@2386
   934
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@2191
   935
            _edgeset.eraseNode(nodes[i]);
deba@2191
   936
          }
deba@2191
   937
          Parent::erase(nodes);
deba@2191
   938
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
   939
          Parent::clear();
deba@2193
   940
          throw;
deba@1962
   941
        }
deba@1962
   942
      }
deba@1962
   943
      virtual void clear() {
deba@1962
   944
	_edgeset.clearNodes();
deba@1962
   945
	Parent::clear();
deba@1962
   946
      }
deba@1962
   947
deba@1962
   948
    private:
deba@1962
   949
      SmartEdgeSet& _edgeset;
deba@1962
   950
    };
deba@1962
   951
deba@1962
   952
    NodesImpl nodes;
deba@1962
   953
    
deba@1962
   954
  public:
deba@1962
   955
deba@1962
   956
    /// \brief Constructor of the adaptor.
deba@1962
   957
    /// 
deba@1962
   958
    /// Constructor of the adaptor.
deba@1962
   959
    SmartEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
   960
      Parent::initalize(graph, nodes);
deba@1962
   961
    }
deba@2193
   962
deba@2193
   963
    bool valid() const {
deba@2193
   964
      return nodes.attached();
deba@2193
   965
    }
deba@1962
   966
    
deba@1962
   967
  };
deba@1962
   968
deba@2498
   969
deba@2498
   970
  template <typename _Graph>
deba@2498
   971
  class SmartUEdgeSetBase {
deba@2498
   972
  public:
deba@2498
   973
deba@2498
   974
    typedef _Graph Graph;
deba@2498
   975
    typedef typename Graph::Node Node;
deba@2498
   976
    typedef typename Graph::NodeIt NodeIt;
deba@2498
   977
deba@2498
   978
  protected:
deba@2498
   979
deba@2498
   980
    struct NodeT {
deba@2498
   981
      int first_out;
deba@2498
   982
      NodeT() : first_out(-1) {}
deba@2498
   983
    };
deba@2498
   984
deba@2498
   985
    typedef DefaultMap<Graph, Node, NodeT> NodesImplBase;
deba@2498
   986
deba@2498
   987
    NodesImplBase* nodes;
deba@2498
   988
deba@2498
   989
    struct EdgeT {
deba@2498
   990
      Node target;
deba@2498
   991
      int next_out;
deba@2498
   992
      EdgeT() {}
deba@2498
   993
    };
deba@2498
   994
deba@2498
   995
    std::vector<EdgeT> edges;
deba@2498
   996
deba@2498
   997
    const Graph* graph;
deba@2498
   998
deba@2498
   999
    void initalize(const Graph& _graph, NodesImplBase& _nodes) {
deba@2498
  1000
      graph = &_graph;
deba@2498
  1001
      nodes = &_nodes;
deba@2498
  1002
    }
deba@2498
  1003
    
deba@2498
  1004
  public:
deba@2498
  1005
deba@2498
  1006
    class UEdge {
deba@2498
  1007
      friend class SmartUEdgeSetBase;
deba@2498
  1008
    protected:
deba@2498
  1009
deba@2498
  1010
      int id;
deba@2498
  1011
      explicit UEdge(int _id) { id = _id;}
deba@2498
  1012
deba@2498
  1013
    public:
deba@2498
  1014
      UEdge() {}
deba@2498
  1015
      UEdge (Invalid) { id = -1; }
deba@2498
  1016
      bool operator==(const UEdge& edge) const {return id == edge.id;}
deba@2498
  1017
      bool operator!=(const UEdge& edge) const {return id != edge.id;}
deba@2498
  1018
      bool operator<(const UEdge& edge) const {return id < edge.id;}
deba@2498
  1019
    };
deba@2498
  1020
deba@2498
  1021
    class Edge {
deba@2498
  1022
      friend class SmartUEdgeSetBase;
deba@2498
  1023
    protected:
deba@2498
  1024
      Edge(int _id) : id(_id) {}
deba@2498
  1025
      int id;
deba@2498
  1026
    public:
deba@2498
  1027
      operator UEdge() const { return uEdgeFromId(id / 2); }
deba@2498
  1028
deba@2498
  1029
      Edge() {}
deba@2498
  1030
      Edge(Invalid) : id(-1) {}
deba@2498
  1031
      bool operator==(const Edge& edge) const { return id == edge.id; }
deba@2498
  1032
      bool operator!=(const Edge& edge) const { return id != edge.id; }
deba@2498
  1033
      bool operator<(const Edge& edge) const { return id < edge.id; }
deba@2498
  1034
    };
deba@2498
  1035
deba@2498
  1036
    SmartUEdgeSetBase() {} 
deba@2498
  1037
deba@2498
  1038
    UEdge addEdge(const Node& u, const Node& v) {
deba@2498
  1039
      int n = edges.size();
deba@2498
  1040
      edges.push_back(EdgeT());
deba@2498
  1041
      edges.push_back(EdgeT());
deba@2498
  1042
      
deba@2498
  1043
      edges[n].target = u;
deba@2498
  1044
      edges[n | 1].target = v;
deba@2498
  1045
deba@2498
  1046
      edges[n].next_out = (*nodes)[v].first_out;
deba@2498
  1047
      (*nodes)[v].first_out = n;
deba@2498
  1048
deba@2498
  1049
      edges[n | 1].next_out = (*nodes)[u].first_out;	
deba@2498
  1050
      (*nodes)[u].first_out = (n | 1);
deba@2498
  1051
deba@2498
  1052
      return UEdge(n / 2);
deba@2498
  1053
    }
deba@2498
  1054
deba@2498
  1055
    void clear() {
deba@2498
  1056
      Node node;
deba@2498
  1057
      for (first(node); node != INVALID; next(node)) {
deba@2498
  1058
        (*nodes)[node].first_out = -1;
deba@2498
  1059
      }
deba@2498
  1060
      edges.clear();
deba@2498
  1061
    }
deba@2498
  1062
deba@2498
  1063
    void first(Node& node) const {
deba@2498
  1064
      graph->first(node);
deba@2498
  1065
    }
deba@2498
  1066
deba@2498
  1067
    void next(Node& node) const {
deba@2498
  1068
      graph->next(node);
deba@2498
  1069
    }
deba@2498
  1070
deba@2498
  1071
    void first(Edge& edge) const { 
deba@2498
  1072
      edge.id = edges.size() - 1;
deba@2498
  1073
    }
deba@2498
  1074
deba@2498
  1075
    void next(Edge& edge) const {
deba@2498
  1076
      --edge.id;
deba@2498
  1077
    }
deba@2498
  1078
deba@2498
  1079
    void first(UEdge& edge) const { 
deba@2498
  1080
      edge.id = edges.size() / 2 - 1;
deba@2498
  1081
    }
deba@2498
  1082
deba@2498
  1083
    void next(UEdge& edge) const {
deba@2498
  1084
      --edge.id;
deba@2498
  1085
    }
deba@2498
  1086
deba@2498
  1087
    void firstOut(Edge& edge, const Node& node) const {
deba@2498
  1088
      edge.id = (*nodes)[node].first_out;    
deba@2498
  1089
    }
deba@2498
  1090
    
deba@2498
  1091
    void nextOut(Edge& edge) const {
deba@2498
  1092
      edge.id = edges[edge.id].next_out;        
deba@2498
  1093
    }
deba@2498
  1094
deba@2498
  1095
    void firstIn(Edge& edge, const Node& node) const {
deba@2498
  1096
      edge.id = (((*nodes)[node].first_out) ^ 1);
deba@2498
  1097
      if (edge.id == -2) edge.id = -1;
deba@2498
  1098
    }
deba@2498
  1099
deba@2498
  1100
    void nextIn(Edge& edge) const {
deba@2498
  1101
      edge.id = ((edges[edge.id ^ 1].next_out) ^ 1);
deba@2498
  1102
      if (edge.id == -2) edge.id = -1;
deba@2498
  1103
    }
deba@2498
  1104
deba@2498
  1105
    void firstInc(UEdge &edge, bool& dir, const Node& node) const {
deba@2498
  1106
      int de = (*nodes)[node].first_out;
deba@2498
  1107
      if (de != -1 ) {
deba@2498
  1108
        edge.id = de / 2;
deba@2498
  1109
        dir = ((de & 1) == 1);
deba@2498
  1110
      } else {
deba@2498
  1111
        edge.id = -1;
deba@2498
  1112
        dir = true;
deba@2498
  1113
      }
deba@2498
  1114
    }
deba@2498
  1115
    void nextInc(UEdge &edge, bool& dir) const {
deba@2498
  1116
      int de = (edges[(edge.id * 2) | (dir ? 1 : 0)].next_out);
deba@2498
  1117
      if (de != -1 ) {
deba@2498
  1118
        edge.id = de / 2;
deba@2498
  1119
        dir = ((de & 1) == 1);
deba@2498
  1120
      } else {
deba@2498
  1121
        edge.id = -1;
deba@2498
  1122
        dir = true;
deba@2498
  1123
      }
deba@2498
  1124
    }
deba@2498
  1125
deba@2498
  1126
    static bool direction(Edge edge) {
deba@2498
  1127
      return (edge.id & 1) == 1;
deba@2498
  1128
    }
deba@2498
  1129
deba@2498
  1130
    static Edge direct(UEdge uedge, bool dir) {
deba@2498
  1131
      return Edge(uedge.id * 2 + (dir ? 1 : 0));
deba@2498
  1132
    }
deba@2498
  1133
deba@2498
  1134
    int id(Node node) const { return graph->id(node); }
deba@2498
  1135
    static int id(Edge edge) { return edge.id; }
deba@2498
  1136
    static int id(UEdge edge) { return edge.id; }
deba@2498
  1137
deba@2498
  1138
    Node nodeFromId(int id) const { return graph->nodeFromId(id); }
deba@2498
  1139
    static Edge edgeFromId(int id) { return Edge(id); }
deba@2498
  1140
    static UEdge uEdgeFromId(int id) { return UEdge(id);}
deba@2498
  1141
deba@2498
  1142
    int maxNodeId() const { return graph->maxNodeId(); };
deba@2498
  1143
    int maxEdgeId() const { return edges.size() - 1; }
deba@2498
  1144
    int maxUEdgeId() const { return edges.size() / 2 - 1; }
deba@2498
  1145
deba@2498
  1146
    Node source(Edge e) const { return edges[e.id ^ 1].target; }
deba@2498
  1147
    Node target(Edge e) const { return edges[e.id].target; }
deba@2498
  1148
deba@2498
  1149
    Node source(UEdge e) const { return edges[2 * e.id].target; }
deba@2498
  1150
    Node target(UEdge e) const { return edges[2 * e.id + 1].target; }
deba@2498
  1151
deba@2498
  1152
    typedef typename ItemSetTraits<Graph, Node>::ItemNotifier NodeNotifier;
deba@2498
  1153
deba@2498
  1154
    NodeNotifier& notifier(Node) const {
deba@2498
  1155
      return graph->notifier(Node());
deba@2498
  1156
    } 
deba@2498
  1157
deba@2498
  1158
    template <typename _Value>
deba@2498
  1159
    class NodeMap : public Graph::template NodeMap<_Value> {
deba@2498
  1160
    public:
deba@2498
  1161
deba@2498
  1162
      typedef typename _Graph::template NodeMap<_Value> Parent;
deba@2498
  1163
deba@2498
  1164
      explicit NodeMap(const SmartUEdgeSetBase<Graph>& edgeset) 
deba@2498
  1165
	: Parent(*edgeset.graph) { }
deba@2498
  1166
deba@2498
  1167
      NodeMap(const SmartUEdgeSetBase<Graph>& edgeset, const _Value& value)
deba@2498
  1168
	: Parent(*edgeset.graph, value) { }
deba@2498
  1169
deba@2498
  1170
      NodeMap& operator=(const NodeMap& cmap) {
deba@2498
  1171
        return operator=<NodeMap>(cmap);
deba@2498
  1172
      }
deba@2498
  1173
deba@2498
  1174
      template <typename CMap>
deba@2498
  1175
      NodeMap& operator=(const CMap& cmap) {
deba@2498
  1176
        Parent::operator=(cmap);
deba@2498
  1177
        return *this;
deba@2498
  1178
      }
deba@2498
  1179
    };
deba@2498
  1180
deba@2498
  1181
  };
deba@2498
  1182
deba@1962
  1183
  /// \ingroup semi_adaptors
deba@1962
  1184
  ///
deba@1962
  1185
  /// \brief Graph using a node set of another graph and an
deba@1962
  1186
  /// own uedge set.
deba@1962
  1187
  ///
deba@1962
  1188
  /// This structure can be used to establish another graph over a node set
deba@1962
  1189
  /// of an existing one. The node iterator will go through the nodes of the
deba@1962
  1190
  /// original graph.
deba@1962
  1191
  ///
deba@1962
  1192
  /// \param _Graph The type of the graph which shares its node set with 
alpar@2260
  1193
  /// this class. Its interface must conform to the \ref concepts::Graph
deba@2111
  1194
  /// "Graph" concept.
deba@1962
  1195
  ///
deba@1962
  1196
  /// In the edge extension and removing it conforms to the 
alpar@2260
  1197
  /// \ref concepts::UGraph "UGraph" concept.
deba@1962
  1198
  template <typename _Graph>
deba@2498
  1199
  class SmartUEdgeSet : public UEdgeSetExtender<SmartUEdgeSetBase<_Graph> > {
deba@1962
  1200
deba@1962
  1201
  public:
deba@1962
  1202
deba@2498
  1203
    typedef UEdgeSetExtender<SmartUEdgeSetBase<_Graph> > Parent;
deba@1962
  1204
    
deba@1962
  1205
    typedef typename Parent::Node Node;
deba@1962
  1206
    typedef typename Parent::Edge Edge;
deba@1962
  1207
    
deba@1962
  1208
    typedef _Graph Graph;
deba@1962
  1209
deba@1962
  1210
  protected:
deba@1962
  1211
deba@1962
  1212
    typedef typename Parent::NodesImplBase NodesImplBase;
deba@1962
  1213
deba@1999
  1214
    void eraseNode(const Node& node) {
deba@2031
  1215
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
deba@1999
  1216
        return;
deba@1999
  1217
      }
deba@2191
  1218
      throw typename NodesImplBase::Notifier::ImmediateDetach();
deba@1962
  1219
    }
deba@1962
  1220
    
deba@1962
  1221
    void clearNodes() {
deba@1962
  1222
      Parent::clear();
deba@1962
  1223
    }
deba@1962
  1224
deba@1962
  1225
    class NodesImpl : public NodesImplBase {
deba@1962
  1226
    public:
deba@1962
  1227
      typedef NodesImplBase Parent;
deba@1962
  1228
      
deba@1962
  1229
      NodesImpl(const Graph& graph, SmartUEdgeSet& edgeset) 
deba@1962
  1230
	: Parent(graph), _edgeset(edgeset) {}
deba@1962
  1231
deba@1962
  1232
      virtual ~NodesImpl() {}
deba@2193
  1233
deba@2193
  1234
      bool attached() const {
deba@2193
  1235
        return Parent::attached();
deba@2193
  1236
      }
deba@1962
  1237
      
deba@1962
  1238
    protected:
deba@1962
  1239
deba@1962
  1240
      virtual void erase(const Node& node) {
deba@2191
  1241
        try {
deba@2191
  1242
          _edgeset.eraseNode(node);
deba@2191
  1243
          Parent::erase(node);
deba@2191
  1244
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
  1245
          Parent::clear();
deba@2192
  1246
          throw;
deba@2191
  1247
        }
deba@1962
  1248
      }
deba@1962
  1249
      virtual void erase(const std::vector<Node>& nodes) {
deba@2191
  1250
        try {
deba@2386
  1251
          for (int i = 0; i < int(nodes.size()); ++i) {
deba@2191
  1252
            _edgeset.eraseNode(nodes[i]);
deba@2191
  1253
          }
deba@2191
  1254
          Parent::erase(nodes);
deba@2191
  1255
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
deba@2191
  1256
          Parent::clear();
deba@2192
  1257
          throw;
deba@2191
  1258
        }
deba@1962
  1259
      }
deba@1962
  1260
      virtual void clear() {
deba@1962
  1261
	_edgeset.clearNodes();
deba@1962
  1262
	Parent::clear();
deba@1962
  1263
      }
deba@1962
  1264
deba@1962
  1265
    private:
deba@1962
  1266
      SmartUEdgeSet& _edgeset;
deba@1962
  1267
    };
deba@1962
  1268
deba@1962
  1269
    NodesImpl nodes;
deba@1962
  1270
    
deba@1962
  1271
  public:
deba@1962
  1272
deba@1962
  1273
    /// \brief Constructor of the adaptor.
deba@1962
  1274
    /// 
deba@1962
  1275
    /// Constructor of the adaptor.
deba@1962
  1276
    SmartUEdgeSet(const Graph& graph) : nodes(graph, *this) {
deba@1962
  1277
      Parent::initalize(graph, nodes);
deba@1962
  1278
    }
deba@2193
  1279
deba@2193
  1280
    bool valid() const {
deba@2193
  1281
      return nodes.attached();
deba@2193
  1282
    }
deba@1962
  1283
    
deba@1962
  1284
  };
deba@1962
  1285
deba@1842
  1286
}
deba@1842
  1287
deba@1842
  1288
#endif