gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Add artificial addNode() function to the arc/edge set classes
0 1 0
default
1 file changed with 24 insertions and 0 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_EDGE_SET_H
20 20
#define LEMON_EDGE_SET_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/bits/edge_set_extender.h>
24 24

	
25 25
/// \ingroup graphs
26 26
/// \file
27 27
/// \brief ArcSet and EdgeSet classes.
28 28
///
29 29
/// Graphs which use another graph's node-set as own.
30 30
namespace lemon {
31 31

	
32 32
  template <typename GR>
33 33
  class ListArcSetBase {
34 34
  public:
35 35

	
36 36
    typedef typename GR::Node Node;
37 37
    typedef typename GR::NodeIt NodeIt;
38 38

	
39 39
  protected:
40 40

	
41 41
    struct NodeT {
42 42
      int first_out, first_in;
43 43
      NodeT() : first_out(-1), first_in(-1) {}
44 44
    };
45 45

	
46 46
    typedef typename ItemSetTraits<GR, Node>::
47 47
    template Map<NodeT>::Type NodesImplBase;
48 48

	
49 49
    NodesImplBase* _nodes;
50 50

	
51 51
    struct ArcT {
52 52
      Node source, target;
53 53
      int next_out, next_in;
54 54
      int prev_out, prev_in;
55 55
      ArcT() : prev_out(-1), prev_in(-1) {}
56 56
    };
57 57

	
58 58
    std::vector<ArcT> arcs;
59 59

	
60 60
    int first_arc;
61 61
    int first_free_arc;
62 62

	
63 63
    const GR* _graph;
64 64

	
65 65
    void initalize(const GR& graph, NodesImplBase& nodes) {
66 66
      _graph = &graph;
67 67
      _nodes = &nodes;
68 68
    }
69 69

	
70 70
  public:
71 71

	
72 72
    class Arc {
73 73
      friend class ListArcSetBase<GR>;
74 74
    protected:
75 75
      Arc(int _id) : id(_id) {}
76 76
      int id;
77 77
    public:
78 78
      Arc() {}
79 79
      Arc(Invalid) : id(-1) {}
80 80
      bool operator==(const Arc& arc) const { return id == arc.id; }
81 81
      bool operator!=(const Arc& arc) const { return id != arc.id; }
82 82
      bool operator<(const Arc& arc) const { return id < arc.id; }
83 83
    };
84 84

	
85 85
    ListArcSetBase() : first_arc(-1), first_free_arc(-1) {}
86 86

	
87
    Node addNode() {
88
      LEMON_ASSERT(false,
89
        "This graph structure does not support node insertion");
90
      return INVALID; // avoid warning
91
    }
92

	
87 93
    Arc addArc(const Node& u, const Node& v) {
88 94
      int n;
89 95
      if (first_free_arc == -1) {
90 96
        n = arcs.size();
91 97
        arcs.push_back(ArcT());
92 98
      } else {
93 99
        n = first_free_arc;
94 100
        first_free_arc = arcs[first_free_arc].next_in;
95 101
      }
96 102
      arcs[n].next_in = (*_nodes)[v].first_in;
97 103
      if ((*_nodes)[v].first_in != -1) {
98 104
        arcs[(*_nodes)[v].first_in].prev_in = n;
99 105
      }
100 106
      (*_nodes)[v].first_in = n;
101 107
      arcs[n].next_out = (*_nodes)[u].first_out;
102 108
      if ((*_nodes)[u].first_out != -1) {
103 109
        arcs[(*_nodes)[u].first_out].prev_out = n;
104 110
      }
105 111
      (*_nodes)[u].first_out = n;
106 112
      arcs[n].source = u;
107 113
      arcs[n].target = v;
108 114
      return Arc(n);
109 115
    }
110 116

	
111 117
    void erase(const Arc& arc) {
112 118
      int n = arc.id;
113 119
      if (arcs[n].prev_in != -1) {
114 120
        arcs[arcs[n].prev_in].next_in = arcs[n].next_in;
115 121
      } else {
116 122
        (*_nodes)[arcs[n].target].first_in = arcs[n].next_in;
117 123
      }
118 124
      if (arcs[n].next_in != -1) {
119 125
        arcs[arcs[n].next_in].prev_in = arcs[n].prev_in;
120 126
      }
121 127

	
122 128
      if (arcs[n].prev_out != -1) {
123 129
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
124 130
      } else {
125 131
        (*_nodes)[arcs[n].source].first_out = arcs[n].next_out;
126 132
      }
127 133
      if (arcs[n].next_out != -1) {
128 134
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
129 135
      }
130 136

	
131 137
    }
132 138

	
133 139
    void clear() {
134 140
      Node node;
135 141
      for (first(node); node != INVALID; next(node)) {
136 142
        (*_nodes)[node].first_in = -1;
137 143
        (*_nodes)[node].first_out = -1;
138 144
      }
139 145
      arcs.clear();
140 146
      first_arc = -1;
141 147
      first_free_arc = -1;
142 148
    }
143 149

	
144 150
    void first(Node& node) const {
145 151
      _graph->first(node);
146 152
    }
147 153

	
148 154
    void next(Node& node) const {
149 155
      _graph->next(node);
150 156
    }
151 157

	
152 158
    void first(Arc& arc) const {
153 159
      Node node;
154 160
      first(node);
155 161
      while (node != INVALID && (*_nodes)[node].first_in == -1) {
156 162
        next(node);
157 163
      }
158 164
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
159 165
    }
160 166

	
161 167
    void next(Arc& arc) const {
162 168
      if (arcs[arc.id].next_in != -1) {
163 169
        arc.id = arcs[arc.id].next_in;
164 170
      } else {
165 171
        Node node = arcs[arc.id].target;
166 172
        next(node);
167 173
        while (node != INVALID && (*_nodes)[node].first_in == -1) {
168 174
          next(node);
169 175
        }
170 176
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_in;
171 177
      }
172 178
    }
173 179

	
174 180
    void firstOut(Arc& arc, const Node& node) const {
175 181
      arc.id = (*_nodes)[node].first_out;
176 182
    }
177 183

	
178 184
    void nextOut(Arc& arc) const {
179 185
      arc.id = arcs[arc.id].next_out;
180 186
    }
181 187

	
182 188
    void firstIn(Arc& arc, const Node& node) const {
183 189
      arc.id = (*_nodes)[node].first_in;
184 190
    }
185 191

	
186 192
    void nextIn(Arc& arc) const {
187 193
      arc.id = arcs[arc.id].next_in;
188 194
    }
189 195

	
190 196
    int id(const Node& node) const { return _graph->id(node); }
191 197
    int id(const Arc& arc) const { return arc.id; }
192 198

	
193 199
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
194 200
    Arc arcFromId(int ix) const { return Arc(ix); }
195 201

	
196 202
    int maxNodeId() const { return _graph->maxNodeId(); };
197 203
    int maxArcId() const { return arcs.size() - 1; }
198 204

	
199 205
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
200 206
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
201 207

	
202 208
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
203 209

	
204 210
    NodeNotifier& notifier(Node) const {
205 211
      return _graph->notifier(Node());
206 212
    }
207 213

	
208 214
    template <typename V>
209 215
    class NodeMap : public GR::template NodeMap<V> {
210 216
      typedef typename GR::template NodeMap<V> Parent;
211 217

	
212 218
    public:
213 219

	
214 220
      explicit NodeMap(const ListArcSetBase<GR>& arcset)
215 221
        : Parent(*arcset._graph) {}
216 222

	
217 223
      NodeMap(const ListArcSetBase<GR>& arcset, const V& value)
218 224
        : Parent(*arcset._graph, value) {}
219 225

	
220 226
      NodeMap& operator=(const NodeMap& cmap) {
221 227
        return operator=<NodeMap>(cmap);
222 228
      }
223 229

	
224 230
      template <typename CMap>
225 231
      NodeMap& operator=(const CMap& cmap) {
226 232
        Parent::operator=(cmap);
227 233
        return *this;
228 234
      }
229 235
    };
230 236

	
231 237
  };
232 238

	
233 239
  /// \ingroup graphs
234 240
  ///
235 241
  /// \brief Digraph using a node set of another digraph or graph and
236 242
  /// an own arc set.
237 243
  ///
238 244
  /// This structure can be used to establish another directed graph
239 245
  /// over a node set of an existing one. This class uses the same
240 246
  /// Node type as the underlying graph, and each valid node of the
241 247
  /// original graph is valid in this arc set, therefore the node
242 248
  /// objects of the original graph can be used directly with this
243 249
  /// class. The node handling functions (id handling, observing, and
244 250
  /// iterators) works equivalently as in the original graph.
245 251
  ///
246 252
  /// This implementation is based on doubly-linked lists, from each
247 253
  /// node the outgoing and the incoming arcs make up lists, therefore
248 254
  /// one arc can be erased in constant time. It also makes possible,
249 255
  /// that node can be removed from the underlying graph, in this case
250 256
  /// all arcs incident to the given node is erased from the arc set.
251 257
  ///
252 258
  /// \param GR The type of the graph which shares its node set with
253 259
  /// this class. Its interface must conform to the
254 260
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
255 261
  /// concept.
256 262
  ///
257 263
  /// This class fully conforms to the \ref concepts::Digraph
258 264
  /// "Digraph" concept.
259 265
  template <typename GR>
260 266
  class ListArcSet : public ArcSetExtender<ListArcSetBase<GR> > {
261 267
    typedef ArcSetExtender<ListArcSetBase<GR> > Parent;
262 268

	
263 269
  public:
264 270

	
265 271
    typedef typename Parent::Node Node;
266 272
    typedef typename Parent::Arc Arc;
267 273

	
268 274
    typedef typename Parent::NodesImplBase NodesImplBase;
269 275

	
270 276
    void eraseNode(const Node& node) {
271 277
      Arc arc;
272 278
      Parent::firstOut(arc, node);
273 279
      while (arc != INVALID ) {
274 280
        erase(arc);
275 281
        Parent::firstOut(arc, node);
276 282
      }
277 283

	
278 284
      Parent::firstIn(arc, node);
279 285
      while (arc != INVALID ) {
280 286
        erase(arc);
281 287
        Parent::firstIn(arc, node);
282 288
      }
283 289
    }
284 290

	
285 291
    void clearNodes() {
286 292
      Parent::clear();
287 293
    }
288 294

	
289 295
    class NodesImpl : public NodesImplBase {
290 296
      typedef NodesImplBase Parent;
291 297

	
292 298
    public:
293 299
      NodesImpl(const GR& graph, ListArcSet& arcset)
294 300
        : Parent(graph), _arcset(arcset) {}
295 301

	
296 302
      virtual ~NodesImpl() {}
297 303

	
298 304
    protected:
299 305

	
300 306
      virtual void erase(const Node& node) {
301 307
        _arcset.eraseNode(node);
302 308
        Parent::erase(node);
303 309
      }
304 310
      virtual void erase(const std::vector<Node>& nodes) {
305 311
        for (int i = 0; i < int(nodes.size()); ++i) {
306 312
          _arcset.eraseNode(nodes[i]);
307 313
        }
308 314
        Parent::erase(nodes);
309 315
      }
310 316
      virtual void clear() {
311 317
        _arcset.clearNodes();
312 318
        Parent::clear();
313 319
      }
314 320

	
315 321
    private:
316 322
      ListArcSet& _arcset;
317 323
    };
318 324

	
319 325
    NodesImpl _nodes;
320 326

	
321 327
  public:
322 328

	
323 329
    /// \brief Constructor of the ArcSet.
324 330
    ///
325 331
    /// Constructor of the ArcSet.
326 332
    ListArcSet(const GR& graph) : _nodes(graph, *this) {
327 333
      Parent::initalize(graph, _nodes);
328 334
    }
329 335

	
330 336
    /// \brief Add a new arc to the digraph.
331 337
    ///
332 338
    /// Add a new arc to the digraph with source node \c s
333 339
    /// and target node \c t.
334 340
    /// \return The new arc.
335 341
    Arc addArc(const Node& s, const Node& t) {
336 342
      return Parent::addArc(s, t);
337 343
    }
338 344

	
339 345
    /// \brief Erase an arc from the digraph.
340 346
    ///
341 347
    /// Erase an arc \c a from the digraph.
342 348
    void erase(const Arc& a) {
343 349
      return Parent::erase(a);
344 350
    }
345 351

	
346 352
  };
347 353

	
348 354
  template <typename GR>
349 355
  class ListEdgeSetBase {
350 356
  public:
351 357

	
352 358
    typedef typename GR::Node Node;
353 359
    typedef typename GR::NodeIt NodeIt;
354 360

	
355 361
  protected:
356 362

	
357 363
    struct NodeT {
358 364
      int first_out;
359 365
      NodeT() : first_out(-1) {}
360 366
    };
361 367

	
362 368
    typedef typename ItemSetTraits<GR, Node>::
363 369
    template Map<NodeT>::Type NodesImplBase;
364 370

	
365 371
    NodesImplBase* _nodes;
366 372

	
367 373
    struct ArcT {
368 374
      Node target;
369 375
      int prev_out, next_out;
370 376
      ArcT() : prev_out(-1), next_out(-1) {}
371 377
    };
372 378

	
373 379
    std::vector<ArcT> arcs;
374 380

	
375 381
    int first_arc;
376 382
    int first_free_arc;
377 383

	
378 384
    const GR* _graph;
379 385

	
380 386
    void initalize(const GR& graph, NodesImplBase& nodes) {
381 387
      _graph = &graph;
382 388
      _nodes = &nodes;
383 389
    }
384 390

	
385 391
  public:
386 392

	
387 393
    class Edge {
388 394
      friend class ListEdgeSetBase;
389 395
    protected:
390 396

	
391 397
      int id;
392 398
      explicit Edge(int _id) { id = _id;}
393 399

	
394 400
    public:
395 401
      Edge() {}
396 402
      Edge (Invalid) { id = -1; }
397 403
      bool operator==(const Edge& arc) const {return id == arc.id;}
398 404
      bool operator!=(const Edge& arc) const {return id != arc.id;}
399 405
      bool operator<(const Edge& arc) const {return id < arc.id;}
400 406
    };
401 407

	
402 408
    class Arc {
403 409
      friend class ListEdgeSetBase;
404 410
    protected:
405 411
      Arc(int _id) : id(_id) {}
406 412
      int id;
407 413
    public:
408 414
      operator Edge() const { return edgeFromId(id / 2); }
409 415

	
410 416
      Arc() {}
411 417
      Arc(Invalid) : id(-1) {}
412 418
      bool operator==(const Arc& arc) const { return id == arc.id; }
413 419
      bool operator!=(const Arc& arc) const { return id != arc.id; }
414 420
      bool operator<(const Arc& arc) const { return id < arc.id; }
415 421
    };
416 422

	
417 423
    ListEdgeSetBase() : first_arc(-1), first_free_arc(-1) {}
418 424

	
425
    Node addNode() {
426
      LEMON_ASSERT(false,
427
        "This graph structure does not support node insertion");
428
      return INVALID; // avoid warning
429
    }
430

	
419 431
    Edge addEdge(const Node& u, const Node& v) {
420 432
      int n;
421 433

	
422 434
      if (first_free_arc == -1) {
423 435
        n = arcs.size();
424 436
        arcs.push_back(ArcT());
425 437
        arcs.push_back(ArcT());
426 438
      } else {
427 439
        n = first_free_arc;
428 440
        first_free_arc = arcs[n].next_out;
429 441
      }
430 442

	
431 443
      arcs[n].target = u;
432 444
      arcs[n | 1].target = v;
433 445

	
434 446
      arcs[n].next_out = (*_nodes)[v].first_out;
435 447
      if ((*_nodes)[v].first_out != -1) {
436 448
        arcs[(*_nodes)[v].first_out].prev_out = n;
437 449
      }
438 450
      (*_nodes)[v].first_out = n;
439 451
      arcs[n].prev_out = -1;
440 452

	
441 453
      if ((*_nodes)[u].first_out != -1) {
442 454
        arcs[(*_nodes)[u].first_out].prev_out = (n | 1);
443 455
      }
444 456
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
445 457
      (*_nodes)[u].first_out = (n | 1);
446 458
      arcs[n | 1].prev_out = -1;
447 459

	
448 460
      return Edge(n / 2);
449 461
    }
450 462

	
451 463
    void erase(const Edge& arc) {
452 464
      int n = arc.id * 2;
453 465

	
454 466
      if (arcs[n].next_out != -1) {
455 467
        arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
456 468
      }
457 469

	
458 470
      if (arcs[n].prev_out != -1) {
459 471
        arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
460 472
      } else {
461 473
        (*_nodes)[arcs[n | 1].target].first_out = arcs[n].next_out;
462 474
      }
463 475

	
464 476
      if (arcs[n | 1].next_out != -1) {
465 477
        arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
466 478
      }
467 479

	
468 480
      if (arcs[n | 1].prev_out != -1) {
469 481
        arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
470 482
      } else {
471 483
        (*_nodes)[arcs[n].target].first_out = arcs[n | 1].next_out;
472 484
      }
473 485

	
474 486
      arcs[n].next_out = first_free_arc;
475 487
      first_free_arc = n;
476 488

	
477 489
    }
478 490

	
479 491
    void clear() {
480 492
      Node node;
481 493
      for (first(node); node != INVALID; next(node)) {
482 494
        (*_nodes)[node].first_out = -1;
483 495
      }
484 496
      arcs.clear();
485 497
      first_arc = -1;
486 498
      first_free_arc = -1;
487 499
    }
488 500

	
489 501
    void first(Node& node) const {
490 502
      _graph->first(node);
491 503
    }
492 504

	
493 505
    void next(Node& node) const {
494 506
      _graph->next(node);
495 507
    }
496 508

	
497 509
    void first(Arc& arc) const {
498 510
      Node node;
499 511
      first(node);
500 512
      while (node != INVALID && (*_nodes)[node].first_out == -1) {
501 513
        next(node);
502 514
      }
503 515
      arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
504 516
    }
505 517

	
506 518
    void next(Arc& arc) const {
507 519
      if (arcs[arc.id].next_out != -1) {
508 520
        arc.id = arcs[arc.id].next_out;
509 521
      } else {
510 522
        Node node = arcs[arc.id ^ 1].target;
511 523
        next(node);
512 524
        while(node != INVALID && (*_nodes)[node].first_out == -1) {
513 525
          next(node);
514 526
        }
515 527
        arc.id = (node == INVALID) ? -1 : (*_nodes)[node].first_out;
516 528
      }
517 529
    }
518 530

	
519 531
    void first(Edge& edge) const {
520 532
      Node node;
521 533
      first(node);
522 534
      while (node != INVALID) {
523 535
        edge.id = (*_nodes)[node].first_out;
524 536
        while ((edge.id & 1) != 1) {
525 537
          edge.id = arcs[edge.id].next_out;
526 538
        }
527 539
        if (edge.id != -1) {
528 540
          edge.id /= 2;
529 541
          return;
530 542
        }
531 543
        next(node);
532 544
      }
533 545
      edge.id = -1;
534 546
    }
535 547

	
536 548
    void next(Edge& edge) const {
537 549
      Node node = arcs[edge.id * 2].target;
538 550
      edge.id = arcs[(edge.id * 2) | 1].next_out;
539 551
      while ((edge.id & 1) != 1) {
540 552
        edge.id = arcs[edge.id].next_out;
541 553
      }
542 554
      if (edge.id != -1) {
543 555
        edge.id /= 2;
544 556
        return;
545 557
      }
546 558
      next(node);
547 559
      while (node != INVALID) {
548 560
        edge.id = (*_nodes)[node].first_out;
549 561
        while ((edge.id & 1) != 1) {
550 562
          edge.id = arcs[edge.id].next_out;
551 563
        }
552 564
        if (edge.id != -1) {
553 565
          edge.id /= 2;
554 566
          return;
555 567
        }
556 568
        next(node);
557 569
      }
558 570
      edge.id = -1;
559 571
    }
560 572

	
561 573
    void firstOut(Arc& arc, const Node& node) const {
562 574
      arc.id = (*_nodes)[node].first_out;
563 575
    }
564 576

	
565 577
    void nextOut(Arc& arc) const {
566 578
      arc.id = arcs[arc.id].next_out;
567 579
    }
568 580

	
569 581
    void firstIn(Arc& arc, const Node& node) const {
570 582
      arc.id = (((*_nodes)[node].first_out) ^ 1);
571 583
      if (arc.id == -2) arc.id = -1;
572 584
    }
573 585

	
574 586
    void nextIn(Arc& arc) const {
575 587
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
576 588
      if (arc.id == -2) arc.id = -1;
577 589
    }
578 590

	
579 591
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
580 592
      int de = (*_nodes)[node].first_out;
581 593
      if (de != -1 ) {
582 594
        arc.id = de / 2;
583 595
        dir = ((de & 1) == 1);
584 596
      } else {
585 597
        arc.id = -1;
586 598
        dir = true;
587 599
      }
588 600
    }
589 601
    void nextInc(Edge &arc, bool& dir) const {
590 602
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
591 603
      if (de != -1 ) {
592 604
        arc.id = de / 2;
593 605
        dir = ((de & 1) == 1);
594 606
      } else {
595 607
        arc.id = -1;
596 608
        dir = true;
597 609
      }
598 610
    }
599 611

	
600 612
    static bool direction(Arc arc) {
601 613
      return (arc.id & 1) == 1;
602 614
    }
603 615

	
604 616
    static Arc direct(Edge edge, bool dir) {
605 617
      return Arc(edge.id * 2 + (dir ? 1 : 0));
606 618
    }
607 619

	
608 620
    int id(const Node& node) const { return _graph->id(node); }
609 621
    static int id(Arc e) { return e.id; }
610 622
    static int id(Edge e) { return e.id; }
... ...
@@ -627,680 +639,692 @@
627 639

	
628 640
    NodeNotifier& notifier(Node) const {
629 641
      return _graph->notifier(Node());
630 642
    }
631 643

	
632 644
    template <typename V>
633 645
    class NodeMap : public GR::template NodeMap<V> {
634 646
      typedef typename GR::template NodeMap<V> Parent;
635 647

	
636 648
    public:
637 649

	
638 650
      explicit NodeMap(const ListEdgeSetBase<GR>& arcset)
639 651
        : Parent(*arcset._graph) {}
640 652

	
641 653
      NodeMap(const ListEdgeSetBase<GR>& arcset, const V& value)
642 654
        : Parent(*arcset._graph, value) {}
643 655

	
644 656
      NodeMap& operator=(const NodeMap& cmap) {
645 657
        return operator=<NodeMap>(cmap);
646 658
      }
647 659

	
648 660
      template <typename CMap>
649 661
      NodeMap& operator=(const CMap& cmap) {
650 662
        Parent::operator=(cmap);
651 663
        return *this;
652 664
      }
653 665
    };
654 666

	
655 667
  };
656 668

	
657 669
  /// \ingroup graphs
658 670
  ///
659 671
  /// \brief Graph using a node set of another digraph or graph and an
660 672
  /// own edge set.
661 673
  ///
662 674
  /// This structure can be used to establish another graph over a
663 675
  /// node set of an existing one. This class uses the same Node type
664 676
  /// as the underlying graph, and each valid node of the original
665 677
  /// graph is valid in this arc set, therefore the node objects of
666 678
  /// the original graph can be used directly with this class. The
667 679
  /// node handling functions (id handling, observing, and iterators)
668 680
  /// works equivalently as in the original graph.
669 681
  ///
670 682
  /// This implementation is based on doubly-linked lists, from each
671 683
  /// node the incident edges make up lists, therefore one edge can be
672 684
  /// erased in constant time. It also makes possible, that node can
673 685
  /// be removed from the underlying graph, in this case all edges
674 686
  /// incident to the given node is erased from the arc set.
675 687
  ///
676 688
  /// \param GR The type of the graph which shares its node set
677 689
  /// with this class. Its interface must conform to the
678 690
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
679 691
  /// concept.
680 692
  ///
681 693
  /// This class fully conforms to the \ref concepts::Graph "Graph"
682 694
  /// concept.
683 695
  template <typename GR>
684 696
  class ListEdgeSet : public EdgeSetExtender<ListEdgeSetBase<GR> > {
685 697
    typedef EdgeSetExtender<ListEdgeSetBase<GR> > Parent;
686 698

	
687 699
  public:
688 700

	
689 701
    typedef typename Parent::Node Node;
690 702
    typedef typename Parent::Arc Arc;
691 703
    typedef typename Parent::Edge Edge;
692 704

	
693 705
    typedef typename Parent::NodesImplBase NodesImplBase;
694 706

	
695 707
    void eraseNode(const Node& node) {
696 708
      Arc arc;
697 709
      Parent::firstOut(arc, node);
698 710
      while (arc != INVALID ) {
699 711
        erase(arc);
700 712
        Parent::firstOut(arc, node);
701 713
      }
702 714

	
703 715
    }
704 716

	
705 717
    void clearNodes() {
706 718
      Parent::clear();
707 719
    }
708 720

	
709 721
    class NodesImpl : public NodesImplBase {
710 722
      typedef NodesImplBase Parent;
711 723

	
712 724
    public:
713 725
      NodesImpl(const GR& graph, ListEdgeSet& arcset)
714 726
        : Parent(graph), _arcset(arcset) {}
715 727

	
716 728
      virtual ~NodesImpl() {}
717 729

	
718 730
    protected:
719 731

	
720 732
      virtual void erase(const Node& node) {
721 733
        _arcset.eraseNode(node);
722 734
        Parent::erase(node);
723 735
      }
724 736
      virtual void erase(const std::vector<Node>& nodes) {
725 737
        for (int i = 0; i < int(nodes.size()); ++i) {
726 738
          _arcset.eraseNode(nodes[i]);
727 739
        }
728 740
        Parent::erase(nodes);
729 741
      }
730 742
      virtual void clear() {
731 743
        _arcset.clearNodes();
732 744
        Parent::clear();
733 745
      }
734 746

	
735 747
    private:
736 748
      ListEdgeSet& _arcset;
737 749
    };
738 750

	
739 751
    NodesImpl _nodes;
740 752

	
741 753
  public:
742 754

	
743 755
    /// \brief Constructor of the EdgeSet.
744 756
    ///
745 757
    /// Constructor of the EdgeSet.
746 758
    ListEdgeSet(const GR& graph) : _nodes(graph, *this) {
747 759
      Parent::initalize(graph, _nodes);
748 760
    }
749 761

	
750 762
    /// \brief Add a new edge to the graph.
751 763
    ///
752 764
    /// Add a new edge to the graph with node \c u
753 765
    /// and node \c v endpoints.
754 766
    /// \return The new edge.
755 767
    Edge addEdge(const Node& u, const Node& v) {
756 768
      return Parent::addEdge(u, v);
757 769
    }
758 770

	
759 771
    /// \brief Erase an edge from the graph.
760 772
    ///
761 773
    /// Erase the edge \c e from the graph.
762 774
    void erase(const Edge& e) {
763 775
      return Parent::erase(e);
764 776
    }
765 777

	
766 778
  };
767 779

	
768 780
  template <typename GR>
769 781
  class SmartArcSetBase {
770 782
  public:
771 783

	
772 784
    typedef typename GR::Node Node;
773 785
    typedef typename GR::NodeIt NodeIt;
774 786

	
775 787
  protected:
776 788

	
777 789
    struct NodeT {
778 790
      int first_out, first_in;
779 791
      NodeT() : first_out(-1), first_in(-1) {}
780 792
    };
781 793

	
782 794
    typedef typename ItemSetTraits<GR, Node>::
783 795
    template Map<NodeT>::Type NodesImplBase;
784 796

	
785 797
    NodesImplBase* _nodes;
786 798

	
787 799
    struct ArcT {
788 800
      Node source, target;
789 801
      int next_out, next_in;
790 802
      ArcT() {}
791 803
    };
792 804

	
793 805
    std::vector<ArcT> arcs;
794 806

	
795 807
    const GR* _graph;
796 808

	
797 809
    void initalize(const GR& graph, NodesImplBase& nodes) {
798 810
      _graph = &graph;
799 811
      _nodes = &nodes;
800 812
    }
801 813

	
802 814
  public:
803 815

	
804 816
    class Arc {
805 817
      friend class SmartArcSetBase<GR>;
806 818
    protected:
807 819
      Arc(int _id) : id(_id) {}
808 820
      int id;
809 821
    public:
810 822
      Arc() {}
811 823
      Arc(Invalid) : id(-1) {}
812 824
      bool operator==(const Arc& arc) const { return id == arc.id; }
813 825
      bool operator!=(const Arc& arc) const { return id != arc.id; }
814 826
      bool operator<(const Arc& arc) const { return id < arc.id; }
815 827
    };
816 828

	
817 829
    SmartArcSetBase() {}
818 830

	
831
    Node addNode() {
832
      LEMON_ASSERT(false,
833
        "This graph structure does not support node insertion");
834
      return INVALID; // avoid warning
835
    }
836

	
819 837
    Arc addArc(const Node& u, const Node& v) {
820 838
      int n = arcs.size();
821 839
      arcs.push_back(ArcT());
822 840
      arcs[n].next_in = (*_nodes)[v].first_in;
823 841
      (*_nodes)[v].first_in = n;
824 842
      arcs[n].next_out = (*_nodes)[u].first_out;
825 843
      (*_nodes)[u].first_out = n;
826 844
      arcs[n].source = u;
827 845
      arcs[n].target = v;
828 846
      return Arc(n);
829 847
    }
830 848

	
831 849
    void clear() {
832 850
      Node node;
833 851
      for (first(node); node != INVALID; next(node)) {
834 852
        (*_nodes)[node].first_in = -1;
835 853
        (*_nodes)[node].first_out = -1;
836 854
      }
837 855
      arcs.clear();
838 856
    }
839 857

	
840 858
    void first(Node& node) const {
841 859
      _graph->first(node);
842 860
    }
843 861

	
844 862
    void next(Node& node) const {
845 863
      _graph->next(node);
846 864
    }
847 865

	
848 866
    void first(Arc& arc) const {
849 867
      arc.id = arcs.size() - 1;
850 868
    }
851 869

	
852 870
    void next(Arc& arc) const {
853 871
      --arc.id;
854 872
    }
855 873

	
856 874
    void firstOut(Arc& arc, const Node& node) const {
857 875
      arc.id = (*_nodes)[node].first_out;
858 876
    }
859 877

	
860 878
    void nextOut(Arc& arc) const {
861 879
      arc.id = arcs[arc.id].next_out;
862 880
    }
863 881

	
864 882
    void firstIn(Arc& arc, const Node& node) const {
865 883
      arc.id = (*_nodes)[node].first_in;
866 884
    }
867 885

	
868 886
    void nextIn(Arc& arc) const {
869 887
      arc.id = arcs[arc.id].next_in;
870 888
    }
871 889

	
872 890
    int id(const Node& node) const { return _graph->id(node); }
873 891
    int id(const Arc& arc) const { return arc.id; }
874 892

	
875 893
    Node nodeFromId(int ix) const { return _graph->nodeFromId(ix); }
876 894
    Arc arcFromId(int ix) const { return Arc(ix); }
877 895

	
878 896
    int maxNodeId() const { return _graph->maxNodeId(); };
879 897
    int maxArcId() const { return arcs.size() - 1; }
880 898

	
881 899
    Node source(const Arc& arc) const { return arcs[arc.id].source;}
882 900
    Node target(const Arc& arc) const { return arcs[arc.id].target;}
883 901

	
884 902
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
885 903

	
886 904
    NodeNotifier& notifier(Node) const {
887 905
      return _graph->notifier(Node());
888 906
    }
889 907

	
890 908
    template <typename V>
891 909
    class NodeMap : public GR::template NodeMap<V> {
892 910
      typedef typename GR::template NodeMap<V> Parent;
893 911

	
894 912
    public:
895 913

	
896 914
      explicit NodeMap(const SmartArcSetBase<GR>& arcset)
897 915
        : Parent(*arcset._graph) { }
898 916

	
899 917
      NodeMap(const SmartArcSetBase<GR>& arcset, const V& value)
900 918
        : Parent(*arcset._graph, value) { }
901 919

	
902 920
      NodeMap& operator=(const NodeMap& cmap) {
903 921
        return operator=<NodeMap>(cmap);
904 922
      }
905 923

	
906 924
      template <typename CMap>
907 925
      NodeMap& operator=(const CMap& cmap) {
908 926
        Parent::operator=(cmap);
909 927
        return *this;
910 928
      }
911 929
    };
912 930

	
913 931
  };
914 932

	
915 933

	
916 934
  /// \ingroup graphs
917 935
  ///
918 936
  /// \brief Digraph using a node set of another digraph or graph and
919 937
  /// an own arc set.
920 938
  ///
921 939
  /// This structure can be used to establish another directed graph
922 940
  /// over a node set of an existing one. This class uses the same
923 941
  /// Node type as the underlying graph, and each valid node of the
924 942
  /// original graph is valid in this arc set, therefore the node
925 943
  /// objects of the original graph can be used directly with this
926 944
  /// class. The node handling functions (id handling, observing, and
927 945
  /// iterators) works equivalently as in the original graph.
928 946
  ///
929 947
  /// \param GR The type of the graph which shares its node set with
930 948
  /// this class. Its interface must conform to the
931 949
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
932 950
  /// concept.
933 951
  ///
934 952
  /// This implementation is slightly faster than the \c ListArcSet,
935 953
  /// because it uses continuous storage for arcs and it uses just
936 954
  /// single-linked lists for enumerate outgoing and incoming
937 955
  /// arcs. Therefore the arcs cannot be erased from the arc sets.
938 956
  ///
939 957
  /// \warning If a node is erased from the underlying graph and this
940 958
  /// node is the source or target of one arc in the arc set, then
941 959
  /// the arc set is invalidated, and it cannot be used anymore. The
942 960
  /// validity can be checked with the \c valid() member function.
943 961
  ///
944 962
  /// This class fully conforms to the \ref concepts::Digraph
945 963
  /// "Digraph" concept.
946 964
  template <typename GR>
947 965
  class SmartArcSet : public ArcSetExtender<SmartArcSetBase<GR> > {
948 966
    typedef ArcSetExtender<SmartArcSetBase<GR> > Parent;
949 967

	
950 968
  public:
951 969

	
952 970
    typedef typename Parent::Node Node;
953 971
    typedef typename Parent::Arc Arc;
954 972

	
955 973
  protected:
956 974

	
957 975
    typedef typename Parent::NodesImplBase NodesImplBase;
958 976

	
959 977
    void eraseNode(const Node& node) {
960 978
      if (typename Parent::InArcIt(*this, node) == INVALID &&
961 979
          typename Parent::OutArcIt(*this, node) == INVALID) {
962 980
        return;
963 981
      }
964 982
      throw typename NodesImplBase::Notifier::ImmediateDetach();
965 983
    }
966 984

	
967 985
    void clearNodes() {
968 986
      Parent::clear();
969 987
    }
970 988

	
971 989
    class NodesImpl : public NodesImplBase {
972 990
      typedef NodesImplBase Parent;
973 991

	
974 992
    public:
975 993
      NodesImpl(const GR& graph, SmartArcSet& arcset)
976 994
        : Parent(graph), _arcset(arcset) {}
977 995

	
978 996
      virtual ~NodesImpl() {}
979 997

	
980 998
      bool attached() const {
981 999
        return Parent::attached();
982 1000
      }
983 1001

	
984 1002
    protected:
985 1003

	
986 1004
      virtual void erase(const Node& node) {
987 1005
        try {
988 1006
          _arcset.eraseNode(node);
989 1007
          Parent::erase(node);
990 1008
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
991 1009
          Parent::clear();
992 1010
          throw;
993 1011
        }
994 1012
      }
995 1013
      virtual void erase(const std::vector<Node>& nodes) {
996 1014
        try {
997 1015
          for (int i = 0; i < int(nodes.size()); ++i) {
998 1016
            _arcset.eraseNode(nodes[i]);
999 1017
          }
1000 1018
          Parent::erase(nodes);
1001 1019
        } catch (const typename NodesImplBase::Notifier::ImmediateDetach&) {
1002 1020
          Parent::clear();
1003 1021
          throw;
1004 1022
        }
1005 1023
      }
1006 1024
      virtual void clear() {
1007 1025
        _arcset.clearNodes();
1008 1026
        Parent::clear();
1009 1027
      }
1010 1028

	
1011 1029
    private:
1012 1030
      SmartArcSet& _arcset;
1013 1031
    };
1014 1032

	
1015 1033
    NodesImpl _nodes;
1016 1034

	
1017 1035
  public:
1018 1036

	
1019 1037
    /// \brief Constructor of the ArcSet.
1020 1038
    ///
1021 1039
    /// Constructor of the ArcSet.
1022 1040
    SmartArcSet(const GR& graph) : _nodes(graph, *this) {
1023 1041
      Parent::initalize(graph, _nodes);
1024 1042
    }
1025 1043

	
1026 1044
    /// \brief Add a new arc to the digraph.
1027 1045
    ///
1028 1046
    /// Add a new arc to the digraph with source node \c s
1029 1047
    /// and target node \c t.
1030 1048
    /// \return The new arc.
1031 1049
    Arc addArc(const Node& s, const Node& t) {
1032 1050
      return Parent::addArc(s, t);
1033 1051
    }
1034 1052

	
1035 1053
    /// \brief Validity check
1036 1054
    ///
1037 1055
    /// This functions gives back false if the ArcSet is
1038 1056
    /// invalidated. It occurs when a node in the underlying graph is
1039 1057
    /// erased and it is not isolated in the ArcSet.
1040 1058
    bool valid() const {
1041 1059
      return _nodes.attached();
1042 1060
    }
1043 1061

	
1044 1062
  };
1045 1063

	
1046 1064

	
1047 1065
  template <typename GR>
1048 1066
  class SmartEdgeSetBase {
1049 1067
  public:
1050 1068

	
1051 1069
    typedef typename GR::Node Node;
1052 1070
    typedef typename GR::NodeIt NodeIt;
1053 1071

	
1054 1072
  protected:
1055 1073

	
1056 1074
    struct NodeT {
1057 1075
      int first_out;
1058 1076
      NodeT() : first_out(-1) {}
1059 1077
    };
1060 1078

	
1061 1079
    typedef typename ItemSetTraits<GR, Node>::
1062 1080
    template Map<NodeT>::Type NodesImplBase;
1063 1081

	
1064 1082
    NodesImplBase* _nodes;
1065 1083

	
1066 1084
    struct ArcT {
1067 1085
      Node target;
1068 1086
      int next_out;
1069 1087
      ArcT() {}
1070 1088
    };
1071 1089

	
1072 1090
    std::vector<ArcT> arcs;
1073 1091

	
1074 1092
    const GR* _graph;
1075 1093

	
1076 1094
    void initalize(const GR& graph, NodesImplBase& nodes) {
1077 1095
      _graph = &graph;
1078 1096
      _nodes = &nodes;
1079 1097
    }
1080 1098

	
1081 1099
  public:
1082 1100

	
1083 1101
    class Edge {
1084 1102
      friend class SmartEdgeSetBase;
1085 1103
    protected:
1086 1104

	
1087 1105
      int id;
1088 1106
      explicit Edge(int _id) { id = _id;}
1089 1107

	
1090 1108
    public:
1091 1109
      Edge() {}
1092 1110
      Edge (Invalid) { id = -1; }
1093 1111
      bool operator==(const Edge& arc) const {return id == arc.id;}
1094 1112
      bool operator!=(const Edge& arc) const {return id != arc.id;}
1095 1113
      bool operator<(const Edge& arc) const {return id < arc.id;}
1096 1114
    };
1097 1115

	
1098 1116
    class Arc {
1099 1117
      friend class SmartEdgeSetBase;
1100 1118
    protected:
1101 1119
      Arc(int _id) : id(_id) {}
1102 1120
      int id;
1103 1121
    public:
1104 1122
      operator Edge() const { return edgeFromId(id / 2); }
1105 1123

	
1106 1124
      Arc() {}
1107 1125
      Arc(Invalid) : id(-1) {}
1108 1126
      bool operator==(const Arc& arc) const { return id == arc.id; }
1109 1127
      bool operator!=(const Arc& arc) const { return id != arc.id; }
1110 1128
      bool operator<(const Arc& arc) const { return id < arc.id; }
1111 1129
    };
1112 1130

	
1113 1131
    SmartEdgeSetBase() {}
1114 1132

	
1133
    Node addNode() {
1134
      LEMON_ASSERT(false,
1135
        "This graph structure does not support node insertion");
1136
      return INVALID; // avoid warning
1137
    }
1138

	
1115 1139
    Edge addEdge(const Node& u, const Node& v) {
1116 1140
      int n = arcs.size();
1117 1141
      arcs.push_back(ArcT());
1118 1142
      arcs.push_back(ArcT());
1119 1143

	
1120 1144
      arcs[n].target = u;
1121 1145
      arcs[n | 1].target = v;
1122 1146

	
1123 1147
      arcs[n].next_out = (*_nodes)[v].first_out;
1124 1148
      (*_nodes)[v].first_out = n;
1125 1149

	
1126 1150
      arcs[n | 1].next_out = (*_nodes)[u].first_out;
1127 1151
      (*_nodes)[u].first_out = (n | 1);
1128 1152

	
1129 1153
      return Edge(n / 2);
1130 1154
    }
1131 1155

	
1132 1156
    void clear() {
1133 1157
      Node node;
1134 1158
      for (first(node); node != INVALID; next(node)) {
1135 1159
        (*_nodes)[node].first_out = -1;
1136 1160
      }
1137 1161
      arcs.clear();
1138 1162
    }
1139 1163

	
1140 1164
    void first(Node& node) const {
1141 1165
      _graph->first(node);
1142 1166
    }
1143 1167

	
1144 1168
    void next(Node& node) const {
1145 1169
      _graph->next(node);
1146 1170
    }
1147 1171

	
1148 1172
    void first(Arc& arc) const {
1149 1173
      arc.id = arcs.size() - 1;
1150 1174
    }
1151 1175

	
1152 1176
    void next(Arc& arc) const {
1153 1177
      --arc.id;
1154 1178
    }
1155 1179

	
1156 1180
    void first(Edge& arc) const {
1157 1181
      arc.id = arcs.size() / 2 - 1;
1158 1182
    }
1159 1183

	
1160 1184
    void next(Edge& arc) const {
1161 1185
      --arc.id;
1162 1186
    }
1163 1187

	
1164 1188
    void firstOut(Arc& arc, const Node& node) const {
1165 1189
      arc.id = (*_nodes)[node].first_out;
1166 1190
    }
1167 1191

	
1168 1192
    void nextOut(Arc& arc) const {
1169 1193
      arc.id = arcs[arc.id].next_out;
1170 1194
    }
1171 1195

	
1172 1196
    void firstIn(Arc& arc, const Node& node) const {
1173 1197
      arc.id = (((*_nodes)[node].first_out) ^ 1);
1174 1198
      if (arc.id == -2) arc.id = -1;
1175 1199
    }
1176 1200

	
1177 1201
    void nextIn(Arc& arc) const {
1178 1202
      arc.id = ((arcs[arc.id ^ 1].next_out) ^ 1);
1179 1203
      if (arc.id == -2) arc.id = -1;
1180 1204
    }
1181 1205

	
1182 1206
    void firstInc(Edge &arc, bool& dir, const Node& node) const {
1183 1207
      int de = (*_nodes)[node].first_out;
1184 1208
      if (de != -1 ) {
1185 1209
        arc.id = de / 2;
1186 1210
        dir = ((de & 1) == 1);
1187 1211
      } else {
1188 1212
        arc.id = -1;
1189 1213
        dir = true;
1190 1214
      }
1191 1215
    }
1192 1216
    void nextInc(Edge &arc, bool& dir) const {
1193 1217
      int de = (arcs[(arc.id * 2) | (dir ? 1 : 0)].next_out);
1194 1218
      if (de != -1 ) {
1195 1219
        arc.id = de / 2;
1196 1220
        dir = ((de & 1) == 1);
1197 1221
      } else {
1198 1222
        arc.id = -1;
1199 1223
        dir = true;
1200 1224
      }
1201 1225
    }
1202 1226

	
1203 1227
    static bool direction(Arc arc) {
1204 1228
      return (arc.id & 1) == 1;
1205 1229
    }
1206 1230

	
1207 1231
    static Arc direct(Edge edge, bool dir) {
1208 1232
      return Arc(edge.id * 2 + (dir ? 1 : 0));
1209 1233
    }
1210 1234

	
1211 1235
    int id(Node node) const { return _graph->id(node); }
1212 1236
    static int id(Arc arc) { return arc.id; }
1213 1237
    static int id(Edge arc) { return arc.id; }
1214 1238

	
1215 1239
    Node nodeFromId(int id) const { return _graph->nodeFromId(id); }
1216 1240
    static Arc arcFromId(int id) { return Arc(id); }
1217 1241
    static Edge edgeFromId(int id) { return Edge(id);}
1218 1242

	
1219 1243
    int maxNodeId() const { return _graph->maxNodeId(); };
1220 1244
    int maxArcId() const { return arcs.size() - 1; }
1221 1245
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
1222 1246

	
1223 1247
    Node source(Arc e) const { return arcs[e.id ^ 1].target; }
1224 1248
    Node target(Arc e) const { return arcs[e.id].target; }
1225 1249

	
1226 1250
    Node u(Edge e) const { return arcs[2 * e.id].target; }
1227 1251
    Node v(Edge e) const { return arcs[2 * e.id + 1].target; }
1228 1252

	
1229 1253
    typedef typename ItemSetTraits<GR, Node>::ItemNotifier NodeNotifier;
1230 1254

	
1231 1255
    NodeNotifier& notifier(Node) const {
1232 1256
      return _graph->notifier(Node());
1233 1257
    }
1234 1258

	
1235 1259
    template <typename V>
1236 1260
    class NodeMap : public GR::template NodeMap<V> {
1237 1261
      typedef typename GR::template NodeMap<V> Parent;
1238 1262

	
1239 1263
    public:
1240 1264

	
1241 1265
      explicit NodeMap(const SmartEdgeSetBase<GR>& arcset)
1242 1266
        : Parent(*arcset._graph) { }
1243 1267

	
1244 1268
      NodeMap(const SmartEdgeSetBase<GR>& arcset, const V& value)
1245 1269
        : Parent(*arcset._graph, value) { }
1246 1270

	
1247 1271
      NodeMap& operator=(const NodeMap& cmap) {
1248 1272
        return operator=<NodeMap>(cmap);
1249 1273
      }
1250 1274

	
1251 1275
      template <typename CMap>
1252 1276
      NodeMap& operator=(const CMap& cmap) {
1253 1277
        Parent::operator=(cmap);
1254 1278
        return *this;
1255 1279
      }
1256 1280
    };
1257 1281

	
1258 1282
  };
1259 1283

	
1260 1284
  /// \ingroup graphs
1261 1285
  ///
1262 1286
  /// \brief Graph using a node set of another digraph or graph and an
1263 1287
  /// own edge set.
1264 1288
  ///
1265 1289
  /// This structure can be used to establish another graph over a
1266 1290
  /// node set of an existing one. This class uses the same Node type
1267 1291
  /// as the underlying graph, and each valid node of the original
1268 1292
  /// graph is valid in this arc set, therefore the node objects of
1269 1293
  /// the original graph can be used directly with this class. The
1270 1294
  /// node handling functions (id handling, observing, and iterators)
1271 1295
  /// works equivalently as in the original graph.
1272 1296
  ///
1273 1297
  /// \param GR The type of the graph which shares its node set
1274 1298
  /// with this class. Its interface must conform to the
1275 1299
  /// \ref concepts::Digraph "Digraph" or \ref concepts::Graph "Graph"
1276 1300
  ///  concept.
1277 1301
  ///
1278 1302
  /// This implementation is slightly faster than the \c ListEdgeSet,
1279 1303
  /// because it uses continuous storage for edges and it uses just
1280 1304
  /// single-linked lists for enumerate incident edges. Therefore the
1281 1305
  /// edges cannot be erased from the edge sets.
1282 1306
  ///
1283 1307
  /// \warning If a node is erased from the underlying graph and this
1284 1308
  /// node is incident to one edge in the edge set, then the edge set
1285 1309
  /// is invalidated, and it cannot be used anymore. The validity can
1286 1310
  /// be checked with the \c valid() member function.
1287 1311
  ///
1288 1312
  /// This class fully conforms to the \ref concepts::Graph
1289 1313
  /// "Graph" concept.
1290 1314
  template <typename GR>
1291 1315
  class SmartEdgeSet : public EdgeSetExtender<SmartEdgeSetBase<GR> > {
1292 1316
    typedef EdgeSetExtender<SmartEdgeSetBase<GR> > Parent;
1293 1317

	
1294 1318
  public:
1295 1319

	
1296 1320
    typedef typename Parent::Node Node;
1297 1321
    typedef typename Parent::Arc Arc;
1298 1322
    typedef typename Parent::Edge Edge;
1299 1323

	
1300 1324
  protected:
1301 1325

	
1302 1326
    typedef typename Parent::NodesImplBase NodesImplBase;
1303 1327

	
1304 1328
    void eraseNode(const Node& node) {
1305 1329
      if (typename Parent::IncEdgeIt(*this, node) == INVALID) {
1306 1330
        return;
0 comments (0 inline)