gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Several fixes and improvements in list_graph.h. - Fix incorrect or misleading renamings in the code and in the documentation. - Improve the documentation.
0 1 0
default
1 file changed with 166 insertions and 144 deletions:
↑ Collapse diff ↑
Ignore white space 32 line context
... ...
@@ -98,38 +98,38 @@
98 98
    int maxNodeId() const { return nodes.size()-1; } 
99 99
    int maxArcId() const { return arcs.size()-1; }
100 100

	
101 101
    Node source(Arc e) const { return Node(arcs[e.id].source); }
102 102
    Node target(Arc e) const { return Node(arcs[e.id].target); }
103 103

	
104 104

	
105 105
    void first(Node& node) const { 
106 106
      node.id = first_node;
107 107
    }
108 108

	
109 109
    void next(Node& node) const {
110 110
      node.id = nodes[node.id].next;
111 111
    }
112 112

	
113 113

	
114
    void first(Arc& e) const { 
114
    void first(Arc& arc) const { 
115 115
      int n;
116 116
      for(n = first_node; 
117 117
	  n!=-1 && nodes[n].first_in == -1; 
118 118
	  n = nodes[n].next);
119
      e.id = (n == -1) ? -1 : nodes[n].first_in;
119
      arc.id = (n == -1) ? -1 : nodes[n].first_in;
120 120
    }
121 121

	
122 122
    void next(Arc& arc) const {
123 123
      if (arcs[arc.id].next_in != -1) {
124 124
	arc.id = arcs[arc.id].next_in;
125 125
      } else {
126 126
	int n;
127 127
	for(n = nodes[arcs[arc.id].target].next;
128 128
	  n!=-1 && nodes[n].first_in == -1; 
129 129
	  n = nodes[n].next);
130 130
	arc.id = (n == -1) ? -1 : nodes[n].first_in;
131 131
      }      
132 132
    }
133 133

	
134 134
    void firstOut(Arc &e, const Node& v) const {
135 135
      e.id = nodes[v.id].first_out;
... ...
@@ -280,157 +280,162 @@
280 280
      if(arcs[e.id].prev_out != -1)
281 281
	arcs[arcs[e.id].prev_out].next_out = arcs[e.id].next_out;
282 282
      else nodes[arcs[e.id].source].first_out = arcs[e.id].next_out;
283 283
      if (nodes[n.id].first_out != -1) {
284 284
	arcs[nodes[n.id].first_out].prev_out = e.id;
285 285
      }
286 286
      arcs[e.id].source = n.id;
287 287
      arcs[e.id].prev_out = -1;
288 288
      arcs[e.id].next_out = nodes[n.id].first_out;
289 289
      nodes[n.id].first_out = e.id;
290 290
    }
291 291

	
292 292
  };
293 293

	
294 294
  typedef DigraphExtender<ListDigraphBase> ExtendedListDigraphBase;
295 295

	
296
  /// \addtogroup digraphs
296
  /// \addtogroup graphs
297 297
  /// @{
298 298

	
299
  ///A list digraph class.
299
  ///A general directed graph structure. 
300 300

	
301
  ///This is a simple and fast digraph implementation.
301
  ///\ref ListDigraph is a simple and fast <em>directed graph</em> 
302
  ///implementation based on static linked lists that are stored in 
303
  ///\c std::vector structures.   
302 304
  ///
303 305
  ///It conforms to the \ref concepts::Digraph "Digraph concept" and it
304
  ///also provides several additional useful extra functionalities.
305
  ///The most of the member functions and nested classes are
306
  ///documented only in the concept class.
306
  ///also provides several useful additional functionalities.
307
  ///Most of the member functions and nested classes are documented
308
  ///only in the concept class.
307 309
  ///
308 310
  ///An important extra feature of this digraph implementation is that
309 311
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
310 312
  ///
311
  ///\sa concepts::Digraph.
313
  ///\sa concepts::Digraph
312 314

	
313 315
  class ListDigraph : public ExtendedListDigraphBase {
314 316
  private:
315
    ///ListDigraph is \e not copy constructible. Use DigraphCopy() instead.
317
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
316 318
    
317
    ///ListDigraph is \e not copy constructible. Use DigraphCopy() instead.
319
    ///ListDigraph is \e not copy constructible. Use copyDigraph() instead.
318 320
    ///
319 321
    ListDigraph(const ListDigraph &) :ExtendedListDigraphBase() {};
320 322
    ///\brief Assignment of ListDigraph to another one is \e not allowed.
321
    ///Use DigraphCopy() instead.
323
    ///Use copyDigraph() instead.
322 324

	
323 325
    ///Assignment of ListDigraph to another one is \e not allowed.
324
    ///Use DigraphCopy() instead.
326
    ///Use copyDigraph() instead.
325 327
    void operator=(const ListDigraph &) {}
326 328
  public:
327 329

	
328 330
    typedef ExtendedListDigraphBase Parent;
329 331

	
330 332
    /// Constructor
331 333
    
332 334
    /// Constructor.
333 335
    ///
334 336
    ListDigraph() {}
335 337

	
336 338
    ///Add a new node to the digraph.
337 339
    
338
    /// \return the new node.
339
    ///
340
    ///Add a new node to the digraph.
341
    ///\return the new node.
340 342
    Node addNode() { return Parent::addNode(); }
341 343

	
342 344
    ///Add a new arc to the digraph.
343 345
    
344 346
    ///Add a new arc to the digraph with source node \c s
345 347
    ///and target node \c t.
346 348
    ///\return the new arc.
347 349
    Arc addArc(const Node& s, const Node& t) { 
348 350
      return Parent::addArc(s, t); 
349 351
    }
350 352

	
351
    /// Changes the target of \c e to \c n
353
    /// Change the target of \c e to \c n
352 354

	
353
    /// Changes the target of \c e to \c n
355
    /// Change the target of \c e to \c n
354 356
    ///
355 357
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s referencing
356 358
    ///the changed arc remain valid. However <tt>InArcIt</tt>s are
357 359
    ///invalidated.
360
    ///
358 361
    ///\warning This functionality cannot be used together with the Snapshot
359 362
    ///feature.
360 363
    void changeTarget(Arc e, Node n) { 
361 364
      Parent::changeTarget(e,n); 
362 365
    }
363
    /// Changes the source of \c e to \c n
366
    /// Change the source of \c e to \c n
364 367

	
365
    /// Changes the source of \c e to \c n
368
    /// Change the source of \c e to \c n
366 369
    ///
367 370
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s referencing
368 371
    ///the changed arc remain valid. However <tt>OutArcIt</tt>s are
369 372
    ///invalidated.
373
    ///
370 374
    ///\warning This functionality cannot be used together with the Snapshot
371 375
    ///feature.
372 376
    void changeSource(Arc e, Node n) { 
373 377
      Parent::changeSource(e,n);
374 378
    }
375 379

	
376 380
    /// Invert the direction of an arc.
377 381

	
378 382
    ///\note The <tt>ArcIt</tt>s referencing the changed arc remain
379 383
    ///valid. However <tt>OutArcIt</tt>s and <tt>InArcIt</tt>s are
380 384
    ///invalidated.
385
    ///
381 386
    ///\warning This functionality cannot be used together with the Snapshot
382 387
    ///feature.
383 388
    void reverseArc(Arc e) {
384 389
      Node t=target(e);
385 390
      changeTarget(e,source(e));
386 391
      changeSource(e,t);
387 392
    }
388 393

	
389
    /// Using this it is possible to avoid the superfluous memory
394
    /// Reserve memory for nodes.
395

	
396
    /// Using this function it is possible to avoid the superfluous memory
390 397
    /// allocation: if you know that the digraph you want to build will
391 398
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
392 399
    /// then it is worth reserving space for this amount before starting
393 400
    /// to build the digraph.
394 401
    /// \sa reserveArc
395 402
    void reserveNode(int n) { nodes.reserve(n); };
396 403

	
397
    /// \brief Using this it is possible to avoid the superfluous memory
398
    /// allocation.
404
    /// Reserve memory for arcs.
399 405

	
400
    /// Using this it is possible to avoid the superfluous memory
406
    /// Using this function it is possible to avoid the superfluous memory
401 407
    /// allocation: if you know that the digraph you want to build will
402 408
    /// be very large (e.g. it will contain millions of nodes and/or arcs)
403 409
    /// then it is worth reserving space for this amount before starting
404 410
    /// to build the digraph.
405 411
    /// \sa reserveNode
406 412
    void reserveArc(int m) { arcs.reserve(m); };
407 413

	
408 414
    ///Contract two nodes.
409 415

	
410 416
    ///This function contracts two nodes.
411
    ///
412 417
    ///Node \p b will be removed but instead of deleting
413 418
    ///incident arcs, they will be joined to \p a.
414 419
    ///The last parameter \p r controls whether to remove loops. \c true
415 420
    ///means that loops will be removed.
416 421
    ///
417
    ///\note The <tt>ArcIt</tt>s
418
    ///referencing a moved arc remain
422
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
419 423
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s
420 424
    ///may be invalidated.
425
    ///
421 426
    ///\warning This functionality cannot be used together with the Snapshot
422 427
    ///feature.
423 428
    void contract(Node a, Node b, bool r = true) 
424 429
    {
425 430
      for(OutArcIt e(*this,b);e!=INVALID;) {
426 431
	OutArcIt f=e;
427 432
	++f;
428 433
	if(r && target(e)==a) erase(e);
429 434
	else changeSource(e,a);
430 435
	e=f;
431 436
      }
432 437
      for(InArcIt e(*this,b);e!=INVALID;) {
433 438
	InArcIt f=e;
434 439
	++f;
435 440
	if(r && source(e)==a) erase(e);
436 441
	else changeTarget(e,a);
... ...
@@ -439,72 +444,75 @@
439 444
      erase(b);
440 445
    }
441 446

	
442 447
    ///Split a node.
443 448

	
444 449
    ///This function splits a node. First a new node is added to the digraph,
445 450
    ///then the source of each outgoing arc of \c n is moved to this new node.
446 451
    ///If \c connect is \c true (this is the default value), then a new arc
447 452
    ///from \c n to the newly created node is also added.
448 453
    ///\return The newly created node.
449 454
    ///
450 455
    ///\note The <tt>ArcIt</tt>s referencing a moved arc remain
451 456
    ///valid. However <tt>InArcIt</tt>s and <tt>OutArcIt</tt>s may
452 457
    ///be invalidated.  
453 458
    ///
454 459
    ///\warning This functionality cannot be used together with the
455
    ///Snapshot feature.  \todo It could be implemented in a bit
456
    ///faster way.
460
    ///Snapshot feature.
461
    ///
462
    ///\todo It could be implemented in a bit faster way.
457 463
    Node split(Node n, bool connect = true) {
458 464
      Node b = addNode();
459 465
      for(OutArcIt e(*this,n);e!=INVALID;) {
460 466
 	OutArcIt f=e;
461 467
	++f;
462 468
	changeSource(e,b);
463 469
	e=f;
464 470
      }
465 471
      if (connect) addArc(n,b);
466 472
      return b;
467 473
    }
468 474
      
469 475
    ///Split an arc.
470 476

	
471 477
    ///This function splits an arc. First a new node \c b is added to
472 478
    ///the digraph, then the original arc is re-targeted to \c
473 479
    ///b. Finally an arc from \c b to the original target is added.
474
    ///\return The newly created node.  
475
    ///\warning This functionality
476
    ///cannot be used together with the Snapshot feature.
480
    ///
481
    ///\return The newly created node.
482
    ///
483
    ///\warning This functionality cannot be used together with the
484
    ///Snapshot feature.
477 485
    Node split(Arc e) {
478 486
      Node b = addNode();
479 487
      addArc(b,target(e));
480 488
      changeTarget(e,b);
481 489
      return b;
482 490
    }
483 491
      
484 492
    /// \brief Class to make a snapshot of the digraph and restore
485
    /// to it later.
493
    /// it later.
486 494
    ///
487
    /// Class to make a snapshot of the digraph and to restore it
488
    /// later.
495
    /// Class to make a snapshot of the digraph and restore it later.
489 496
    ///
490 497
    /// The newly added nodes and arcs can be removed using the
491 498
    /// restore() function.
492 499
    ///
493
    /// \warning Arc and node deletions cannot be restored. This
494
    /// events invalidate the snapshot. 
500
    /// \warning Arc and node deletions and other modifications (e.g.
501
    /// contracting, splitting, reversing arcs or nodes) cannot be 
502
    /// restored. These events invalidate the snapshot. 
495 503
    class Snapshot {
496 504
    protected:
497 505

	
498 506
      typedef Parent::NodeNotifier NodeNotifier;
499 507

	
500 508
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
501 509
      public:
502 510

	
503 511
        NodeObserverProxy(Snapshot& _snapshot)
504 512
          : snapshot(_snapshot) {}
505 513

	
506 514
        using NodeNotifier::ObserverBase::attach;
507 515
        using NodeNotifier::ObserverBase::detach;
508 516
        using NodeNotifier::ObserverBase::attached;
509 517
        
510 518
      protected:
... ...
@@ -763,35 +771,35 @@
763 771
      Node (Invalid) { id = -1; }
764 772
      bool operator==(const Node& node) const {return id == node.id;}
765 773
      bool operator!=(const Node& node) const {return id != node.id;}
766 774
      bool operator<(const Node& node) const {return id < node.id;}
767 775
    };
768 776

	
769 777
    class Edge {
770 778
      friend class ListGraphBase;
771 779
    protected:
772 780

	
773 781
      int id;
774 782
      explicit Edge(int pid) { id = pid;}
775 783

	
776 784
    public:
777 785
      Edge() {}
778 786
      Edge (Invalid) { id = -1; }
779
      bool operator==(const Edge& arc) const {return id == arc.id;}
780
      bool operator!=(const Edge& arc) const {return id != arc.id;}
781
      bool operator<(const Edge& arc) const {return id < arc.id;}
787
      bool operator==(const Edge& edge) const {return id == edge.id;}
788
      bool operator!=(const Edge& edge) const {return id != edge.id;}
789
      bool operator<(const Edge& edge) const {return id < edge.id;}
782 790
    };
783 791

	
784 792
    class Arc {
785 793
      friend class ListGraphBase;
786 794
    protected:
787 795

	
788 796
      int id;
789 797
      explicit Arc(int pid) { id = pid;}
790 798

	
791 799
    public:
792 800
      operator Edge() const { return edgeFromId(id / 2); }
793 801

	
794 802
      Arc() {}
795 803
      Arc (Invalid) { id = -1; }
796 804
      bool operator==(const Arc& arc) const {return id == arc.id;}
797 805
      bool operator!=(const Arc& arc) const {return id != arc.id;}
... ...
@@ -896,46 +904,46 @@
896 904
      e.id = nodes[v.id].first_out;
897 905
    }
898 906
    void nextOut(Arc &e) const {
899 907
      e.id = arcs[e.id].next_out;
900 908
    }
901 909

	
902 910
    void firstIn(Arc &e, const Node& v) const {
903 911
      e.id = ((nodes[v.id].first_out) ^ 1);
904 912
      if (e.id == -2) e.id = -1;
905 913
    }
906 914
    void nextIn(Arc &e) const {
907 915
      e.id = ((arcs[e.id ^ 1].next_out) ^ 1);
908 916
      if (e.id == -2) e.id = -1;
909 917
    }
910 918

	
911 919
    void firstInc(Edge &e, bool& d, const Node& v) const {
912
      int de = nodes[v.id].first_out;
913
      if (de != -1 ) {
914
        e.id = de / 2;
915
        d = ((de & 1) == 1);
920
      int a = nodes[v.id].first_out;
921
      if (a != -1 ) {
922
        e.id = a / 2;
923
        d = ((a & 1) == 1);
916 924
      } else {
917 925
        e.id = -1;
918 926
        d = true;
919 927
      }
920 928
    }
921 929
    void nextInc(Edge &e, bool& d) const {
922
      int de = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
923
      if (de != -1 ) {
924
        e.id = de / 2;
925
        d = ((de & 1) == 1);
930
      int a = (arcs[(e.id * 2) | (d ? 1 : 0)].next_out);
931
      if (a != -1 ) {
932
        e.id = a / 2;
933
        d = ((a & 1) == 1);
926 934
      } else {
927 935
        e.id = -1;
928 936
        d = true;
929 937
      }
930 938
    }
931 939
    
932 940
    static int id(Node v) { return v.id; }
933 941
    static int id(Arc e) { return e.id; }
934 942
    static int id(Edge e) { return e.id; }
935 943

	
936 944
    static Node nodeFromId(int id) { return Node(id);}
937 945
    static Arc arcFromId(int id) { return Arc(id);}
938 946
    static Edge edgeFromId(int id) { return Edge(id);}
939 947

	
940 948
    Node addNode() {     
941 949
      int n;
... ...
@@ -995,34 +1003,34 @@
995 1003
      
996 1004
      if(nodes[n].next != -1) {
997 1005
	nodes[nodes[n].next].prev = nodes[n].prev;
998 1006
      }
999 1007
      
1000 1008
      if(nodes[n].prev != -1) {
1001 1009
	nodes[nodes[n].prev].next = nodes[n].next;
1002 1010
      } else {
1003 1011
	first_node = nodes[n].next;
1004 1012
      }
1005 1013
      
1006 1014
      nodes[n].next = first_free_node;
1007 1015
      first_free_node = n;
1008 1016

	
1009 1017
    }
1010 1018
    
1011
    void erase(const Edge& arc) {
1012
      int n = arc.id * 2;
1019
    void erase(const Edge& edge) {
1020
      int n = edge.id * 2;
1013 1021
      
1014 1022
      if (arcs[n].next_out != -1) {
1015 1023
	arcs[arcs[n].next_out].prev_out = arcs[n].prev_out;
1016 1024
      } 
1017 1025

	
1018 1026
      if (arcs[n].prev_out != -1) {
1019 1027
	arcs[arcs[n].prev_out].next_out = arcs[n].next_out;
1020 1028
      } else {
1021 1029
	nodes[arcs[n | 1].target].first_out = arcs[n].next_out;
1022 1030
      }
1023 1031

	
1024 1032
      if (arcs[n | 1].next_out != -1) {
1025 1033
	arcs[arcs[n | 1].next_out].prev_out = arcs[n | 1].prev_out;
1026 1034
      } 
1027 1035

	
1028 1036
      if (arcs[n | 1].prev_out != -1) {
... ...
@@ -1076,179 +1084,193 @@
1076 1084
      } else {
1077 1085
        nodes[arcs[2 * e.id].target].first_out = 
1078 1086
          arcs[(2 * e.id) | 1].next_out;
1079 1087
      }
1080 1088

	
1081 1089
      if (nodes[n.id].first_out != -1) {
1082 1090
	arcs[nodes[n.id].first_out].prev_out = ((2 * e.id) | 1);
1083 1091
      }
1084 1092
      arcs[2 * e.id].target = n.id;
1085 1093
      arcs[(2 * e.id) | 1].prev_out = -1;
1086 1094
      arcs[(2 * e.id) | 1].next_out = nodes[n.id].first_out;
1087 1095
      nodes[n.id].first_out = ((2 * e.id) | 1);
1088 1096
    }
1089 1097

	
1090 1098
  };
1091 1099

	
1092
//   typedef GraphExtender<UndirDigraphExtender<ListDigraphBase> > 
1093
//   ExtendedListGraphBase;
1094

	
1095 1100
  typedef GraphExtender<ListGraphBase> ExtendedListGraphBase;
1096 1101

	
1097 1102

	
1098

	
1099
  /// \addtogroup digraphs
1103
  /// \addtogroup graphs
1100 1104
  /// @{
1101 1105

	
1102
  ///An undirected list digraph class.
1106
  ///A general undirected graph structure.
1103 1107

	
1104
  ///This is a simple and fast undirected digraph implementation.
1108
  ///\ref ListGraph is a simple and fast <em>undirected graph</em> 
1109
  ///implementation based on static linked lists that are stored in 
1110
  ///\c std::vector structures. 
1105 1111
  ///
1106
  ///An important extra feature of this digraph implementation is that
1112
  ///It conforms to the \ref concepts::Graph "Graph concept" and it
1113
  ///also provides several useful additional functionalities.
1114
  ///Most of the member functions and nested classes are documented
1115
  ///only in the concept class.
1116
  ///
1117
  ///An important extra feature of this graph implementation is that
1107 1118
  ///its maps are real \ref concepts::ReferenceMap "reference map"s.
1108 1119
  ///
1109
  ///It conforms to the
1110
  ///\ref concepts::Graph "Graph concept".
1111
  ///
1112
  ///\sa concepts::Graph.
1113
  ///
1120
  ///\sa concepts::Graph
1121

	
1114 1122
  class ListGraph : public ExtendedListGraphBase {
1115 1123
  private:
1116
    ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
1124
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1117 1125

	
1118
    ///ListGraph is \e not copy constructible. Use GraphCopy() instead.
1126
    ///ListGraph is \e not copy constructible. Use copyGraph() instead.
1119 1127
    ///
1120 1128
    ListGraph(const ListGraph &) :ExtendedListGraphBase()  {};
1121 1129
    ///\brief Assignment of ListGraph to another one is \e not allowed.
1122
    ///Use GraphCopy() instead.
1130
    ///Use copyGraph() instead.
1123 1131

	
1124 1132
    ///Assignment of ListGraph to another one is \e not allowed.
1125
    ///Use GraphCopy() instead.
1133
    ///Use copyGraph() instead.
1126 1134
    void operator=(const ListGraph &) {}
1127 1135
  public:
1128 1136
    /// Constructor
1129 1137
    
1130 1138
    /// Constructor.
1131 1139
    ///
1132 1140
    ListGraph() {}
1133 1141

	
1134 1142
    typedef ExtendedListGraphBase Parent;
1135 1143

	
1136
    typedef Parent::OutArcIt IncArcIt;
1144
    typedef Parent::OutArcIt IncEdgeIt;
1137 1145

	
1138
    /// \brief Add a new node to the digraph.
1146
    /// \brief Add a new node to the graph.
1139 1147
    ///
1148
    /// Add a new node to the graph.
1140 1149
    /// \return the new node.
1141
    ///
1142 1150
    Node addNode() { return Parent::addNode(); }
1143 1151

	
1144
    /// \brief Add a new edge to the digraph.
1152
    /// \brief Add a new edge to the graph.
1145 1153
    ///
1146
    /// Add a new arc to the digraph with source node \c s
1154
    /// Add a new edge to the graph with source node \c s
1147 1155
    /// and target node \c t.
1148 1156
    /// \return the new edge.
1149 1157
    Edge addEdge(const Node& s, const Node& t) { 
1150 1158
      return Parent::addEdge(s, t); 
1151 1159
    }
1152
    /// \brief Changes the source of \c e to \c n
1160
    /// \brief Change the source of \c e to \c n
1153 1161
    ///
1154
    /// Changes the source of \c e to \c n
1162
    /// This function changes the source of \c e to \c n.
1155 1163
    ///
1156 1164
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1157 1165
    ///referencing the changed arc remain
1158 1166
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1167
    ///
1168
    ///\warning This functionality cannot be used together with the
1169
    ///Snapshot feature.
1159 1170
    void changeSource(Edge e, Node n) { 
1160 1171
      Parent::changeSource(e,n); 
1161 1172
    }    
1162
    /// \brief Changes the target of \c e to \c n
1173
    /// \brief Change the target of \c e to \c n
1163 1174
    ///
1164
    /// Changes the target of \c e to \c n
1175
    /// This function changes the target of \c e to \c n.
1165 1176
    ///
1166 1177
    /// \note The <tt>ArcIt</tt>s referencing the changed arc remain
1167 1178
    /// valid. However the other iterators may be invalidated.
1179
    ///
1180
    ///\warning This functionality cannot be used together with the
1181
    ///Snapshot feature.
1168 1182
    void changeTarget(Edge e, Node n) { 
1169 1183
      Parent::changeTarget(e,n); 
1170 1184
    }
1171
    /// \brief Changes the source of \c e to \c n
1185
    /// \brief Change the source of \c e to \c n
1172 1186
    ///
1173
    /// Changes the source of \c e to \c n. It changes the proper
1174
    /// node of the represented edge.
1187
    /// This function changes the source of \c e to \c n. 
1188
    /// It also changes the proper node of the represented edge.
1175 1189
    ///
1176 1190
    ///\note The <tt>ArcIt</tt>s and <tt>InArcIt</tt>s
1177 1191
    ///referencing the changed arc remain
1178 1192
    ///valid. However <tt>OutArcIt</tt>s are invalidated.
1193
    ///
1194
    ///\warning This functionality cannot be used together with the
1195
    ///Snapshot feature.
1179 1196
    void changeSource(Arc e, Node n) { 
1180 1197
      if (Parent::direction(e)) {
1181 1198
        Parent::changeSource(e,n);
1182 1199
      } else {
1183 1200
        Parent::changeTarget(e,n);
1184 1201
      } 
1185 1202
    }
1186
    /// \brief Changes the target of \c e to \c n
1203
    /// \brief Change the target of \c e to \c n
1187 1204
    ///
1188
    /// Changes the target of \c e to \c n. It changes the proper
1189
    /// node of the represented edge.
1205
    /// This function changes the target of \c e to \c n. 
1206
    /// It also changes the proper node of the represented edge.
1190 1207
    ///
1191 1208
    ///\note The <tt>ArcIt</tt>s and <tt>OutArcIt</tt>s
1192 1209
    ///referencing the changed arc remain
1193 1210
    ///valid. However <tt>InArcIt</tt>s are invalidated.
1211
    ///
1212
    ///\warning This functionality cannot be used together with the
1213
    ///Snapshot feature.
1194 1214
    void changeTarget(Arc e, Node n) { 
1195 1215
      if (Parent::direction(e)) {
1196 1216
        Parent::changeTarget(e,n);
1197 1217
      } else {
1198 1218
        Parent::changeSource(e,n);
1199 1219
      } 
1200 1220
    }
1201 1221
    /// \brief Contract two nodes.
1202 1222
    ///
1203 1223
    /// This function contracts two nodes.
1204
    ///
1205 1224
    /// Node \p b will be removed but instead of deleting
1206 1225
    /// its neighboring arcs, they will be joined to \p a.
1207 1226
    /// The last parameter \p r controls whether to remove loops. \c true
1208 1227
    /// means that loops will be removed.
1209 1228
    ///
1210 1229
    /// \note The <tt>ArcIt</tt>s referencing a moved arc remain
1211 1230
    /// valid.
1231
    ///
1232
    ///\warning This functionality cannot be used together with the
1233
    ///Snapshot feature.
1212 1234
    void contract(Node a, Node b, bool r = true) {
1213
      for(IncArcIt e(*this, b); e!=INVALID;) {
1214
	IncArcIt f = e; ++f;
1235
      for(IncEdgeIt e(*this, b); e!=INVALID;) {
1236
	IncEdgeIt f = e; ++f;
1215 1237
	if (r && runningNode(e) == a) {
1216 1238
	  erase(e);
1217 1239
	} else if (source(e) == b) {
1218 1240
	  changeSource(e, a);
1219 1241
	} else {
1220 1242
	  changeTarget(e, a);
1221 1243
	}
1222 1244
	e = f;
1223 1245
      }
1224 1246
      erase(b);
1225 1247
    }
1226 1248

	
1227 1249

	
1228
    /// \brief Class to make a snapshot of the digraph and restore
1229
    /// to it later.
1250
    /// \brief Class to make a snapshot of the graph and restore
1251
    /// it later.
1230 1252
    ///
1231
    /// Class to make a snapshot of the digraph and to restore it
1232
    /// later.
1253
    /// Class to make a snapshot of the graph and restore it later.
1233 1254
    ///
1234 1255
    /// The newly added nodes and edges can be removed
1235 1256
    /// using the restore() function.
1236 1257
    ///
1237
    /// \warning Arc and node deletions cannot be restored. This
1238
    /// events invalidate the snapshot. 
1258
    /// \warning Edge and node deletions and other modifications
1259
    /// (e.g. changing nodes of edges, contracting nodes) cannot be 
1260
    /// restored. These events invalidate the snapshot.
1239 1261
    class Snapshot {
1240 1262
    protected:
1241 1263

	
1242 1264
      typedef Parent::NodeNotifier NodeNotifier;
1243 1265

	
1244 1266
      class NodeObserverProxy : public NodeNotifier::ObserverBase {
1245 1267
      public:
1246 1268

	
1247 1269
        NodeObserverProxy(Snapshot& _snapshot)
1248 1270
          : snapshot(_snapshot) {}
1249 1271

	
1250 1272
        using NodeNotifier::ObserverBase::attach;
1251 1273
        using NodeNotifier::ObserverBase::detach;
1252 1274
        using NodeNotifier::ObserverBase::attached;
1253 1275
        
1254 1276
      protected:
... ...
@@ -1290,176 +1312,176 @@
1290 1312

	
1291 1313
        Snapshot& snapshot;
1292 1314
      };
1293 1315

	
1294 1316
      class EdgeObserverProxy : public EdgeNotifier::ObserverBase {
1295 1317
      public:
1296 1318

	
1297 1319
        EdgeObserverProxy(Snapshot& _snapshot)
1298 1320
          : snapshot(_snapshot) {}
1299 1321

	
1300 1322
        using EdgeNotifier::ObserverBase::attach;
1301 1323
        using EdgeNotifier::ObserverBase::detach;
1302 1324
        using EdgeNotifier::ObserverBase::attached;
1303 1325
        
1304 1326
      protected:
1305 1327

	
1306
        virtual void add(const Edge& arc) {
1307
          snapshot.addEdge(arc);
1328
        virtual void add(const Edge& edge) {
1329
          snapshot.addEdge(edge);
1308 1330
        }
1309
        virtual void add(const std::vector<Edge>& arcs) {
1310
          for (int i = arcs.size() - 1; i >= 0; ++i) {
1311
            snapshot.addEdge(arcs[i]);
1331
        virtual void add(const std::vector<Edge>& edges) {
1332
          for (int i = edges.size() - 1; i >= 0; ++i) {
1333
            snapshot.addEdge(edges[i]);
1312 1334
          }
1313 1335
        }
1314
        virtual void erase(const Edge& arc) {
1315
          snapshot.eraseEdge(arc);
1336
        virtual void erase(const Edge& edge) {
1337
          snapshot.eraseEdge(edge);
1316 1338
        }
1317
        virtual void erase(const std::vector<Edge>& arcs) {
1318
          for (int i = 0; i < int(arcs.size()); ++i) {
1319
            snapshot.eraseEdge(arcs[i]);
1339
        virtual void erase(const std::vector<Edge>& edges) {
1340
          for (int i = 0; i < int(edges.size()); ++i) {
1341
            snapshot.eraseEdge(edges[i]);
1320 1342
          }
1321 1343
        }
1322 1344
        virtual void build() {
1323
          Edge arc;
1324
          std::vector<Edge> arcs;
1325
          for (notifier()->first(arc); arc != INVALID; 
1326
               notifier()->next(arc)) {
1327
            arcs.push_back(arc);
1345
          Edge edge;
1346
          std::vector<Edge> edges;
1347
          for (notifier()->first(edge); edge != INVALID; 
1348
               notifier()->next(edge)) {
1349
            edges.push_back(edge);
1328 1350
          }
1329
          for (int i = arcs.size() - 1; i >= 0; --i) {
1330
            snapshot.addEdge(arcs[i]);
1351
          for (int i = edges.size() - 1; i >= 0; --i) {
1352
            snapshot.addEdge(edges[i]);
1331 1353
          }
1332 1354
        }
1333 1355
        virtual void clear() {
1334
          Edge arc;
1335
          for (notifier()->first(arc); arc != INVALID; 
1336
               notifier()->next(arc)) {
1337
            snapshot.eraseEdge(arc);
1356
          Edge edge;
1357
          for (notifier()->first(edge); edge != INVALID; 
1358
               notifier()->next(edge)) {
1359
            snapshot.eraseEdge(edge);
1338 1360
          }
1339 1361
        }
1340 1362

	
1341 1363
        Snapshot& snapshot;
1342 1364
      };
1343
      
1344
      ListGraph *digraph;
1365

	
1366
      ListGraph *graph;
1345 1367

	
1346 1368
      NodeObserverProxy node_observer_proxy;
1347
      EdgeObserverProxy arc_observer_proxy;
1369
      EdgeObserverProxy edge_observer_proxy;
1348 1370

	
1349 1371
      std::list<Node> added_nodes;
1350
      std::list<Edge> added_arcs;
1372
      std::list<Edge> added_edges;
1351 1373

	
1352 1374

	
1353 1375
      void addNode(const Node& node) {
1354 1376
        added_nodes.push_front(node);        
1355 1377
      }
1356 1378
      void eraseNode(const Node& node) {
1357 1379
        std::list<Node>::iterator it = 
1358 1380
          std::find(added_nodes.begin(), added_nodes.end(), node);
1359 1381
        if (it == added_nodes.end()) {
1360 1382
          clear();
1361
          arc_observer_proxy.detach();
1383
          edge_observer_proxy.detach();
1362 1384
          throw NodeNotifier::ImmediateDetach();
1363 1385
        } else {
1364 1386
          added_nodes.erase(it);
1365 1387
        }
1366 1388
      }
1367 1389

	
1368
      void addEdge(const Edge& arc) {
1369
        added_arcs.push_front(arc);        
1390
      void addEdge(const Edge& edge) {
1391
        added_edges.push_front(edge);        
1370 1392
      }
1371
      void eraseEdge(const Edge& arc) {
1393
      void eraseEdge(const Edge& edge) {
1372 1394
        std::list<Edge>::iterator it = 
1373
          std::find(added_arcs.begin(), added_arcs.end(), arc);
1374
        if (it == added_arcs.end()) {
1395
          std::find(added_edges.begin(), added_edges.end(), edge);
1396
        if (it == added_edges.end()) {
1375 1397
          clear();
1376 1398
          node_observer_proxy.detach();
1377 1399
          throw EdgeNotifier::ImmediateDetach();
1378 1400
        } else {
1379
          added_arcs.erase(it);
1380
        }        
1401
          added_edges.erase(it);
1402
        }
1381 1403
      }
1382 1404

	
1383
      void attach(ListGraph &_digraph) {
1384
	digraph = &_digraph;
1385
	node_observer_proxy.attach(digraph->notifier(Node()));
1386
        arc_observer_proxy.attach(digraph->notifier(Edge()));
1405
      void attach(ListGraph &_graph) {
1406
	graph = &_graph;
1407
	node_observer_proxy.attach(graph->notifier(Node()));
1408
        edge_observer_proxy.attach(graph->notifier(Edge()));
1387 1409
      }
1388 1410
            
1389 1411
      void detach() {
1390 1412
	node_observer_proxy.detach();
1391
	arc_observer_proxy.detach();
1413
	edge_observer_proxy.detach();
1392 1414
      }
1393 1415

	
1394 1416
      bool attached() const {
1395 1417
        return node_observer_proxy.attached();
1396 1418
      }
1397 1419

	
1398 1420
      void clear() {
1399 1421
        added_nodes.clear();
1400
        added_arcs.clear();        
1422
        added_edges.clear();        
1401 1423
      }
1402 1424

	
1403 1425
    public:
1404 1426

	
1405 1427
      /// \brief Default constructor.
1406 1428
      ///
1407 1429
      /// Default constructor.
1408 1430
      /// To actually make a snapshot you must call save().
1409 1431
      Snapshot() 
1410
        : digraph(0), node_observer_proxy(*this), 
1411
          arc_observer_proxy(*this) {}
1432
        : graph(0), node_observer_proxy(*this), 
1433
          edge_observer_proxy(*this) {}
1412 1434
      
1413 1435
      /// \brief Constructor that immediately makes a snapshot.
1414 1436
      ///      
1415
      /// This constructor immediately makes a snapshot of the digraph.
1416
      /// \param _digraph The digraph we make a snapshot of.
1417
      Snapshot(ListGraph &_digraph) 
1437
      /// This constructor immediately makes a snapshot of the graph.
1438
      /// \param _graph The graph we make a snapshot of.
1439
      Snapshot(ListGraph &_graph) 
1418 1440
        : node_observer_proxy(*this), 
1419
          arc_observer_proxy(*this) {
1420
	attach(_digraph);
1441
          edge_observer_proxy(*this) {
1442
	attach(_graph);
1421 1443
      }
1422 1444
      
1423 1445
      /// \brief Make a snapshot.
1424 1446
      ///
1425
      /// Make a snapshot of the digraph.
1447
      /// Make a snapshot of the graph.
1426 1448
      ///
1427 1449
      /// This function can be called more than once. In case of a repeated
1428 1450
      /// call, the previous snapshot gets lost.
1429
      /// \param _digraph The digraph we make the snapshot of.
1430
      void save(ListGraph &_digraph) {
1451
      /// \param _graph The graph we make the snapshot of.
1452
      void save(ListGraph &_graph) {
1431 1453
        if (attached()) {
1432 1454
          detach();
1433 1455
          clear();
1434 1456
        }
1435
        attach(_digraph);
1457
        attach(_graph);
1436 1458
      }
1437 1459
      
1438 1460
      /// \brief Undo the changes until the last snapshot.
1439 1461
      // 
1440 1462
      /// Undo the changes until the last snapshot created by save().
1441 1463
      void restore() {
1442 1464
	detach();
1443
	for(std::list<Edge>::iterator it = added_arcs.begin(); 
1444
            it != added_arcs.end(); ++it) {
1445
	  digraph->erase(*it);
1465
	for(std::list<Edge>::iterator it = added_edges.begin(); 
1466
            it != added_edges.end(); ++it) {
1467
	  graph->erase(*it);
1446 1468
	}
1447 1469
	for(std::list<Node>::iterator it = added_nodes.begin(); 
1448 1470
            it != added_nodes.end(); ++it) {
1449
	  digraph->erase(*it);
1471
	  graph->erase(*it);
1450 1472
	}
1451 1473
        clear();
1452 1474
      }
1453 1475

	
1454 1476
      /// \brief Gives back true when the snapshot is valid.
1455 1477
      ///
1456 1478
      /// Gives back true when the snapshot is valid.
1457 1479
      bool valid() const {
1458 1480
        return attached();
1459 1481
      }
1460 1482
    };
1461 1483
  };
1462 1484
  
1463 1485
  /// @}  
1464 1486
} //namespace lemon
1465 1487
  
0 comments (0 inline)