gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 2 0
merge default
0 files changed with 170 insertions and 150 deletions:
↑ Collapse diff ↑
Ignore white space 96 line context
... ...
@@ -10,97 +10,96 @@
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_CONCEPT_MAPS_H
20 20
#define LEMON_CONCEPT_MAPS_H
21 21

	
22 22
#include <lemon/bits/utility.h>
23 23
#include <lemon/concept_check.h>
24 24

	
25 25
///\ingroup concept
26 26
///\file
27 27
///\brief Map concepts checking classes for testing and documenting.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  namespace concepts {
32 32
  
33 33
    /// \addtogroup concept
34 34
    /// @{
35 35

	
36 36
    /// Readable map concept
37 37

	
38 38
    /// Readable map concept.
39 39
    ///
40 40
    template<typename K, typename T>
41 41
    class ReadMap
42 42
    {
43 43
    public:
44 44
      /// The key type of the map.
45 45
      typedef K Key;    
46 46
      /// The value type of the map. (The type of objects associated with the keys).
47 47
      typedef T Value;
48 48

	
49 49
      /// Returns the value associated with a key.
50 50

	
51 51
      /// Returns the value associated with a key.
52 52
      /// \bug Value shouldn't need to be default constructible.
53 53
      ///
54 54
      Value operator[](const Key &) const {return Value();}
55 55

	
56 56
      template<typename _ReadMap>
57 57
      struct Constraints {
58

	
59 58
	void constraints() {
60 59
	  Value val = m[key];
61 60
	  val = m[key];
62 61
	  typename _ReadMap::Value own_val = m[own_key]; 
63 62
	  own_val = m[own_key]; 
64 63

	
65 64
	  ignore_unused_variable_warning(val);
66 65
	  ignore_unused_variable_warning(own_val);
67 66
	  ignore_unused_variable_warning(key);
68 67
	}
69 68
	Key& key;
70 69
	typename _ReadMap::Key& own_key;
71 70
	_ReadMap& m;
72 71
      };
73 72
      
74 73
    };
75 74

	
76 75

	
77 76
    /// Writable map concept
78 77
    
79 78
    /// Writable map concept.
80 79
    ///
81 80
    template<typename K, typename T>
82 81
    class WriteMap
83 82
    {
84 83
    public:
85 84
      /// The key type of the map.
86 85
      typedef K Key;    
87 86
      /// The value type of the map. (The type of objects associated with the keys).
88 87
      typedef T Value;
89 88

	
90 89
      /// Sets the value associated with a key.
91 90
      void set(const Key &,const Value &) {}
92 91

	
93 92
      ///Default constructor
94 93
      WriteMap() {}
95 94

	
96 95
      template <typename _WriteMap>
97 96
      struct Constraints {
98 97
	void constraints() {
99 98
	  // No constraints for constructor.
100 99
	  m.set(key, val);
101 100
	  m.set(own_key, own_val);
102 101
	  ignore_unused_variable_warning(key);
103 102
	  ignore_unused_variable_warning(val);
104 103
	  ignore_unused_variable_warning(own_key);
105 104
	  ignore_unused_variable_warning(own_val);
106 105
	}
... ...
@@ -130,79 +129,78 @@
130 129

	
131 130
      /// Returns the value associated with a key.
132 131
      Value operator[](const Key &) const {return Value();}
133 132
      /// Sets the value associated with a key.
134 133
      void set(const Key & ,const Value &) {}
135 134

	
136 135
      template<typename _ReadWriteMap>
137 136
      struct Constraints {
138 137
	void constraints() {
139 138
	  checkConcept<ReadMap<K, T>, _ReadWriteMap >();
140 139
	  checkConcept<WriteMap<K, T>, _ReadWriteMap >();
141 140
	}
142 141
      };
143 142
    };
144 143
  
145 144
  
146 145
    /// Dereferable map concept
147 146
    
148 147
    /// Dereferable map concept.
149 148
    ///
150 149
    /// \todo Rethink this concept.
151 150
    template<typename K, typename T, typename R, typename CR>
152 151
    class ReferenceMap : public ReadWriteMap<K,T>
153 152
    {
154 153
    public:
155 154
      /// Tag for reference maps.
156 155
      typedef True ReferenceMapTag;
157 156
      /// The key type of the map.
158 157
      typedef K Key;    
159 158
      /// The value type of the map. (The type of objects associated with the keys).
160 159
      typedef T Value;
161 160
      /// The reference type of the map.
162 161
      typedef R Reference;
163 162
      /// The const reference type of the map.
164 163
      typedef CR ConstReference;
165 164

	
166 165
    protected:
167 166
      Value tmp;
168 167
    public:
169 168

	
170 169
      ///Returns a reference to the value associated with a key.
171 170
      Reference operator[](const Key &) { return tmp; }
172 171
      ///Returns a const reference to the value associated with a key.
173 172
      ConstReference operator[](const Key &) const { return tmp; }
174 173
      /// Sets the value associated with a key.
175 174
      void set(const Key &k,const Value &t) { operator[](k)=t; }
176 175

	
177 176
      template<typename _ReferenceMap>
178
      struct ReferenceMapConcept {
179

	
177
      struct Constraints {
180 178
	void constraints() {
181
	  checkConcept<ReadWriteMap, _ReferenceMap >();
179
	  checkConcept<ReadWriteMap<K, T>, _ReferenceMap >();
182 180
	  m[key] = val;
183 181
	  val  = m[key];
184 182
	  m[key] = ref;
185 183
	  ref = m[key];
186 184
	  m[own_key] = own_val;
187 185
	  own_val  = m[own_key];
188 186
	  m[own_key] = own_ref;
189 187
	  own_ref = m[own_key];	  	  
190 188
	}
191 189

	
192 190
	typename _ReferenceMap::Key& own_key;
193 191
	typename _ReferenceMap::Value& own_val;
194
	typename _ReferenceMap::Reference& own_ref;
192
	typename _ReferenceMap::Reference own_ref;
195 193
	Key& key;
196 194
	Value& val;
197
	Reference& ref;
195
	Reference ref;
198 196
	_ReferenceMap& m;
199 197
      };
200 198
    };
201 199

	
202 200
    // @}
203 201

	
204 202
  } //namespace concepts
205 203

	
206 204
} //namespace lemon
207 205

	
208 206
#endif // LEMON_CONCEPT_MAPS_H
Ignore white space 6 line context
... ...
@@ -66,102 +66,102 @@
66 66
      explicit Node(int pid) { id = pid;}
67 67

	
68 68
    public:
69 69
      Node() {}
70 70
      Node (Invalid) { id = -1; }
71 71
      bool operator==(const Node& node) const {return id == node.id;}
72 72
      bool operator!=(const Node& node) const {return id != node.id;}
73 73
      bool operator<(const Node& node) const {return id < node.id;}
74 74
    };
75 75

	
76 76
    class Arc {
77 77
      friend class ListDigraphBase;
78 78
    protected:
79 79

	
80 80
      int id;
81 81
      explicit Arc(int pid) { id = pid;}
82 82

	
83 83
    public:
84 84
      Arc() {}
85 85
      Arc (Invalid) { id = -1; }
86 86
      bool operator==(const Arc& arc) const {return id == arc.id;}
87 87
      bool operator!=(const Arc& arc) const {return id != arc.id;}
88 88
      bool operator<(const Arc& arc) const {return id < arc.id;}
89 89
    };
90 90

	
91 91

	
92 92

	
93 93
    ListDigraphBase()
94 94
      : nodes(), first_node(-1),
95 95
	first_free_node(-1), arcs(), first_free_arc(-1) {}
96 96

	
97 97
    
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;
136 136
    }
137 137
    void nextOut(Arc &e) const {
138 138
      e.id=arcs[e.id].next_out;
139 139
    }
140 140

	
141 141
    void firstIn(Arc &e, const Node& v) const {
142 142
      e.id = nodes[v.id].first_in;
143 143
    }
144 144
    void nextIn(Arc &e) const {
145 145
      e.id=arcs[e.id].next_in;
146 146
    }
147 147

	
148 148
    
149 149
    static int id(Node v) { return v.id; }
150 150
    static int id(Arc e) { return e.id; }
151 151

	
152 152
    static Node nodeFromId(int id) { return Node(id);}
153 153
    static Arc arcFromId(int id) { return Arc(id);}
154 154

	
155 155
    Node addNode() {     
156 156
      int n;
157 157
      
158 158
      if(first_free_node==-1) {
159 159
	n = nodes.size();
160 160
	nodes.push_back(NodeT());
161 161
      } else {
162 162
	n = first_free_node;
163 163
	first_free_node = nodes[n].next;
164 164
      }
165 165
      
166 166
      nodes[n].next = first_node;
167 167
      if(first_node != -1) nodes[first_node].prev = n;
... ...
@@ -248,295 +248,303 @@
248 248
      
249 249
      arcs[n].next_in = first_free_arc;
250 250
      first_free_arc = n;      
251 251

	
252 252
    }
253 253

	
254 254
    void clear() {
255 255
      arcs.clear();
256 256
      nodes.clear();
257 257
      first_node = first_free_node = first_free_arc = -1;
258 258
    }
259 259

	
260 260
  protected:
261 261
    void changeTarget(Arc e, Node n) 
262 262
    {
263 263
      if(arcs[e.id].next_in != -1)
264 264
	arcs[arcs[e.id].next_in].prev_in = arcs[e.id].prev_in;
265 265
      if(arcs[e.id].prev_in != -1)
266 266
	arcs[arcs[e.id].prev_in].next_in = arcs[e.id].next_in;
267 267
      else nodes[arcs[e.id].target].first_in = arcs[e.id].next_in;
268 268
      if (nodes[n.id].first_in != -1) {
269 269
	arcs[nodes[n.id].first_in].prev_in = e.id;
270 270
      }
271 271
      arcs[e.id].target = n.id;
272 272
      arcs[e.id].prev_in = -1;
273 273
      arcs[e.id].next_in = nodes[n.id].first_in;
274 274
      nodes[n.id].first_in = e.id;
275 275
    }
276 276
    void changeSource(Arc e, Node n) 
277 277
    {
278 278
      if(arcs[e.id].next_out != -1)
279 279
	arcs[arcs[e.id].next_out].prev_out = arcs[e.id].prev_out;
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);
437 442
	e=f;
438 443
      }
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:
511 519
        
512 520
        virtual void add(const Node& node) {
513 521
          snapshot.addNode(node);
514 522
        }
515 523
        virtual void add(const std::vector<Node>& nodes) {
516 524
          for (int i = nodes.size() - 1; i >= 0; ++i) {
517 525
            snapshot.addNode(nodes[i]);
518 526
          }
519 527
        }
520 528
        virtual void erase(const Node& node) {
521 529
          snapshot.eraseNode(node);
522 530
        }
523 531
        virtual void erase(const std::vector<Node>& nodes) {
524 532
          for (int i = 0; i < int(nodes.size()); ++i) {
525 533
            snapshot.eraseNode(nodes[i]);
526 534
          }
527 535
        }
528 536
        virtual void build() {
529 537
          Node node;
530 538
          std::vector<Node> nodes;
531 539
          for (notifier()->first(node); node != INVALID; 
532 540
               notifier()->next(node)) {
533 541
            nodes.push_back(node);
534 542
          }
535 543
          for (int i = nodes.size() - 1; i >= 0; --i) {
536 544
            snapshot.addNode(nodes[i]);
537 545
          }
538 546
        }
539 547
        virtual void clear() {
540 548
          Node node;
541 549
          for (notifier()->first(node); node != INVALID; 
542 550
               notifier()->next(node)) {
... ...
@@ -731,99 +739,99 @@
731 739
    struct ArcT {
732 740
      int target;
733 741
      int prev_out, next_out;
734 742
    };
735 743

	
736 744
    std::vector<NodeT> nodes;
737 745

	
738 746
    int first_node;
739 747

	
740 748
    int first_free_node;
741 749

	
742 750
    std::vector<ArcT> arcs;
743 751

	
744 752
    int first_free_arc;
745 753
    
746 754
  public:
747 755
    
748 756
    typedef ListGraphBase Digraph;
749 757

	
750 758
    class Node;
751 759
    class Arc;
752 760
    class Edge;
753 761
    
754 762
    class Node {
755 763
      friend class ListGraphBase;
756 764
    protected:
757 765

	
758 766
      int id;
759 767
      explicit Node(int pid) { id = pid;}
760 768

	
761 769
    public:
762 770
      Node() {}
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;}
798 806
      bool operator<(const Arc& arc) const {return id < arc.id;}
799 807
    };
800 808

	
801 809

	
802 810

	
803 811
    ListGraphBase()
804 812
      : nodes(), first_node(-1),
805 813
	first_free_node(-1), arcs(), first_free_arc(-1) {}
806 814

	
807 815
    
808 816
    int maxNodeId() const { return nodes.size()-1; } 
809 817
    int maxEdgeId() const { return arcs.size() / 2 - 1; }
810 818
    int maxArcId() const { return arcs.size()-1; }
811 819

	
812 820
    Node source(Arc e) const { return Node(arcs[e.id ^ 1].target); }
813 821
    Node target(Arc e) const { return Node(arcs[e.id].target); }
814 822

	
815 823
    Node u(Edge e) const { return Node(arcs[2 * e.id].target); }
816 824
    Node v(Edge e) const { return Node(arcs[2 * e.id + 1].target); }
817 825

	
818 826
    static bool direction(Arc e) {
819 827
      return (e.id & 1) == 1;
820 828
    }
821 829

	
822 830
    static Arc direct(Edge e, bool d) {
823 831
      return Arc(e.id * 2 + (d ? 1 : 0));
824 832
    }
825 833

	
826 834
    void first(Node& node) const { 
827 835
      node.id = first_node;
828 836
    }
829 837

	
... ...
@@ -864,604 +872,618 @@
864 872
        } 
865 873
        n = nodes[n].next;
866 874
      }
867 875
      e.id = -1;
868 876
    }
869 877

	
870 878
    void next(Edge& e) const {
871 879
      int n = arcs[e.id * 2].target;
872 880
      e.id = arcs[(e.id * 2) | 1].next_out;
873 881
      while ((e.id & 1) != 1) {
874 882
        e.id = arcs[e.id].next_out;
875 883
      }
876 884
      if (e.id != -1) {
877 885
        e.id /= 2;
878 886
        return;
879 887
      } 
880 888
      n = nodes[n].next;
881 889
      while (n != -1) {
882 890
        e.id = nodes[n].first_out;
883 891
        while ((e.id & 1) != 1) {
884 892
          e.id = arcs[e.id].next_out;
885 893
        }
886 894
        if (e.id != -1) {
887 895
          e.id /= 2;
888 896
          return;
889 897
        } 
890 898
        n = nodes[n].next;
891 899
      }
892 900
      e.id = -1;
893 901
    }
894 902

	
895 903
    void firstOut(Arc &e, const Node& v) const {
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;
942 950
      
943 951
      if(first_free_node==-1) {
944 952
	n = nodes.size();
945 953
	nodes.push_back(NodeT());
946 954
      } else {
947 955
	n = first_free_node;
948 956
	first_free_node = nodes[n].next;
949 957
      }
950 958
      
951 959
      nodes[n].next = first_node;
952 960
      if (first_node != -1) nodes[first_node].prev = n;
953 961
      first_node = n;
954 962
      nodes[n].prev = -1;
955 963
      
956 964
      nodes[n].first_out = -1;
957 965
      
958 966
      return Node(n);
959 967
    }
960 968
    
961 969
    Edge addEdge(Node u, Node v) {
962 970
      int n;      
963 971

	
964 972
      if (first_free_arc == -1) {
965 973
	n = arcs.size();
966 974
	arcs.push_back(ArcT());
967 975
	arcs.push_back(ArcT());
968 976
      } else {
969 977
	n = first_free_arc;
970 978
	first_free_arc = arcs[n].next_out;
971 979
      }
972 980
      
973 981
      arcs[n].target = u.id;
974 982
      arcs[n | 1].target = v.id;
975 983

	
976 984
      arcs[n].next_out = nodes[v.id].first_out;
977 985
      if (nodes[v.id].first_out != -1) {
978 986
	arcs[nodes[v.id].first_out].prev_out = n;
979 987
      }      
980 988
      arcs[n].prev_out = -1;
981 989
      nodes[v.id].first_out = n;
982 990
      
983 991
      arcs[n | 1].next_out = nodes[u.id].first_out;
984 992
      if (nodes[u.id].first_out != -1) {
985 993
	arcs[nodes[u.id].first_out].prev_out = (n | 1);
986 994
      }
987 995
      arcs[n | 1].prev_out = -1;      
988 996
      nodes[u.id].first_out = (n | 1);
989 997

	
990 998
      return Edge(n / 2);
991 999
    }
992 1000
    
993 1001
    void erase(const Node& node) {
994 1002
      int n = node.id;
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) {
1029 1037
	arcs[arcs[n | 1].prev_out].next_out = arcs[n | 1].next_out;
1030 1038
      } else {
1031 1039
	nodes[arcs[n].target].first_out = arcs[n | 1].next_out;
1032 1040
      }
1033 1041
      
1034 1042
      arcs[n].next_out = first_free_arc;
1035 1043
      first_free_arc = n;      
1036 1044

	
1037 1045
    }
1038 1046

	
1039 1047
    void clear() {
1040 1048
      arcs.clear();
1041 1049
      nodes.clear();
1042 1050
      first_node = first_free_node = first_free_arc = -1;
1043 1051
    }
1044 1052

	
1045 1053
  protected:
1046 1054

	
1047 1055
    void changeTarget(Edge e, Node n) {
1048 1056
      if(arcs[2 * e.id].next_out != -1) {
1049 1057
	arcs[arcs[2 * e.id].next_out].prev_out = arcs[2 * e.id].prev_out;
1050 1058
      }
1051 1059
      if(arcs[2 * e.id].prev_out != -1) {
1052 1060
	arcs[arcs[2 * e.id].prev_out].next_out = 
1053 1061
          arcs[2 * e.id].next_out;
1054 1062
      } else {
1055 1063
        nodes[arcs[(2 * e.id) | 1].target].first_out = 
1056 1064
          arcs[2 * e.id].next_out;
1057 1065
      }
1058 1066

	
1059 1067
      if (nodes[n.id].first_out != -1) {
1060 1068
	arcs[nodes[n.id].first_out].prev_out = 2 * e.id;
1061 1069
      }
1062 1070
      arcs[(2 * e.id) | 1].target = n.id;
1063 1071
      arcs[2 * e.id].prev_out = -1;
1064 1072
      arcs[2 * e.id].next_out = nodes[n.id].first_out;
1065 1073
      nodes[n.id].first_out = 2 * e.id;
1066 1074
    }
1067 1075

	
1068 1076
    void changeSource(Edge e, Node n) {
1069 1077
      if(arcs[(2 * e.id) | 1].next_out != -1) {
1070 1078
	arcs[arcs[(2 * e.id) | 1].next_out].prev_out = 
1071 1079
          arcs[(2 * e.id) | 1].prev_out;
1072 1080
      }
1073 1081
      if(arcs[(2 * e.id) | 1].prev_out != -1) {
1074 1082
	arcs[arcs[(2 * e.id) | 1].prev_out].next_out = 
1075 1083
          arcs[(2 * e.id) | 1].next_out;
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:
1255 1277
        
1256 1278
        virtual void add(const Node& node) {
1257 1279
          snapshot.addNode(node);
1258 1280
        }
1259 1281
        virtual void add(const std::vector<Node>& nodes) {
1260 1282
          for (int i = nodes.size() - 1; i >= 0; ++i) {
1261 1283
            snapshot.addNode(nodes[i]);
1262 1284
          }
1263 1285
        }
1264 1286
        virtual void erase(const Node& node) {
1265 1287
          snapshot.eraseNode(node);
1266 1288
        }
1267 1289
        virtual void erase(const std::vector<Node>& nodes) {
1268 1290
          for (int i = 0; i < int(nodes.size()); ++i) {
1269 1291
            snapshot.eraseNode(nodes[i]);
1270 1292
          }
1271 1293
        }
1272 1294
        virtual void build() {
1273 1295
          Node node;
1274 1296
          std::vector<Node> nodes;
1275 1297
          for (notifier()->first(node); node != INVALID; 
1276 1298
               notifier()->next(node)) {
1277 1299
            nodes.push_back(node);
1278 1300
          }
1279 1301
          for (int i = nodes.size() - 1; i >= 0; --i) {
1280 1302
            snapshot.addNode(nodes[i]);
1281 1303
          }
1282 1304
        }
1283 1305
        virtual void clear() {
1284 1306
          Node node;
1285 1307
          for (notifier()->first(node); node != INVALID; 
1286 1308
               notifier()->next(node)) {
1287 1309
            snapshot.eraseNode(node);
1288 1310
          }
1289 1311
        }
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
  
1466 1488

	
1467 1489
#endif
0 comments (0 inline)