gravatar
kpeter (Peter Kovacs)
kpeter@inf.elte.hu
Small doc improvements (#263)
0 19 0
default
19 files changed:
↑ 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-2009
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_BIN_HEAP_H
20 20
#define LEMON_BIN_HEAP_H
21 21

	
22 22
///\ingroup auxdat
23 23
///\file
24 24
///\brief Binary Heap implementation.
25 25

	
26 26
#include <vector>
27 27
#include <utility>
28 28
#include <functional>
29 29

	
30 30
namespace lemon {
31 31

	
32 32
  ///\ingroup auxdat
33 33
  ///
34 34
  ///\brief A Binary Heap implementation.
35 35
  ///
36 36
  ///This class implements the \e binary \e heap data structure. 
37 37
  /// 
38 38
  ///A \e heap is a data structure for storing items with specified values
39 39
  ///called \e priorities in such a way that finding the item with minimum
40 40
  ///priority is efficient. \c Comp specifies the ordering of the priorities.
41 41
  ///In a heap one can change the priority of an item, add or erase an
42 42
  ///item, etc.
43 43
  ///
44 44
  ///\tparam PR Type of the priority of the items.
45 45
  ///\tparam IM A read and writable item map with int values, used internally
46 46
  ///to handle the cross references.
47 47
  ///\tparam Comp A functor class for the ordering of the priorities.
48 48
  ///The default is \c std::less<PR>.
49 49
  ///
50 50
  ///\sa FibHeap
51 51
  ///\sa Dijkstra
52 52
  template <typename PR, typename IM, typename Comp = std::less<PR> >
53 53
  class BinHeap {
54 54

	
55 55
  public:
56 56
    ///\e
57 57
    typedef IM ItemIntMap;
58 58
    ///\e
59 59
    typedef PR Prio;
60 60
    ///\e
61 61
    typedef typename ItemIntMap::Key Item;
62 62
    ///\e
63 63
    typedef std::pair<Item,Prio> Pair;
64 64
    ///\e
65 65
    typedef Comp Compare;
66 66

	
67 67
    /// \brief Type to represent the items states.
68 68
    ///
69 69
    /// Each Item element have a state associated to it. It may be "in heap",
70 70
    /// "pre heap" or "post heap". The latter two are indifferent from the
71 71
    /// heap's point of view, but may be useful to the user.
72 72
    ///
73 73
    /// The item-int map must be initialized in such way that it assigns
74 74
    /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
75 75
    enum State {
76
      IN_HEAP = 0,    ///< \e
77
      PRE_HEAP = -1,  ///< \e
78
      POST_HEAP = -2  ///< \e
76
      IN_HEAP = 0,    ///< = 0.
77
      PRE_HEAP = -1,  ///< = -1.
78
      POST_HEAP = -2  ///< = -2.
79 79
    };
80 80

	
81 81
  private:
82 82
    std::vector<Pair> _data;
83 83
    Compare _comp;
84 84
    ItemIntMap &_iim;
85 85

	
86 86
  public:
87 87
    /// \brief The constructor.
88 88
    ///
89 89
    /// The constructor.
90 90
    /// \param map should be given to the constructor, since it is used
91 91
    /// internally to handle the cross references. The value of the map
92 92
    /// must be \c PRE_HEAP (<tt>-1</tt>) for every item.
93 93
    explicit BinHeap(ItemIntMap &map) : _iim(map) {}
94 94

	
95 95
    /// \brief The constructor.
96 96
    ///
97 97
    /// The constructor.
98 98
    /// \param map should be given to the constructor, since it is used
99 99
    /// internally to handle the cross references. The value of the map
100 100
    /// should be PRE_HEAP (-1) for each element.
101 101
    ///
102 102
    /// \param comp The comparator function object.
103 103
    BinHeap(ItemIntMap &map, const Compare &comp)
104 104
      : _iim(map), _comp(comp) {}
105 105

	
106 106

	
107 107
    /// The number of items stored in the heap.
108 108
    ///
109 109
    /// \brief Returns the number of items stored in the heap.
110 110
    int size() const { return _data.size(); }
111 111

	
112 112
    /// \brief Checks if the heap stores no items.
113 113
    ///
114 114
    /// Returns \c true if and only if the heap stores no items.
115 115
    bool empty() const { return _data.empty(); }
116 116

	
117 117
    /// \brief Make empty this heap.
118 118
    ///
119 119
    /// Make empty this heap. It does not change the cross reference map.
120 120
    /// If you want to reuse what is not surely empty you should first clear
121 121
    /// the heap and after that you should set the cross reference map for
122 122
    /// each item to \c PRE_HEAP.
123 123
    void clear() {
124 124
      _data.clear();
125 125
    }
126 126

	
127 127
  private:
128 128
    static int parent(int i) { return (i-1)/2; }
129 129

	
130 130
    static int second_child(int i) { return 2*i+2; }
131 131
    bool less(const Pair &p1, const Pair &p2) const {
132 132
      return _comp(p1.second, p2.second);
133 133
    }
134 134

	
135 135
    int bubble_up(int hole, Pair p) {
136 136
      int par = parent(hole);
137 137
      while( hole>0 && less(p,_data[par]) ) {
138 138
        move(_data[par],hole);
139 139
        hole = par;
140 140
        par = parent(hole);
141 141
      }
142 142
      move(p, hole);
143 143
      return hole;
144 144
    }
145 145

	
146 146
    int bubble_down(int hole, Pair p, int length) {
147 147
      int child = second_child(hole);
148 148
      while(child < length) {
149 149
        if( less(_data[child-1], _data[child]) ) {
150 150
          --child;
151 151
        }
152 152
        if( !less(_data[child], p) )
153 153
          goto ok;
154 154
        move(_data[child], hole);
155 155
        hole = child;
156 156
        child = second_child(hole);
157 157
      }
158 158
      child--;
159 159
      if( child<length && less(_data[child], p) ) {
160 160
        move(_data[child], hole);
161 161
        hole=child;
162 162
      }
163 163
    ok:
164 164
      move(p, hole);
165 165
      return hole;
166 166
    }
167 167

	
168 168
    void move(const Pair &p, int i) {
169 169
      _data[i] = p;
170 170
      _iim.set(p.first, i);
171 171
    }
172 172

	
173 173
  public:
174 174
    /// \brief Insert a pair of item and priority into the heap.
175 175
    ///
176 176
    /// Adds \c p.first to the heap with priority \c p.second.
177 177
    /// \param p The pair to insert.
178 178
    void push(const Pair &p) {
179 179
      int n = _data.size();
180 180
      _data.resize(n+1);
181 181
      bubble_up(n, p);
182 182
    }
183 183

	
184 184
    /// \brief Insert an item into the heap with the given heap.
185 185
    ///
186 186
    /// Adds \c i to the heap with priority \c p.
187 187
    /// \param i The item to insert.
188 188
    /// \param p The priority of the item.
189 189
    void push(const Item &i, const Prio &p) { push(Pair(i,p)); }
190 190

	
191 191
    /// \brief Returns the item with minimum priority relative to \c Compare.
192 192
    ///
193 193
    /// This method returns the item with minimum priority relative to \c
194 194
    /// Compare.
195 195
    /// \pre The heap must be nonempty.
196 196
    Item top() const {
197 197
      return _data[0].first;
198 198
    }
199 199

	
200 200
    /// \brief Returns the minimum priority relative to \c Compare.
201 201
    ///
202 202
    /// It returns the minimum priority relative to \c Compare.
203 203
    /// \pre The heap must be nonempty.
204 204
    Prio prio() const {
205 205
      return _data[0].second;
206 206
    }
207 207

	
208 208
    /// \brief Deletes the item with minimum priority relative to \c Compare.
209 209
    ///
210 210
    /// This method deletes the item with minimum priority relative to \c
211 211
    /// Compare from the heap.
212 212
    /// \pre The heap must be non-empty.
213 213
    void pop() {
214 214
      int n = _data.size()-1;
215 215
      _iim.set(_data[0].first, POST_HEAP);
216 216
      if (n > 0) {
217 217
        bubble_down(0, _data[n], n);
218 218
      }
219 219
      _data.pop_back();
220 220
    }
221 221

	
222 222
    /// \brief Deletes \c i from the heap.
223 223
    ///
224 224
    /// This method deletes item \c i from the heap.
225 225
    /// \param i The item to erase.
226 226
    /// \pre The item should be in the heap.
227 227
    void erase(const Item &i) {
228 228
      int h = _iim[i];
229 229
      int n = _data.size()-1;
230 230
      _iim.set(_data[h].first, POST_HEAP);
231 231
      if( h < n ) {
232 232
        if ( bubble_up(h, _data[n]) == h) {
233 233
          bubble_down(h, _data[n], n);
234 234
        }
235 235
      }
236 236
      _data.pop_back();
237 237
    }
238 238

	
239 239

	
240 240
    /// \brief Returns the priority of \c i.
241 241
    ///
242 242
    /// This function returns the priority of item \c i.
243 243
    /// \param i The item.
244 244
    /// \pre \c i must be in the heap.
245 245
    Prio operator[](const Item &i) const {
246 246
      int idx = _iim[i];
247 247
      return _data[idx].second;
248 248
    }
249 249

	
250 250
    /// \brief \c i gets to the heap with priority \c p independently
251 251
    /// if \c i was already there.
252 252
    ///
253 253
    /// This method calls \ref push(\c i, \c p) if \c i is not stored
254 254
    /// in the heap and sets the priority of \c i to \c p otherwise.
255 255
    /// \param i The item.
256 256
    /// \param p The priority.
257 257
    void set(const Item &i, const Prio &p) {
258 258
      int idx = _iim[i];
259 259
      if( idx < 0 ) {
260 260
        push(i,p);
261 261
      }
262 262
      else if( _comp(p, _data[idx].second) ) {
263 263
        bubble_up(idx, Pair(i,p));
264 264
      }
265 265
      else {
266 266
        bubble_down(idx, Pair(i,p), _data.size());
267 267
      }
268 268
    }
269 269

	
270 270
    /// \brief Decreases the priority of \c i to \c p.
Ignore white space 384 line context
... ...
@@ -413,601 +413,601 @@
413 413
          ueid = graph.id(edge);
414 414
          edge = graph.edgeFromId(ueid);
415 415
          ueid = graph.maxEdgeId();
416 416
          ignore_unused_variable_warning(ueid);
417 417
        }
418 418

	
419 419
        const _Graph& graph;
420 420
      };
421 421
    };
422 422

	
423 423
    /// \brief Concept class for \c NodeIt, \c ArcIt and \c EdgeIt types.
424 424
    ///
425 425
    /// This class describes the concept of \c NodeIt, \c ArcIt and 
426 426
    /// \c EdgeIt subtypes of digraph and graph types.
427 427
    template <typename GR, typename Item>
428 428
    class GraphItemIt : public Item {
429 429
    public:
430 430
      /// \brief Default constructor.
431 431
      ///
432 432
      /// Default constructor.
433 433
      /// \warning The default constructor is not required to set
434 434
      /// the iterator to some well-defined value. So you should consider it
435 435
      /// as uninitialized.
436 436
      GraphItemIt() {}
437 437

	
438 438
      /// \brief Copy constructor.
439 439
      ///
440 440
      /// Copy constructor.
441 441
      GraphItemIt(const GraphItemIt& it) : Item(it) {}
442 442

	
443 443
      /// \brief Constructor that sets the iterator to the first item.
444 444
      ///
445 445
      /// Constructor that sets the iterator to the first item.
446 446
      explicit GraphItemIt(const GR&) {}
447 447

	
448 448
      /// \brief Constructor for conversion from \c INVALID.
449 449
      ///
450 450
      /// Constructor for conversion from \c INVALID.
451 451
      /// It initializes the iterator to be invalid.
452 452
      /// \sa Invalid for more details.
453 453
      GraphItemIt(Invalid) {}
454 454

	
455 455
      /// \brief Assignment operator.
456 456
      ///
457 457
      /// Assignment operator for the iterator.
458 458
      GraphItemIt& operator=(const GraphItemIt&) { return *this; }
459 459

	
460 460
      /// \brief Increment the iterator.
461 461
      ///
462 462
      /// This operator increments the iterator, i.e. assigns it to the
463 463
      /// next item.
464 464
      GraphItemIt& operator++() { return *this; }
465 465
 
466 466
      /// \brief Equality operator
467 467
      ///
468 468
      /// Equality operator.
469 469
      /// Two iterators are equal if and only if they point to the
470 470
      /// same object or both are invalid.
471 471
      bool operator==(const GraphItemIt&) const { return true;}
472 472

	
473 473
      /// \brief Inequality operator
474 474
      ///
475 475
      /// Inequality operator.
476 476
      /// Two iterators are equal if and only if they point to the
477 477
      /// same object or both are invalid.
478 478
      bool operator!=(const GraphItemIt&) const { return true;}
479 479

	
480 480
      template<typename _GraphItemIt>
481 481
      struct Constraints {
482 482
        void constraints() {
483 483
          checkConcept<GraphItem<>, _GraphItemIt>();
484 484
          _GraphItemIt it1(g);
485 485
          _GraphItemIt it2;
486 486
          _GraphItemIt it3 = it1;
487 487
          _GraphItemIt it4 = INVALID;
488 488

	
489 489
          it2 = ++it1;
490 490
          ++it2 = it1;
491 491
          ++(++it1);
492 492

	
493 493
          Item bi = it1;
494 494
          bi = it2;
495 495
        }
496 496
        const GR& g;
497 497
      };
498 498
    };
499 499

	
500 500
    /// \brief Concept class for \c InArcIt, \c OutArcIt and 
501 501
    /// \c IncEdgeIt types.
502 502
    ///
503 503
    /// This class describes the concept of \c InArcIt, \c OutArcIt 
504 504
    /// and \c IncEdgeIt subtypes of digraph and graph types.
505 505
    ///
506 506
    /// \note Since these iterator classes do not inherit from the same
507 507
    /// base class, there is an additional template parameter (selector)
508 508
    /// \c sel. For \c InArcIt you should instantiate it with character 
509 509
    /// \c 'i', for \c OutArcIt with \c 'o' and for \c IncEdgeIt with \c 'e'.
510 510
    template <typename GR,
511 511
              typename Item = typename GR::Arc,
512 512
              typename Base = typename GR::Node,
513 513
              char sel = '0'>
514 514
    class GraphIncIt : public Item {
515 515
    public:
516 516
      /// \brief Default constructor.
517 517
      ///
518 518
      /// Default constructor.
519 519
      /// \warning The default constructor is not required to set
520 520
      /// the iterator to some well-defined value. So you should consider it
521 521
      /// as uninitialized.
522 522
      GraphIncIt() {}
523 523

	
524 524
      /// \brief Copy constructor.
525 525
      ///
526 526
      /// Copy constructor.
527 527
      GraphIncIt(const GraphIncIt& it) : Item(it) {}
528 528

	
529 529
      /// \brief Constructor that sets the iterator to the first 
530 530
      /// incoming or outgoing arc.
531 531
      ///
532 532
      /// Constructor that sets the iterator to the first arc 
533 533
      /// incoming to or outgoing from the given node.
534 534
      explicit GraphIncIt(const GR&, const Base&) {}
535 535

	
536 536
      /// \brief Constructor for conversion from \c INVALID.
537 537
      ///
538 538
      /// Constructor for conversion from \c INVALID.
539 539
      /// It initializes the iterator to be invalid.
540 540
      /// \sa Invalid for more details.
541 541
      GraphIncIt(Invalid) {}
542 542

	
543 543
      /// \brief Assignment operator.
544 544
      ///
545 545
      /// Assignment operator for the iterator.
546 546
      GraphIncIt& operator=(const GraphIncIt&) { return *this; }
547 547

	
548 548
      /// \brief Increment the iterator.
549 549
      ///
550 550
      /// This operator increments the iterator, i.e. assigns it to the
551 551
      /// next arc incoming to or outgoing from the given node.
552 552
      GraphIncIt& operator++() { return *this; }
553 553

	
554 554
      /// \brief Equality operator
555 555
      ///
556 556
      /// Equality operator.
557 557
      /// Two iterators are equal if and only if they point to the
558 558
      /// same object or both are invalid.
559 559
      bool operator==(const GraphIncIt&) const { return true;}
560 560

	
561 561
      /// \brief Inequality operator
562 562
      ///
563 563
      /// Inequality operator.
564 564
      /// Two iterators are equal if and only if they point to the
565 565
      /// same object or both are invalid.
566 566
      bool operator!=(const GraphIncIt&) const { return true;}
567 567

	
568 568
      template <typename _GraphIncIt>
569 569
      struct Constraints {
570 570
        void constraints() {
571 571
          checkConcept<GraphItem<sel>, _GraphIncIt>();
572 572
          _GraphIncIt it1(graph, node);
573 573
          _GraphIncIt it2;
574 574
          _GraphIncIt it3 = it1;
575 575
          _GraphIncIt it4 = INVALID;
576 576

	
577 577
          it2 = ++it1;
578 578
          ++it2 = it1;
579 579
          ++(++it1);
580 580
          Item e = it1;
581 581
          e = it2;
582 582
        }
583 583
        const Base& node;
584 584
        const GR& graph;
585 585
      };
586 586
    };
587 587

	
588 588
    /// \brief Skeleton class for iterable directed graphs.
589 589
    ///
590 590
    /// This class describes the interface of iterable directed
591 591
    /// graphs. It extends \ref BaseDigraphComponent with the core
592 592
    /// iterable interface.
593 593
    /// This concept is part of the Digraph concept.
594 594
    template <typename BAS = BaseDigraphComponent>
595 595
    class IterableDigraphComponent : public BAS {
596 596

	
597 597
    public:
598 598

	
599 599
      typedef BAS Base;
600 600
      typedef typename Base::Node Node;
601 601
      typedef typename Base::Arc Arc;
602 602

	
603 603
      typedef IterableDigraphComponent Digraph;
604 604

	
605
      /// \name Base iteration
605
      /// \name Base Iteration
606 606
      ///
607 607
      /// This interface provides functions for iteration on digraph items.
608 608
      ///
609 609
      /// @{
610 610

	
611 611
      /// \brief Return the first node.
612 612
      ///
613 613
      /// This function gives back the first node in the iteration order.
614 614
      void first(Node&) const {}
615 615

	
616 616
      /// \brief Return the next node.
617 617
      ///
618 618
      /// This function gives back the next node in the iteration order.
619 619
      void next(Node&) const {}
620 620

	
621 621
      /// \brief Return the first arc.
622 622
      ///
623 623
      /// This function gives back the first arc in the iteration order.
624 624
      void first(Arc&) const {}
625 625

	
626 626
      /// \brief Return the next arc.
627 627
      ///
628 628
      /// This function gives back the next arc in the iteration order.
629 629
      void next(Arc&) const {}
630 630

	
631 631
      /// \brief Return the first arc incomming to the given node.
632 632
      ///
633 633
      /// This function gives back the first arc incomming to the
634 634
      /// given node.
635 635
      void firstIn(Arc&, const Node&) const {}
636 636

	
637 637
      /// \brief Return the next arc incomming to the given node.
638 638
      ///
639 639
      /// This function gives back the next arc incomming to the
640 640
      /// given node.
641 641
      void nextIn(Arc&) const {}
642 642

	
643 643
      /// \brief Return the first arc outgoing form the given node.
644 644
      ///
645 645
      /// This function gives back the first arc outgoing form the
646 646
      /// given node.
647 647
      void firstOut(Arc&, const Node&) const {}
648 648

	
649 649
      /// \brief Return the next arc outgoing form the given node.
650 650
      ///
651 651
      /// This function gives back the next arc outgoing form the
652 652
      /// given node.
653 653
      void nextOut(Arc&) const {}
654 654

	
655 655
      /// @}
656 656

	
657
      /// \name Class based iteration
657
      /// \name Class Based Iteration
658 658
      ///
659 659
      /// This interface provides iterator classes for digraph items.
660 660
      ///
661 661
      /// @{
662 662

	
663 663
      /// \brief This iterator goes through each node.
664 664
      ///
665 665
      /// This iterator goes through each node.
666 666
      ///
667 667
      typedef GraphItemIt<Digraph, Node> NodeIt;
668 668

	
669 669
      /// \brief This iterator goes through each arc.
670 670
      ///
671 671
      /// This iterator goes through each arc.
672 672
      ///
673 673
      typedef GraphItemIt<Digraph, Arc> ArcIt;
674 674

	
675 675
      /// \brief This iterator goes trough the incoming arcs of a node.
676 676
      ///
677 677
      /// This iterator goes trough the \e incoming arcs of a certain node
678 678
      /// of a digraph.
679 679
      typedef GraphIncIt<Digraph, Arc, Node, 'i'> InArcIt;
680 680

	
681 681
      /// \brief This iterator goes trough the outgoing arcs of a node.
682 682
      ///
683 683
      /// This iterator goes trough the \e outgoing arcs of a certain node
684 684
      /// of a digraph.
685 685
      typedef GraphIncIt<Digraph, Arc, Node, 'o'> OutArcIt;
686 686

	
687 687
      /// \brief The base node of the iterator.
688 688
      ///
689 689
      /// This function gives back the base node of the iterator.
690 690
      /// It is always the target node of the pointed arc.
691 691
      Node baseNode(const InArcIt&) const { return INVALID; }
692 692

	
693 693
      /// \brief The running node of the iterator.
694 694
      ///
695 695
      /// This function gives back the running node of the iterator.
696 696
      /// It is always the source node of the pointed arc.
697 697
      Node runningNode(const InArcIt&) const { return INVALID; }
698 698

	
699 699
      /// \brief The base node of the iterator.
700 700
      ///
701 701
      /// This function gives back the base node of the iterator.
702 702
      /// It is always the source node of the pointed arc.
703 703
      Node baseNode(const OutArcIt&) const { return INVALID; }
704 704

	
705 705
      /// \brief The running node of the iterator.
706 706
      ///
707 707
      /// This function gives back the running node of the iterator.
708 708
      /// It is always the target node of the pointed arc.
709 709
      Node runningNode(const OutArcIt&) const { return INVALID; }
710 710

	
711 711
      /// @}
712 712

	
713 713
      template <typename _Digraph>
714 714
      struct Constraints {
715 715
        void constraints() {
716 716
          checkConcept<Base, _Digraph>();
717 717

	
718 718
          {
719 719
            typename _Digraph::Node node(INVALID);
720 720
            typename _Digraph::Arc arc(INVALID);
721 721
            {
722 722
              digraph.first(node);
723 723
              digraph.next(node);
724 724
            }
725 725
            {
726 726
              digraph.first(arc);
727 727
              digraph.next(arc);
728 728
            }
729 729
            {
730 730
              digraph.firstIn(arc, node);
731 731
              digraph.nextIn(arc);
732 732
            }
733 733
            {
734 734
              digraph.firstOut(arc, node);
735 735
              digraph.nextOut(arc);
736 736
            }
737 737
          }
738 738

	
739 739
          {
740 740
            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Arc>,
741 741
              typename _Digraph::ArcIt >();
742 742
            checkConcept<GraphItemIt<_Digraph, typename _Digraph::Node>,
743 743
              typename _Digraph::NodeIt >();
744 744
            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
745 745
              typename _Digraph::Node, 'i'>, typename _Digraph::InArcIt>();
746 746
            checkConcept<GraphIncIt<_Digraph, typename _Digraph::Arc,
747 747
              typename _Digraph::Node, 'o'>, typename _Digraph::OutArcIt>();
748 748

	
749 749
            typename _Digraph::Node n;
750 750
            const typename _Digraph::InArcIt iait(INVALID);
751 751
            const typename _Digraph::OutArcIt oait(INVALID);
752 752
            n = digraph.baseNode(iait);
753 753
            n = digraph.runningNode(iait);
754 754
            n = digraph.baseNode(oait);
755 755
            n = digraph.runningNode(oait);
756 756
            ignore_unused_variable_warning(n);
757 757
          }
758 758
        }
759 759

	
760 760
        const _Digraph& digraph;
761 761
      };
762 762
    };
763 763

	
764 764
    /// \brief Skeleton class for iterable undirected graphs.
765 765
    ///
766 766
    /// This class describes the interface of iterable undirected
767 767
    /// graphs. It extends \ref IterableDigraphComponent with the core
768 768
    /// iterable interface of undirected graphs.
769 769
    /// This concept is part of the Graph concept.
770 770
    template <typename BAS = BaseGraphComponent>
771 771
    class IterableGraphComponent : public IterableDigraphComponent<BAS> {
772 772
    public:
773 773

	
774 774
      typedef BAS Base;
775 775
      typedef typename Base::Node Node;
776 776
      typedef typename Base::Arc Arc;
777 777
      typedef typename Base::Edge Edge;
778 778

	
779 779

	
780 780
      typedef IterableGraphComponent Graph;
781 781

	
782
      /// \name Base iteration
782
      /// \name Base Iteration
783 783
      ///
784 784
      /// This interface provides functions for iteration on edges.
785 785
      ///
786 786
      /// @{
787 787

	
788 788
      using IterableDigraphComponent<Base>::first;
789 789
      using IterableDigraphComponent<Base>::next;
790 790

	
791 791
      /// \brief Return the first edge.
792 792
      ///
793 793
      /// This function gives back the first edge in the iteration order.
794 794
      void first(Edge&) const {}
795 795

	
796 796
      /// \brief Return the next edge.
797 797
      ///
798 798
      /// This function gives back the next edge in the iteration order.
799 799
      void next(Edge&) const {}
800 800

	
801 801
      /// \brief Return the first edge incident to the given node.
802 802
      ///
803 803
      /// This function gives back the first edge incident to the given 
804 804
      /// node. The bool parameter gives back the direction for which the
805 805
      /// source node of the directed arc representing the edge is the 
806 806
      /// given node.
807 807
      void firstInc(Edge&, bool&, const Node&) const {}
808 808

	
809 809
      /// \brief Gives back the next of the edges from the
810 810
      /// given node.
811 811
      ///
812 812
      /// This function gives back the next edge incident to the given 
813 813
      /// node. The bool parameter should be used as \c firstInc() use it.
814 814
      void nextInc(Edge&, bool&) const {}
815 815

	
816 816
      using IterableDigraphComponent<Base>::baseNode;
817 817
      using IterableDigraphComponent<Base>::runningNode;
818 818

	
819 819
      /// @}
820 820

	
821
      /// \name Class based iteration
821
      /// \name Class Based Iteration
822 822
      ///
823 823
      /// This interface provides iterator classes for edges.
824 824
      ///
825 825
      /// @{
826 826

	
827 827
      /// \brief This iterator goes through each edge.
828 828
      ///
829 829
      /// This iterator goes through each edge.
830 830
      typedef GraphItemIt<Graph, Edge> EdgeIt;
831 831

	
832 832
      /// \brief This iterator goes trough the incident edges of a
833 833
      /// node.
834 834
      ///
835 835
      /// This iterator goes trough the incident edges of a certain
836 836
      /// node of a graph.
837 837
      typedef GraphIncIt<Graph, Edge, Node, 'e'> IncEdgeIt;
838 838

	
839 839
      /// \brief The base node of the iterator.
840 840
      ///
841 841
      /// This function gives back the base node of the iterator.
842 842
      Node baseNode(const IncEdgeIt&) const { return INVALID; }
843 843

	
844 844
      /// \brief The running node of the iterator.
845 845
      ///
846 846
      /// This function gives back the running node of the iterator.
847 847
      Node runningNode(const IncEdgeIt&) const { return INVALID; }
848 848

	
849 849
      /// @}
850 850

	
851 851
      template <typename _Graph>
852 852
      struct Constraints {
853 853
        void constraints() {
854 854
          checkConcept<IterableDigraphComponent<Base>, _Graph>();
855 855

	
856 856
          {
857 857
            typename _Graph::Node node(INVALID);
858 858
            typename _Graph::Edge edge(INVALID);
859 859
            bool dir;
860 860
            {
861 861
              graph.first(edge);
862 862
              graph.next(edge);
863 863
            }
864 864
            {
865 865
              graph.firstInc(edge, dir, node);
866 866
              graph.nextInc(edge, dir);
867 867
            }
868 868

	
869 869
          }
870 870

	
871 871
          {
872 872
            checkConcept<GraphItemIt<_Graph, typename _Graph::Edge>,
873 873
              typename _Graph::EdgeIt >();
874 874
            checkConcept<GraphIncIt<_Graph, typename _Graph::Edge,
875 875
              typename _Graph::Node, 'e'>, typename _Graph::IncEdgeIt>();
876 876

	
877 877
            typename _Graph::Node n;
878 878
            const typename _Graph::IncEdgeIt ieit(INVALID);
879 879
            n = graph.baseNode(ieit);
880 880
            n = graph.runningNode(ieit);
881 881
          }
882 882
        }
883 883

	
884 884
        const _Graph& graph;
885 885
      };
886 886
    };
887 887

	
888 888
    /// \brief Skeleton class for alterable directed graphs.
889 889
    ///
890 890
    /// This class describes the interface of alterable directed
891 891
    /// graphs. It extends \ref BaseDigraphComponent with the alteration
892 892
    /// notifier interface. It implements
893 893
    /// an observer-notifier pattern for each digraph item. More
894 894
    /// obsevers can be registered into the notifier and whenever an
895 895
    /// alteration occured in the digraph all the observers will be
896 896
    /// notified about it.
897 897
    template <typename BAS = BaseDigraphComponent>
898 898
    class AlterableDigraphComponent : public BAS {
899 899
    public:
900 900

	
901 901
      typedef BAS Base;
902 902
      typedef typename Base::Node Node;
903 903
      typedef typename Base::Arc Arc;
904 904

	
905 905

	
906 906
      /// Node alteration notifier class.
907 907
      typedef AlterationNotifier<AlterableDigraphComponent, Node>
908 908
      NodeNotifier;
909 909
      /// Arc alteration notifier class.
910 910
      typedef AlterationNotifier<AlterableDigraphComponent, Arc>
911 911
      ArcNotifier;
912 912

	
913 913
      /// \brief Return the node alteration notifier.
914 914
      ///
915 915
      /// This function gives back the node alteration notifier.
916 916
      NodeNotifier& notifier(Node) const {
917 917
         return NodeNotifier();
918 918
      }
919 919

	
920 920
      /// \brief Return the arc alteration notifier.
921 921
      ///
922 922
      /// This function gives back the arc alteration notifier.
923 923
      ArcNotifier& notifier(Arc) const {
924 924
        return ArcNotifier();
925 925
      }
926 926

	
927 927
      template <typename _Digraph>
928 928
      struct Constraints {
929 929
        void constraints() {
930 930
          checkConcept<Base, _Digraph>();
931 931
          typename _Digraph::NodeNotifier& nn
932 932
            = digraph.notifier(typename _Digraph::Node());
933 933

	
934 934
          typename _Digraph::ArcNotifier& en
935 935
            = digraph.notifier(typename _Digraph::Arc());
936 936

	
937 937
          ignore_unused_variable_warning(nn);
938 938
          ignore_unused_variable_warning(en);
939 939
        }
940 940

	
941 941
        const _Digraph& digraph;
942 942
      };
943 943
    };
944 944

	
945 945
    /// \brief Skeleton class for alterable undirected graphs.
946 946
    ///
947 947
    /// This class describes the interface of alterable undirected
948 948
    /// graphs. It extends \ref AlterableDigraphComponent with the alteration
949 949
    /// notifier interface of undirected graphs. It implements
950 950
    /// an observer-notifier pattern for the edges. More
951 951
    /// obsevers can be registered into the notifier and whenever an
952 952
    /// alteration occured in the graph all the observers will be
953 953
    /// notified about it.
954 954
    template <typename BAS = BaseGraphComponent>
955 955
    class AlterableGraphComponent : public AlterableDigraphComponent<BAS> {
956 956
    public:
957 957

	
958 958
      typedef BAS Base;
959 959
      typedef typename Base::Edge Edge;
960 960

	
961 961

	
962 962
      /// Edge alteration notifier class.
963 963
      typedef AlterationNotifier<AlterableGraphComponent, Edge>
964 964
      EdgeNotifier;
965 965

	
966 966
      /// \brief Return the edge alteration notifier.
967 967
      ///
968 968
      /// This function gives back the edge alteration notifier.
969 969
      EdgeNotifier& notifier(Edge) const {
970 970
        return EdgeNotifier();
971 971
      }
972 972

	
973 973
      template <typename _Graph>
974 974
      struct Constraints {
975 975
        void constraints() {
976 976
          checkConcept<AlterableDigraphComponent<Base>, _Graph>();
977 977
          typename _Graph::EdgeNotifier& uen
978 978
            = graph.notifier(typename _Graph::Edge());
979 979
          ignore_unused_variable_warning(uen);
980 980
        }
981 981

	
982 982
        const _Graph& graph;
983 983
      };
984 984
    };
985 985

	
986 986
    /// \brief Concept class for standard graph maps.
987 987
    ///
988 988
    /// This class describes the concept of standard graph maps, i.e.
989 989
    /// the \c NodeMap, \c ArcMap and \c EdgeMap subtypes of digraph and 
990 990
    /// graph types, which can be used for associating data to graph items.
991 991
    /// The standard graph maps must conform to the ReferenceMap concept.
992 992
    template <typename GR, typename K, typename V>
993 993
    class GraphMap : public ReferenceMap<K, V, V&, const V&> {
994 994
    public:
995 995

	
996 996
      typedef ReadWriteMap<K, V> Parent;
997 997

	
998 998
      /// The graph type of the map.
999 999
      typedef GR Graph;
1000 1000
      /// The key type of the map.
1001 1001
      typedef K Key;
1002 1002
      /// The value type of the map.
1003 1003
      typedef V Value;
1004 1004
      /// The reference type of the map.
1005 1005
      typedef Value& Reference;
1006 1006
      /// The const reference type of the map.
1007 1007
      typedef const Value& ConstReference;
1008 1008

	
1009 1009
      // The reference map tag.
1010 1010
      typedef True ReferenceMapTag;
1011 1011

	
1012 1012
      /// \brief Construct a new map.
1013 1013
      ///
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-2009
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
///\ingroup concept
20 20
///\file
21 21
///\brief The concept of heaps.
22 22

	
23 23
#ifndef LEMON_CONCEPTS_HEAP_H
24 24
#define LEMON_CONCEPTS_HEAP_H
25 25

	
26 26
#include <lemon/core.h>
27 27
#include <lemon/concept_check.h>
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  namespace concepts {
32 32

	
33 33
    /// \addtogroup concept
34 34
    /// @{
35 35

	
36 36
    /// \brief The heap concept.
37 37
    ///
38 38
    /// Concept class describing the main interface of heaps. A \e heap
39 39
    /// is a data structure for storing items with specified values called
40 40
    /// \e priorities in such a way that finding the item with minimum
41 41
    /// priority is efficient. In a heap one can change the priority of an
42 42
    /// item, add or erase an item, etc.
43 43
    ///
44 44
    /// \tparam PR Type of the priority of the items.
45 45
    /// \tparam IM A read and writable item map with int values, used
46 46
    /// internally to handle the cross references.
47 47
    /// \tparam Comp A functor class for the ordering of the priorities.
48 48
    /// The default is \c std::less<PR>.
49 49
#ifdef DOXYGEN
50 50
    template <typename PR, typename IM, typename Comp = std::less<PR> >
51 51
#else
52 52
    template <typename PR, typename IM>
53 53
#endif
54 54
    class Heap {
55 55
    public:
56 56

	
57 57
      /// Type of the item-int map.
58 58
      typedef IM ItemIntMap;
59 59
      /// Type of the priorities.
60 60
      typedef PR Prio;
61 61
      /// Type of the items stored in the heap.
62 62
      typedef typename ItemIntMap::Key Item;
63 63

	
64 64
      /// \brief Type to represent the states of the items.
65 65
      ///
66 66
      /// Each item has a state associated to it. It can be "in heap",
67 67
      /// "pre heap" or "post heap". The later two are indifferent
68 68
      /// from the point of view of the heap, but may be useful for
69 69
      /// the user.
70 70
      ///
71 71
      /// The item-int map must be initialized in such way that it assigns
72 72
      /// \c PRE_HEAP (<tt>-1</tt>) to any element to be put in the heap.
73 73
      enum State {
74
        IN_HEAP = 0,    ///< The "in heap" state constant.
75
        PRE_HEAP = -1,  ///< The "pre heap" state constant.
76
        POST_HEAP = -2  ///< The "post heap" state constant.
74
        IN_HEAP = 0,    ///< = 0. The "in heap" state constant.
75
        PRE_HEAP = -1,  ///< = -1. The "pre heap" state constant.
76
        POST_HEAP = -2  ///< = -2. The "post heap" state constant.
77 77
      };
78 78

	
79 79
      /// \brief The constructor.
80 80
      ///
81 81
      /// The constructor.
82 82
      /// \param map A map that assigns \c int values to keys of type
83 83
      /// \c Item. It is used internally by the heap implementations to
84 84
      /// handle the cross references. The assigned value must be
85 85
      /// \c PRE_HEAP (<tt>-1</tt>) for every item.
86 86
      explicit Heap(ItemIntMap &map) {}
87 87

	
88 88
      /// \brief The number of items stored in the heap.
89 89
      ///
90 90
      /// Returns the number of items stored in the heap.
91 91
      int size() const { return 0; }
92 92

	
93 93
      /// \brief Checks if the heap is empty.
94 94
      ///
95 95
      /// Returns \c true if the heap is empty.
96 96
      bool empty() const { return false; }
97 97

	
98 98
      /// \brief Makes the heap empty.
99 99
      ///
100 100
      /// Makes the heap empty.
101 101
      void clear();
102 102

	
103 103
      /// \brief Inserts an item into the heap with the given priority.
104 104
      ///
105 105
      /// Inserts the given item into the heap with the given priority.
106 106
      /// \param i The item to insert.
107 107
      /// \param p The priority of the item.
108 108
      void push(const Item &i, const Prio &p) {}
109 109

	
110 110
      /// \brief Returns the item having minimum priority.
111 111
      ///
112 112
      /// Returns the item having minimum priority.
113 113
      /// \pre The heap must be non-empty.
114 114
      Item top() const {}
115 115

	
116 116
      /// \brief The minimum priority.
117 117
      ///
118 118
      /// Returns the minimum priority.
119 119
      /// \pre The heap must be non-empty.
120 120
      Prio prio() const {}
121 121

	
122 122
      /// \brief Removes the item having minimum priority.
123 123
      ///
124 124
      /// Removes the item having minimum priority.
125 125
      /// \pre The heap must be non-empty.
126 126
      void pop() {}
127 127

	
128 128
      /// \brief Removes an item from the heap.
129 129
      ///
130 130
      /// Removes the given item from the heap if it is already stored.
131 131
      /// \param i The item to delete.
132 132
      void erase(const Item &i) {}
133 133

	
134 134
      /// \brief The priority of an item.
135 135
      ///
136 136
      /// Returns the priority of the given item.
137 137
      /// \param i The item.
138 138
      /// \pre \c i must be in the heap.
139 139
      Prio operator[](const Item &i) const {}
140 140

	
141 141
      /// \brief Sets the priority of an item or inserts it, if it is
142 142
      /// not stored in the heap.
143 143
      ///
144 144
      /// This method sets the priority of the given item if it is
145 145
      /// already stored in the heap.
146 146
      /// Otherwise it inserts the given item with the given priority.
147 147
      ///
148 148
      /// \param i The item.
149 149
      /// \param p The priority.
150 150
      void set(const Item &i, const Prio &p) {}
151 151

	
152 152
      /// \brief Decreases the priority of an item to the given value.
153 153
      ///
154 154
      /// Decreases the priority of an item to the given value.
155 155
      /// \param i The item.
156 156
      /// \param p The priority.
157 157
      /// \pre \c i must be stored in the heap with priority at least \c p.
158 158
      void decrease(const Item &i, const Prio &p) {}
159 159

	
160 160
      /// \brief Increases the priority of an item to the given value.
161 161
      ///
162 162
      /// Increases the priority of an item to the given value.
163 163
      /// \param i The item.
164 164
      /// \param p The priority.
165 165
      /// \pre \c i must be stored in the heap with priority at most \c p.
166 166
      void increase(const Item &i, const Prio &p) {}
167 167

	
168 168
      /// \brief Returns if an item is in, has already been in, or has
169 169
      /// never been in the heap.
170 170
      ///
171 171
      /// This method returns \c PRE_HEAP if the given item has never
172 172
      /// been in the heap, \c IN_HEAP if it is in the heap at the moment,
173 173
      /// and \c POST_HEAP otherwise.
174 174
      /// In the latter case it is possible that the item will get back
175 175
      /// to the heap again.
176 176
      /// \param i The item.
177 177
      State state(const Item &i) const {}
178 178

	
179 179
      /// \brief Sets the state of an item in the heap.
180 180
      ///
181 181
      /// Sets the state of the given item in the heap. It can be used
182 182
      /// to manually clear the heap when it is important to achive the
183 183
      /// better time complexity.
184 184
      /// \param i The item.
185 185
      /// \param st The state. It should not be \c IN_HEAP.
186 186
      void state(const Item& i, State st) {}
187 187

	
188 188

	
189 189
      template <typename _Heap>
190 190
      struct Constraints {
191 191
      public:
192 192
        void constraints() {
193 193
          typedef typename _Heap::Item OwnItem;
194 194
          typedef typename _Heap::Prio OwnPrio;
195 195
          typedef typename _Heap::State OwnState;
196 196

	
197 197
          Item item;
198 198
          Prio prio;
199 199
          item=Item();
200 200
          prio=Prio();
201 201
          ignore_unused_variable_warning(item);
202 202
          ignore_unused_variable_warning(prio);
203 203

	
204 204
          OwnItem own_item;
205 205
          OwnPrio own_prio;
206 206
          OwnState own_state;
207 207
          own_item=Item();
208 208
          own_prio=Prio();
209 209
          ignore_unused_variable_warning(own_item);
210 210
          ignore_unused_variable_warning(own_prio);
211 211
          ignore_unused_variable_warning(own_state);
212 212

	
213 213
          _Heap heap1(map);
214 214
          _Heap heap2 = heap1;
215 215
          ignore_unused_variable_warning(heap1);
216 216
          ignore_unused_variable_warning(heap2);
217 217

	
218 218
          int s = heap.size();
219 219
          ignore_unused_variable_warning(s);
220 220
          bool e = heap.empty();
221 221
          ignore_unused_variable_warning(e);
222 222

	
223 223
          prio = heap.prio();
224 224
          item = heap.top();
225 225
          prio = heap[item];
226 226
          own_prio = heap.prio();
227 227
          own_item = heap.top();
228 228
          own_prio = heap[own_item];
229 229

	
230 230
          heap.push(item, prio);
231 231
          heap.push(own_item, own_prio);
232 232
          heap.pop();
233 233

	
234 234
          heap.set(item, prio);
235 235
          heap.decrease(item, prio);
236 236
          heap.increase(item, prio);
237 237
          heap.set(own_item, own_prio);
238 238
          heap.decrease(own_item, own_prio);
239 239
          heap.increase(own_item, own_prio);
240 240

	
241 241
          heap.erase(item);
242 242
          heap.erase(own_item);
243 243
          heap.clear();
244 244

	
245 245
          own_state = heap.state(own_item);
246 246
          heap.state(own_item, own_state);
247 247

	
248 248
          own_state = _Heap::PRE_HEAP;
249 249
          own_state = _Heap::IN_HEAP;
250 250
          own_state = _Heap::POST_HEAP;
251 251
        }
252 252

	
253 253
        _Heap& heap;
254 254
        ItemIntMap& map;
255 255
      };
256 256
    };
257 257

	
258 258
    /// @}
259 259
  } // namespace lemon
260 260
}
261 261
#endif
Ignore white space 384 line context
... ...
@@ -17,385 +17,385 @@
17 17
 */
18 18

	
19 19
#ifndef LEMON_DFS_H
20 20
#define LEMON_DFS_H
21 21

	
22 22
///\ingroup search
23 23
///\file
24 24
///\brief DFS algorithm.
25 25

	
26 26
#include <lemon/list_graph.h>
27 27
#include <lemon/bits/path_dump.h>
28 28
#include <lemon/core.h>
29 29
#include <lemon/error.h>
30 30
#include <lemon/maps.h>
31 31
#include <lemon/path.h>
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  ///Default traits class of Dfs class.
36 36

	
37 37
  ///Default traits class of Dfs class.
38 38
  ///\tparam GR Digraph type.
39 39
  template<class GR>
40 40
  struct DfsDefaultTraits
41 41
  {
42 42
    ///The type of the digraph the algorithm runs on.
43 43
    typedef GR Digraph;
44 44

	
45 45
    ///\brief The type of the map that stores the predecessor
46 46
    ///arcs of the %DFS paths.
47 47
    ///
48 48
    ///The type of the map that stores the predecessor
49 49
    ///arcs of the %DFS paths.
50 50
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
51 51
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
52 52
    ///Instantiates a \c PredMap.
53 53

	
54 54
    ///This function instantiates a \ref PredMap.
55 55
    ///\param g is the digraph, to which we would like to define the
56 56
    ///\ref PredMap.
57 57
    static PredMap *createPredMap(const Digraph &g)
58 58
    {
59 59
      return new PredMap(g);
60 60
    }
61 61

	
62 62
    ///The type of the map that indicates which nodes are processed.
63 63

	
64 64
    ///The type of the map that indicates which nodes are processed.
65 65
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
66 66
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
67 67
    ///Instantiates a \c ProcessedMap.
68 68

	
69 69
    ///This function instantiates a \ref ProcessedMap.
70 70
    ///\param g is the digraph, to which
71 71
    ///we would like to define the \ref ProcessedMap.
72 72
#ifdef DOXYGEN
73 73
    static ProcessedMap *createProcessedMap(const Digraph &g)
74 74
#else
75 75
    static ProcessedMap *createProcessedMap(const Digraph &)
76 76
#endif
77 77
    {
78 78
      return new ProcessedMap();
79 79
    }
80 80

	
81 81
    ///The type of the map that indicates which nodes are reached.
82 82

	
83 83
    ///The type of the map that indicates which nodes are reached.
84 84
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
85 85
    typedef typename Digraph::template NodeMap<bool> ReachedMap;
86 86
    ///Instantiates a \c ReachedMap.
87 87

	
88 88
    ///This function instantiates a \ref ReachedMap.
89 89
    ///\param g is the digraph, to which
90 90
    ///we would like to define the \ref ReachedMap.
91 91
    static ReachedMap *createReachedMap(const Digraph &g)
92 92
    {
93 93
      return new ReachedMap(g);
94 94
    }
95 95

	
96 96
    ///The type of the map that stores the distances of the nodes.
97 97

	
98 98
    ///The type of the map that stores the distances of the nodes.
99 99
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
100 100
    typedef typename Digraph::template NodeMap<int> DistMap;
101 101
    ///Instantiates a \c DistMap.
102 102

	
103 103
    ///This function instantiates a \ref DistMap.
104 104
    ///\param g is the digraph, to which we would like to define the
105 105
    ///\ref DistMap.
106 106
    static DistMap *createDistMap(const Digraph &g)
107 107
    {
108 108
      return new DistMap(g);
109 109
    }
110 110
  };
111 111

	
112 112
  ///%DFS algorithm class.
113 113

	
114 114
  ///\ingroup search
115 115
  ///This class provides an efficient implementation of the %DFS algorithm.
116 116
  ///
117 117
  ///There is also a \ref dfs() "function-type interface" for the DFS
118 118
  ///algorithm, which is convenient in the simplier cases and it can be
119 119
  ///used easier.
120 120
  ///
121 121
  ///\tparam GR The type of the digraph the algorithm runs on.
122 122
  ///The default type is \ref ListDigraph.
123 123
#ifdef DOXYGEN
124 124
  template <typename GR,
125 125
            typename TR>
126 126
#else
127 127
  template <typename GR=ListDigraph,
128 128
            typename TR=DfsDefaultTraits<GR> >
129 129
#endif
130 130
  class Dfs {
131 131
  public:
132 132

	
133 133
    ///The type of the digraph the algorithm runs on.
134 134
    typedef typename TR::Digraph Digraph;
135 135

	
136 136
    ///\brief The type of the map that stores the predecessor arcs of the
137 137
    ///DFS paths.
138 138
    typedef typename TR::PredMap PredMap;
139 139
    ///The type of the map that stores the distances of the nodes.
140 140
    typedef typename TR::DistMap DistMap;
141 141
    ///The type of the map that indicates which nodes are reached.
142 142
    typedef typename TR::ReachedMap ReachedMap;
143 143
    ///The type of the map that indicates which nodes are processed.
144 144
    typedef typename TR::ProcessedMap ProcessedMap;
145 145
    ///The type of the paths.
146 146
    typedef PredMapPath<Digraph, PredMap> Path;
147 147

	
148 148
    ///The \ref DfsDefaultTraits "traits class" of the algorithm.
149 149
    typedef TR Traits;
150 150

	
151 151
  private:
152 152

	
153 153
    typedef typename Digraph::Node Node;
154 154
    typedef typename Digraph::NodeIt NodeIt;
155 155
    typedef typename Digraph::Arc Arc;
156 156
    typedef typename Digraph::OutArcIt OutArcIt;
157 157

	
158 158
    //Pointer to the underlying digraph.
159 159
    const Digraph *G;
160 160
    //Pointer to the map of predecessor arcs.
161 161
    PredMap *_pred;
162 162
    //Indicates if _pred is locally allocated (true) or not.
163 163
    bool local_pred;
164 164
    //Pointer to the map of distances.
165 165
    DistMap *_dist;
166 166
    //Indicates if _dist is locally allocated (true) or not.
167 167
    bool local_dist;
168 168
    //Pointer to the map of reached status of the nodes.
169 169
    ReachedMap *_reached;
170 170
    //Indicates if _reached is locally allocated (true) or not.
171 171
    bool local_reached;
172 172
    //Pointer to the map of processed status of the nodes.
173 173
    ProcessedMap *_processed;
174 174
    //Indicates if _processed is locally allocated (true) or not.
175 175
    bool local_processed;
176 176

	
177 177
    std::vector<typename Digraph::OutArcIt> _stack;
178 178
    int _stack_head;
179 179

	
180 180
    //Creates the maps if necessary.
181 181
    void create_maps()
182 182
    {
183 183
      if(!_pred) {
184 184
        local_pred = true;
185 185
        _pred = Traits::createPredMap(*G);
186 186
      }
187 187
      if(!_dist) {
188 188
        local_dist = true;
189 189
        _dist = Traits::createDistMap(*G);
190 190
      }
191 191
      if(!_reached) {
192 192
        local_reached = true;
193 193
        _reached = Traits::createReachedMap(*G);
194 194
      }
195 195
      if(!_processed) {
196 196
        local_processed = true;
197 197
        _processed = Traits::createProcessedMap(*G);
198 198
      }
199 199
    }
200 200

	
201 201
  protected:
202 202

	
203 203
    Dfs() {}
204 204

	
205 205
  public:
206 206

	
207 207
    typedef Dfs Create;
208 208

	
209
    ///\name Named template parameters
209
    ///\name Named Template Parameters
210 210

	
211 211
    ///@{
212 212

	
213 213
    template <class T>
214 214
    struct SetPredMapTraits : public Traits {
215 215
      typedef T PredMap;
216 216
      static PredMap *createPredMap(const Digraph &)
217 217
      {
218 218
        LEMON_ASSERT(false, "PredMap is not initialized");
219 219
        return 0; // ignore warnings
220 220
      }
221 221
    };
222 222
    ///\brief \ref named-templ-param "Named parameter" for setting
223 223
    ///\c PredMap type.
224 224
    ///
225 225
    ///\ref named-templ-param "Named parameter" for setting
226 226
    ///\c PredMap type.
227 227
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
228 228
    template <class T>
229 229
    struct SetPredMap : public Dfs<Digraph, SetPredMapTraits<T> > {
230 230
      typedef Dfs<Digraph, SetPredMapTraits<T> > Create;
231 231
    };
232 232

	
233 233
    template <class T>
234 234
    struct SetDistMapTraits : public Traits {
235 235
      typedef T DistMap;
236 236
      static DistMap *createDistMap(const Digraph &)
237 237
      {
238 238
        LEMON_ASSERT(false, "DistMap is not initialized");
239 239
        return 0; // ignore warnings
240 240
      }
241 241
    };
242 242
    ///\brief \ref named-templ-param "Named parameter" for setting
243 243
    ///\c DistMap type.
244 244
    ///
245 245
    ///\ref named-templ-param "Named parameter" for setting
246 246
    ///\c DistMap type.
247 247
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
248 248
    template <class T>
249 249
    struct SetDistMap : public Dfs< Digraph, SetDistMapTraits<T> > {
250 250
      typedef Dfs<Digraph, SetDistMapTraits<T> > Create;
251 251
    };
252 252

	
253 253
    template <class T>
254 254
    struct SetReachedMapTraits : public Traits {
255 255
      typedef T ReachedMap;
256 256
      static ReachedMap *createReachedMap(const Digraph &)
257 257
      {
258 258
        LEMON_ASSERT(false, "ReachedMap is not initialized");
259 259
        return 0; // ignore warnings
260 260
      }
261 261
    };
262 262
    ///\brief \ref named-templ-param "Named parameter" for setting
263 263
    ///\c ReachedMap type.
264 264
    ///
265 265
    ///\ref named-templ-param "Named parameter" for setting
266 266
    ///\c ReachedMap type.
267 267
    ///It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
268 268
    template <class T>
269 269
    struct SetReachedMap : public Dfs< Digraph, SetReachedMapTraits<T> > {
270 270
      typedef Dfs< Digraph, SetReachedMapTraits<T> > Create;
271 271
    };
272 272

	
273 273
    template <class T>
274 274
    struct SetProcessedMapTraits : public Traits {
275 275
      typedef T ProcessedMap;
276 276
      static ProcessedMap *createProcessedMap(const Digraph &)
277 277
      {
278 278
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
279 279
        return 0; // ignore warnings
280 280
      }
281 281
    };
282 282
    ///\brief \ref named-templ-param "Named parameter" for setting
283 283
    ///\c ProcessedMap type.
284 284
    ///
285 285
    ///\ref named-templ-param "Named parameter" for setting
286 286
    ///\c ProcessedMap type.
287 287
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
288 288
    template <class T>
289 289
    struct SetProcessedMap : public Dfs< Digraph, SetProcessedMapTraits<T> > {
290 290
      typedef Dfs< Digraph, SetProcessedMapTraits<T> > Create;
291 291
    };
292 292

	
293 293
    struct SetStandardProcessedMapTraits : public Traits {
294 294
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
295 295
      static ProcessedMap *createProcessedMap(const Digraph &g)
296 296
      {
297 297
        return new ProcessedMap(g);
298 298
      }
299 299
    };
300 300
    ///\brief \ref named-templ-param "Named parameter" for setting
301 301
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
302 302
    ///
303 303
    ///\ref named-templ-param "Named parameter" for setting
304 304
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
305 305
    ///If you don't set it explicitly, it will be automatically allocated.
306 306
    struct SetStandardProcessedMap :
307 307
      public Dfs< Digraph, SetStandardProcessedMapTraits > {
308 308
      typedef Dfs< Digraph, SetStandardProcessedMapTraits > Create;
309 309
    };
310 310

	
311 311
    ///@}
312 312

	
313 313
  public:
314 314

	
315 315
    ///Constructor.
316 316

	
317 317
    ///Constructor.
318 318
    ///\param g The digraph the algorithm runs on.
319 319
    Dfs(const Digraph &g) :
320 320
      G(&g),
321 321
      _pred(NULL), local_pred(false),
322 322
      _dist(NULL), local_dist(false),
323 323
      _reached(NULL), local_reached(false),
324 324
      _processed(NULL), local_processed(false)
325 325
    { }
326 326

	
327 327
    ///Destructor.
328 328
    ~Dfs()
329 329
    {
330 330
      if(local_pred) delete _pred;
331 331
      if(local_dist) delete _dist;
332 332
      if(local_reached) delete _reached;
333 333
      if(local_processed) delete _processed;
334 334
    }
335 335

	
336 336
    ///Sets the map that stores the predecessor arcs.
337 337

	
338 338
    ///Sets the map that stores the predecessor arcs.
339 339
    ///If you don't use this function before calling \ref run(Node) "run()"
340 340
    ///or \ref init(), an instance will be allocated automatically.
341 341
    ///The destructor deallocates this automatically allocated map,
342 342
    ///of course.
343 343
    ///\return <tt> (*this) </tt>
344 344
    Dfs &predMap(PredMap &m)
345 345
    {
346 346
      if(local_pred) {
347 347
        delete _pred;
348 348
        local_pred=false;
349 349
      }
350 350
      _pred = &m;
351 351
      return *this;
352 352
    }
353 353

	
354 354
    ///Sets the map that indicates which nodes are reached.
355 355

	
356 356
    ///Sets the map that indicates which nodes are reached.
357 357
    ///If you don't use this function before calling \ref run(Node) "run()"
358 358
    ///or \ref init(), an instance will be allocated automatically.
359 359
    ///The destructor deallocates this automatically allocated map,
360 360
    ///of course.
361 361
    ///\return <tt> (*this) </tt>
362 362
    Dfs &reachedMap(ReachedMap &m)
363 363
    {
364 364
      if(local_reached) {
365 365
        delete _reached;
366 366
        local_reached=false;
367 367
      }
368 368
      _reached = &m;
369 369
      return *this;
370 370
    }
371 371

	
372 372
    ///Sets the map that indicates which nodes are processed.
373 373

	
374 374
    ///Sets the map that indicates which nodes are processed.
375 375
    ///If you don't use this function before calling \ref run(Node) "run()"
376 376
    ///or \ref init(), an instance will be allocated automatically.
377 377
    ///The destructor deallocates this automatically allocated map,
378 378
    ///of course.
379 379
    ///\return <tt> (*this) </tt>
380 380
    Dfs &processedMap(ProcessedMap &m)
381 381
    {
382 382
      if(local_processed) {
383 383
        delete _processed;
384 384
        local_processed=false;
385 385
      }
386 386
      _processed = &m;
387 387
      return *this;
388 388
    }
389 389

	
390 390
    ///Sets the map that stores the distances of the nodes.
391 391

	
392 392
    ///Sets the map that stores the distances of the nodes calculated by
393 393
    ///the algorithm.
394 394
    ///If you don't use this function before calling \ref run(Node) "run()"
395 395
    ///or \ref init(), an instance will be allocated automatically.
396 396
    ///The destructor deallocates this automatically allocated map,
397 397
    ///of course.
398 398
    ///\return <tt> (*this) </tt>
399 399
    Dfs &distMap(DistMap &m)
400 400
    {
401 401
      if(local_dist) {
Ignore white space 384 line context
... ...
@@ -97,385 +97,385 @@
97 97
    }
98 98

	
99 99
    ///The heap type used by the %Dijkstra algorithm.
100 100

	
101 101
    ///The heap type used by the Dijkstra algorithm.
102 102
    ///
103 103
    ///\sa BinHeap
104 104
    ///\sa Dijkstra
105 105
    typedef BinHeap<typename LEN::Value, HeapCrossRef, std::less<Value> > Heap;
106 106
    ///Instantiates a \c Heap.
107 107

	
108 108
    ///This function instantiates a \ref Heap.
109 109
    static Heap *createHeap(HeapCrossRef& r)
110 110
    {
111 111
      return new Heap(r);
112 112
    }
113 113

	
114 114
    ///\brief The type of the map that stores the predecessor
115 115
    ///arcs of the shortest paths.
116 116
    ///
117 117
    ///The type of the map that stores the predecessor
118 118
    ///arcs of the shortest paths.
119 119
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
120 120
    typedef typename Digraph::template NodeMap<typename Digraph::Arc> PredMap;
121 121
    ///Instantiates a \c PredMap.
122 122

	
123 123
    ///This function instantiates a \ref PredMap.
124 124
    ///\param g is the digraph, to which we would like to define the
125 125
    ///\ref PredMap.
126 126
    static PredMap *createPredMap(const Digraph &g)
127 127
    {
128 128
      return new PredMap(g);
129 129
    }
130 130

	
131 131
    ///The type of the map that indicates which nodes are processed.
132 132

	
133 133
    ///The type of the map that indicates which nodes are processed.
134 134
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
135 135
    ///By default it is a NullMap.
136 136
    typedef NullMap<typename Digraph::Node,bool> ProcessedMap;
137 137
    ///Instantiates a \c ProcessedMap.
138 138

	
139 139
    ///This function instantiates a \ref ProcessedMap.
140 140
    ///\param g is the digraph, to which
141 141
    ///we would like to define the \ref ProcessedMap.
142 142
#ifdef DOXYGEN
143 143
    static ProcessedMap *createProcessedMap(const Digraph &g)
144 144
#else
145 145
    static ProcessedMap *createProcessedMap(const Digraph &)
146 146
#endif
147 147
    {
148 148
      return new ProcessedMap();
149 149
    }
150 150

	
151 151
    ///The type of the map that stores the distances of the nodes.
152 152

	
153 153
    ///The type of the map that stores the distances of the nodes.
154 154
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
155 155
    typedef typename Digraph::template NodeMap<typename LEN::Value> DistMap;
156 156
    ///Instantiates a \c DistMap.
157 157

	
158 158
    ///This function instantiates a \ref DistMap.
159 159
    ///\param g is the digraph, to which we would like to define
160 160
    ///the \ref DistMap.
161 161
    static DistMap *createDistMap(const Digraph &g)
162 162
    {
163 163
      return new DistMap(g);
164 164
    }
165 165
  };
166 166

	
167 167
  ///%Dijkstra algorithm class.
168 168

	
169 169
  /// \ingroup shortest_path
170 170
  ///This class provides an efficient implementation of the %Dijkstra algorithm.
171 171
  ///
172 172
  ///The arc lengths are passed to the algorithm using a
173 173
  ///\ref concepts::ReadMap "ReadMap",
174 174
  ///so it is easy to change it to any kind of length.
175 175
  ///The type of the length is determined by the
176 176
  ///\ref concepts::ReadMap::Value "Value" of the length map.
177 177
  ///It is also possible to change the underlying priority heap.
178 178
  ///
179 179
  ///There is also a \ref dijkstra() "function-type interface" for the
180 180
  ///%Dijkstra algorithm, which is convenient in the simplier cases and
181 181
  ///it can be used easier.
182 182
  ///
183 183
  ///\tparam GR The type of the digraph the algorithm runs on.
184 184
  ///The default type is \ref ListDigraph.
185 185
  ///\tparam LEN A \ref concepts::ReadMap "readable" arc map that specifies
186 186
  ///the lengths of the arcs.
187 187
  ///It is read once for each arc, so the map may involve in
188 188
  ///relatively time consuming process to compute the arc lengths if
189 189
  ///it is necessary. The default map type is \ref
190 190
  ///concepts::Digraph::ArcMap "GR::ArcMap<int>".
191 191
#ifdef DOXYGEN
192 192
  template <typename GR, typename LEN, typename TR>
193 193
#else
194 194
  template <typename GR=ListDigraph,
195 195
            typename LEN=typename GR::template ArcMap<int>,
196 196
            typename TR=DijkstraDefaultTraits<GR,LEN> >
197 197
#endif
198 198
  class Dijkstra {
199 199
  public:
200 200

	
201 201
    ///The type of the digraph the algorithm runs on.
202 202
    typedef typename TR::Digraph Digraph;
203 203

	
204 204
    ///The type of the length of the arcs.
205 205
    typedef typename TR::LengthMap::Value Value;
206 206
    ///The type of the map that stores the arc lengths.
207 207
    typedef typename TR::LengthMap LengthMap;
208 208
    ///\brief The type of the map that stores the predecessor arcs of the
209 209
    ///shortest paths.
210 210
    typedef typename TR::PredMap PredMap;
211 211
    ///The type of the map that stores the distances of the nodes.
212 212
    typedef typename TR::DistMap DistMap;
213 213
    ///The type of the map that indicates which nodes are processed.
214 214
    typedef typename TR::ProcessedMap ProcessedMap;
215 215
    ///The type of the paths.
216 216
    typedef PredMapPath<Digraph, PredMap> Path;
217 217
    ///The cross reference type used for the current heap.
218 218
    typedef typename TR::HeapCrossRef HeapCrossRef;
219 219
    ///The heap type used by the algorithm.
220 220
    typedef typename TR::Heap Heap;
221 221
    ///\brief The \ref DijkstraDefaultOperationTraits "operation traits class"
222 222
    ///of the algorithm.
223 223
    typedef typename TR::OperationTraits OperationTraits;
224 224

	
225 225
    ///The \ref DijkstraDefaultTraits "traits class" of the algorithm.
226 226
    typedef TR Traits;
227 227

	
228 228
  private:
229 229

	
230 230
    typedef typename Digraph::Node Node;
231 231
    typedef typename Digraph::NodeIt NodeIt;
232 232
    typedef typename Digraph::Arc Arc;
233 233
    typedef typename Digraph::OutArcIt OutArcIt;
234 234

	
235 235
    //Pointer to the underlying digraph.
236 236
    const Digraph *G;
237 237
    //Pointer to the length map.
238 238
    const LengthMap *_length;
239 239
    //Pointer to the map of predecessors arcs.
240 240
    PredMap *_pred;
241 241
    //Indicates if _pred is locally allocated (true) or not.
242 242
    bool local_pred;
243 243
    //Pointer to the map of distances.
244 244
    DistMap *_dist;
245 245
    //Indicates if _dist is locally allocated (true) or not.
246 246
    bool local_dist;
247 247
    //Pointer to the map of processed status of the nodes.
248 248
    ProcessedMap *_processed;
249 249
    //Indicates if _processed is locally allocated (true) or not.
250 250
    bool local_processed;
251 251
    //Pointer to the heap cross references.
252 252
    HeapCrossRef *_heap_cross_ref;
253 253
    //Indicates if _heap_cross_ref is locally allocated (true) or not.
254 254
    bool local_heap_cross_ref;
255 255
    //Pointer to the heap.
256 256
    Heap *_heap;
257 257
    //Indicates if _heap is locally allocated (true) or not.
258 258
    bool local_heap;
259 259

	
260 260
    //Creates the maps if necessary.
261 261
    void create_maps()
262 262
    {
263 263
      if(!_pred) {
264 264
        local_pred = true;
265 265
        _pred = Traits::createPredMap(*G);
266 266
      }
267 267
      if(!_dist) {
268 268
        local_dist = true;
269 269
        _dist = Traits::createDistMap(*G);
270 270
      }
271 271
      if(!_processed) {
272 272
        local_processed = true;
273 273
        _processed = Traits::createProcessedMap(*G);
274 274
      }
275 275
      if (!_heap_cross_ref) {
276 276
        local_heap_cross_ref = true;
277 277
        _heap_cross_ref = Traits::createHeapCrossRef(*G);
278 278
      }
279 279
      if (!_heap) {
280 280
        local_heap = true;
281 281
        _heap = Traits::createHeap(*_heap_cross_ref);
282 282
      }
283 283
    }
284 284

	
285 285
  public:
286 286

	
287 287
    typedef Dijkstra Create;
288 288

	
289
    ///\name Named template parameters
289
    ///\name Named Template Parameters
290 290

	
291 291
    ///@{
292 292

	
293 293
    template <class T>
294 294
    struct SetPredMapTraits : public Traits {
295 295
      typedef T PredMap;
296 296
      static PredMap *createPredMap(const Digraph &)
297 297
      {
298 298
        LEMON_ASSERT(false, "PredMap is not initialized");
299 299
        return 0; // ignore warnings
300 300
      }
301 301
    };
302 302
    ///\brief \ref named-templ-param "Named parameter" for setting
303 303
    ///\c PredMap type.
304 304
    ///
305 305
    ///\ref named-templ-param "Named parameter" for setting
306 306
    ///\c PredMap type.
307 307
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
308 308
    template <class T>
309 309
    struct SetPredMap
310 310
      : public Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > {
311 311
      typedef Dijkstra< Digraph, LengthMap, SetPredMapTraits<T> > Create;
312 312
    };
313 313

	
314 314
    template <class T>
315 315
    struct SetDistMapTraits : public Traits {
316 316
      typedef T DistMap;
317 317
      static DistMap *createDistMap(const Digraph &)
318 318
      {
319 319
        LEMON_ASSERT(false, "DistMap is not initialized");
320 320
        return 0; // ignore warnings
321 321
      }
322 322
    };
323 323
    ///\brief \ref named-templ-param "Named parameter" for setting
324 324
    ///\c DistMap type.
325 325
    ///
326 326
    ///\ref named-templ-param "Named parameter" for setting
327 327
    ///\c DistMap type.
328 328
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
329 329
    template <class T>
330 330
    struct SetDistMap
331 331
      : public Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > {
332 332
      typedef Dijkstra< Digraph, LengthMap, SetDistMapTraits<T> > Create;
333 333
    };
334 334

	
335 335
    template <class T>
336 336
    struct SetProcessedMapTraits : public Traits {
337 337
      typedef T ProcessedMap;
338 338
      static ProcessedMap *createProcessedMap(const Digraph &)
339 339
      {
340 340
        LEMON_ASSERT(false, "ProcessedMap is not initialized");
341 341
        return 0; // ignore warnings
342 342
      }
343 343
    };
344 344
    ///\brief \ref named-templ-param "Named parameter" for setting
345 345
    ///\c ProcessedMap type.
346 346
    ///
347 347
    ///\ref named-templ-param "Named parameter" for setting
348 348
    ///\c ProcessedMap type.
349 349
    ///It must meet the \ref concepts::WriteMap "WriteMap" concept.
350 350
    template <class T>
351 351
    struct SetProcessedMap
352 352
      : public Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > {
353 353
      typedef Dijkstra< Digraph, LengthMap, SetProcessedMapTraits<T> > Create;
354 354
    };
355 355

	
356 356
    struct SetStandardProcessedMapTraits : public Traits {
357 357
      typedef typename Digraph::template NodeMap<bool> ProcessedMap;
358 358
      static ProcessedMap *createProcessedMap(const Digraph &g)
359 359
      {
360 360
        return new ProcessedMap(g);
361 361
      }
362 362
    };
363 363
    ///\brief \ref named-templ-param "Named parameter" for setting
364 364
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
365 365
    ///
366 366
    ///\ref named-templ-param "Named parameter" for setting
367 367
    ///\c ProcessedMap type to be <tt>Digraph::NodeMap<bool></tt>.
368 368
    ///If you don't set it explicitly, it will be automatically allocated.
369 369
    struct SetStandardProcessedMap
370 370
      : public Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits > {
371 371
      typedef Dijkstra< Digraph, LengthMap, SetStandardProcessedMapTraits >
372 372
      Create;
373 373
    };
374 374

	
375 375
    template <class H, class CR>
376 376
    struct SetHeapTraits : public Traits {
377 377
      typedef CR HeapCrossRef;
378 378
      typedef H Heap;
379 379
      static HeapCrossRef *createHeapCrossRef(const Digraph &) {
380 380
        LEMON_ASSERT(false, "HeapCrossRef is not initialized");
381 381
        return 0; // ignore warnings
382 382
      }
383 383
      static Heap *createHeap(HeapCrossRef &)
384 384
      {
385 385
        LEMON_ASSERT(false, "Heap is not initialized");
386 386
        return 0; // ignore warnings
387 387
      }
388 388
    };
389 389
    ///\brief \ref named-templ-param "Named parameter" for setting
390 390
    ///heap and cross reference types
391 391
    ///
392 392
    ///\ref named-templ-param "Named parameter" for setting heap and cross
393 393
    ///reference types. If this named parameter is used, then external
394 394
    ///heap and cross reference objects must be passed to the algorithm
395 395
    ///using the \ref heap() function before calling \ref run(Node) "run()"
396 396
    ///or \ref init().
397 397
    ///\sa SetStandardHeap
398 398
    template <class H, class CR = typename Digraph::template NodeMap<int> >
399 399
    struct SetHeap
400 400
      : public Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > {
401 401
      typedef Dijkstra< Digraph, LengthMap, SetHeapTraits<H, CR> > Create;
402 402
    };
403 403

	
404 404
    template <class H, class CR>
405 405
    struct SetStandardHeapTraits : public Traits {
406 406
      typedef CR HeapCrossRef;
407 407
      typedef H Heap;
408 408
      static HeapCrossRef *createHeapCrossRef(const Digraph &G) {
409 409
        return new HeapCrossRef(G);
410 410
      }
411 411
      static Heap *createHeap(HeapCrossRef &R)
412 412
      {
413 413
        return new Heap(R);
414 414
      }
415 415
    };
416 416
    ///\brief \ref named-templ-param "Named parameter" for setting
417 417
    ///heap and cross reference types with automatic allocation
418 418
    ///
419 419
    ///\ref named-templ-param "Named parameter" for setting heap and cross
420 420
    ///reference types with automatic allocation.
421 421
    ///They should have standard constructor interfaces to be able to
422 422
    ///automatically created by the algorithm (i.e. the digraph should be
423 423
    ///passed to the constructor of the cross reference and the cross
424 424
    ///reference should be passed to the constructor of the heap).
425 425
    ///However external heap and cross reference objects could also be
426 426
    ///passed to the algorithm using the \ref heap() function before
427 427
    ///calling \ref run(Node) "run()" or \ref init().
428 428
    ///\sa SetHeap
429 429
    template <class H, class CR = typename Digraph::template NodeMap<int> >
430 430
    struct SetStandardHeap
431 431
      : public Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> > {
432 432
      typedef Dijkstra< Digraph, LengthMap, SetStandardHeapTraits<H, CR> >
433 433
      Create;
434 434
    };
435 435

	
436 436
    template <class T>
437 437
    struct SetOperationTraitsTraits : public Traits {
438 438
      typedef T OperationTraits;
439 439
    };
440 440

	
441 441
    /// \brief \ref named-templ-param "Named parameter" for setting
442 442
    ///\c OperationTraits type
443 443
    ///
444 444
    ///\ref named-templ-param "Named parameter" for setting
445 445
    ///\c OperationTraits type.
446 446
    template <class T>
447 447
    struct SetOperationTraits
448 448
      : public Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> > {
449 449
      typedef Dijkstra<Digraph, LengthMap, SetOperationTraitsTraits<T> >
450 450
      Create;
451 451
    };
452 452

	
453 453
    ///@}
454 454

	
455 455
  protected:
456 456

	
457 457
    Dijkstra() {}
458 458

	
459 459
  public:
460 460

	
461 461
    ///Constructor.
462 462

	
463 463
    ///Constructor.
464 464
    ///\param g The digraph the algorithm runs on.
465 465
    ///\param length The length map used by the algorithm.
466 466
    Dijkstra(const Digraph& g, const LengthMap& length) :
467 467
      G(&g), _length(&length),
468 468
      _pred(NULL), local_pred(false),
469 469
      _dist(NULL), local_dist(false),
470 470
      _processed(NULL), local_processed(false),
471 471
      _heap_cross_ref(NULL), local_heap_cross_ref(false),
472 472
      _heap(NULL), local_heap(false)
473 473
    { }
474 474

	
475 475
    ///Destructor.
476 476
    ~Dijkstra()
477 477
    {
478 478
      if(local_pred) delete _pred;
479 479
      if(local_dist) delete _dist;
480 480
      if(local_processed) delete _processed;
481 481
      if(local_heap_cross_ref) delete _heap_cross_ref;
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-2009
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_DIMACS_H
20 20
#define LEMON_DIMACS_H
21 21

	
22 22
#include <iostream>
23 23
#include <string>
24 24
#include <vector>
25 25
#include <limits>
26 26
#include <lemon/maps.h>
27 27
#include <lemon/error.h>
28 28
/// \ingroup dimacs_group
29 29
/// \file
30 30
/// \brief DIMACS file format reader.
31 31

	
32 32
namespace lemon {
33 33

	
34 34
  /// \addtogroup dimacs_group
35 35
  /// @{
36 36

	
37 37
  /// DIMACS file type descriptor.
38 38
  struct DimacsDescriptor
39 39
  {
40
    ///File type enum
41
    enum Type
42
      {
43
        NONE, MIN, MAX, SP, MAT
44
      };
40
    ///\brief DIMACS file type enum
41
    ///
42
    ///DIMACS file type enum.
43
    enum Type {
44
      NONE,  ///< Undefined type.
45
      MIN,   ///< DIMACS file type for minimum cost flow problems.
46
      MAX,   ///< DIMACS file type for maximum flow problems.
47
      SP,    ///< DIMACS file type for shostest path problems.
48
      MAT    ///< DIMACS file type for plain graphs and matching problems.
49
    };
45 50
    ///The file type
46 51
    Type type;
47 52
    ///The number of nodes in the graph
48 53
    int nodeNum;
49 54
    ///The number of edges in the graph
50 55
    int edgeNum;
51 56
    int lineShift;
52
    /// Constructor. Sets the type to NONE.
57
    ///Constructor. It sets the type to \c NONE.
53 58
    DimacsDescriptor() : type(NONE) {}
54 59
  };
55 60

	
56 61
  ///Discover the type of a DIMACS file
57 62

	
58
  ///It starts seeking the beginning of the file for the problem type
59
  ///and size info. The found data is returned in a special struct
60
  ///that can be evaluated and passed to the appropriate reader
61
  ///function.
63
  ///This function starts seeking the beginning of the given file for the
64
  ///problem type and size info. 
65
  ///The found data is returned in a special struct that can be evaluated
66
  ///and passed to the appropriate reader function.
62 67
  DimacsDescriptor dimacsType(std::istream& is)
63 68
  {
64 69
    DimacsDescriptor r;
65 70
    std::string problem,str;
66 71
    char c;
67 72
    r.lineShift=0;
68 73
    while (is >> c)
69 74
      switch(c)
70 75
        {
71 76
        case 'p':
72 77
          if(is >> problem >> r.nodeNum >> r.edgeNum)
73 78
            {
74 79
              getline(is, str);
75 80
              r.lineShift++;
76 81
              if(problem=="min") r.type=DimacsDescriptor::MIN;
77 82
              else if(problem=="max") r.type=DimacsDescriptor::MAX;
78 83
              else if(problem=="sp") r.type=DimacsDescriptor::SP;
79 84
              else if(problem=="mat") r.type=DimacsDescriptor::MAT;
80 85
              else throw FormatError("Unknown problem type");
81 86
              return r;
82 87
            }
83 88
          else
84 89
            {
85 90
              throw FormatError("Missing or wrong problem type declaration.");
86 91
            }
87 92
          break;
88 93
        case 'c':
89 94
          getline(is, str);
90 95
          r.lineShift++;
91 96
          break;
92 97
        default:
93 98
          throw FormatError("Unknown DIMACS declaration.");
94 99
        }
95 100
    throw FormatError("Missing problem type declaration.");
96 101
  }
97 102

	
98 103

	
99

	
100
  /// DIMACS minimum cost flow reader function.
104
  /// \brief DIMACS minimum cost flow reader function.
101 105
  ///
102 106
  /// This function reads a minimum cost flow instance from DIMACS format,
103 107
  /// i.e. from a DIMACS file having a line starting with
104 108
  /// \code
105 109
  ///   p min
106 110
  /// \endcode
107 111
  /// At the beginning, \c g is cleared by \c g.clear(). The supply
108 112
  /// amount of the nodes are written to the \c supply node map
109 113
  /// (they are signed values). The lower bounds, capacities and costs
110 114
  /// of the arcs are written to the \c lower, \c capacity and \c cost
111 115
  /// arc maps.
112 116
  ///
113 117
  /// If the capacity of an arc is less than the lower bound, it will
114 118
  /// be set to "infinite" instead. The actual value of "infinite" is
115 119
  /// contolled by the \c infty parameter. If it is 0 (the default value),
116 120
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
117 121
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
118 122
  /// a non-zero value, that value will be used as "infinite".
119 123
  ///
120 124
  /// If the file type was previously evaluated by dimacsType(), then
121 125
  /// the descriptor struct should be given by the \c dest parameter.
122 126
  template <typename Digraph, typename LowerMap,
123 127
            typename CapacityMap, typename CostMap,
124 128
            typename SupplyMap>
125 129
  void readDimacsMin(std::istream& is,
126 130
                     Digraph &g,
127 131
                     LowerMap& lower,
128 132
                     CapacityMap& capacity,
129 133
                     CostMap& cost,
130 134
                     SupplyMap& supply,
131 135
                     typename CapacityMap::Value infty = 0,
132 136
                     DimacsDescriptor desc=DimacsDescriptor())
133 137
  {
134 138
    g.clear();
135 139
    std::vector<typename Digraph::Node> nodes;
136 140
    typename Digraph::Arc e;
137 141
    std::string problem, str;
138 142
    char c;
139 143
    int i, j;
140 144
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
141 145
    if(desc.type!=DimacsDescriptor::MIN)
142 146
      throw FormatError("Problem type mismatch");
143 147

	
144 148
    nodes.resize(desc.nodeNum + 1);
145 149
    for (int k = 1; k <= desc.nodeNum; ++k) {
146 150
      nodes[k] = g.addNode();
147 151
      supply.set(nodes[k], 0);
148 152
    }
149 153

	
150 154
    typename SupplyMap::Value sup;
151 155
    typename CapacityMap::Value low;
152 156
    typename CapacityMap::Value cap;
153 157
    typename CostMap::Value co;
154 158
    typedef typename CapacityMap::Value Capacity;
155 159
    if(infty==0)
156 160
      infty = std::numeric_limits<Capacity>::has_infinity ?
157 161
        std::numeric_limits<Capacity>::infinity() :
158 162
        std::numeric_limits<Capacity>::max();
159 163

	
160 164
    while (is >> c) {
161 165
      switch (c) {
162 166
      case 'c': // comment line
163 167
        getline(is, str);
164 168
        break;
165 169
      case 'n': // node definition line
166 170
        is >> i >> sup;
167 171
        getline(is, str);
168 172
        supply.set(nodes[i], sup);
169 173
        break;
170 174
      case 'a': // arc definition line
171 175
        is >> i >> j >> low >> cap >> co;
172 176
        getline(is, str);
173 177
        e = g.addArc(nodes[i], nodes[j]);
174 178
        lower.set(e, low);
175 179
        if (cap >= low)
176 180
          capacity.set(e, cap);
177 181
        else
178 182
          capacity.set(e, infty);
179 183
        cost.set(e, co);
180 184
        break;
181 185
      }
182 186
    }
183 187
  }
184 188

	
185 189
  template<typename Digraph, typename CapacityMap>
186 190
  void _readDimacs(std::istream& is,
187 191
                   Digraph &g,
188 192
                   CapacityMap& capacity,
189 193
                   typename Digraph::Node &s,
190 194
                   typename Digraph::Node &t,
191 195
                   typename CapacityMap::Value infty = 0,
192 196
                   DimacsDescriptor desc=DimacsDescriptor()) {
193 197
    g.clear();
194 198
    s=t=INVALID;
195 199
    std::vector<typename Digraph::Node> nodes;
196 200
    typename Digraph::Arc e;
197 201
    char c, d;
198 202
    int i, j;
199 203
    typename CapacityMap::Value _cap;
200 204
    std::string str;
201 205
    nodes.resize(desc.nodeNum + 1);
202 206
    for (int k = 1; k <= desc.nodeNum; ++k) {
203 207
      nodes[k] = g.addNode();
204 208
    }
205 209
    typedef typename CapacityMap::Value Capacity;
206 210

	
207 211
    if(infty==0)
208 212
      infty = std::numeric_limits<Capacity>::has_infinity ?
209 213
        std::numeric_limits<Capacity>::infinity() :
210 214
        std::numeric_limits<Capacity>::max();
211 215
 
212 216
    while (is >> c) {
213 217
      switch (c) {
214 218
      case 'c': // comment line
215 219
        getline(is, str);
216 220
        break;
217 221
      case 'n': // node definition line
218 222
        if (desc.type==DimacsDescriptor::SP) { // shortest path problem
219 223
          is >> i;
220 224
          getline(is, str);
221 225
          s = nodes[i];
222 226
        }
223 227
        if (desc.type==DimacsDescriptor::MAX) { // max flow problem
224 228
          is >> i >> d;
225 229
          getline(is, str);
226 230
          if (d == 's') s = nodes[i];
227 231
          if (d == 't') t = nodes[i];
228 232
        }
229 233
        break;
230 234
      case 'a': // arc definition line
231 235
        if (desc.type==DimacsDescriptor::SP) {
232 236
          is >> i >> j >> _cap;
233 237
          getline(is, str);
234 238
          e = g.addArc(nodes[i], nodes[j]);
235 239
          capacity.set(e, _cap);
236 240
        } 
237 241
        else if (desc.type==DimacsDescriptor::MAX) {
238 242
          is >> i >> j >> _cap;
239 243
          getline(is, str);
240 244
          e = g.addArc(nodes[i], nodes[j]);
241 245
          if (_cap >= 0)
242 246
            capacity.set(e, _cap);
243 247
          else
244 248
            capacity.set(e, infty);
245 249
        }
246 250
        else {
247 251
          is >> i >> j;
248 252
          getline(is, str);
249 253
          g.addArc(nodes[i], nodes[j]);
250 254
        }
251 255
        break;
252 256
      }
253 257
    }
254 258
  }
255 259

	
256
  /// DIMACS maximum flow reader function.
260
  /// \brief DIMACS maximum flow reader function.
257 261
  ///
258 262
  /// This function reads a maximum flow instance from DIMACS format,
259 263
  /// i.e. from a DIMACS file having a line starting with
260 264
  /// \code
261 265
  ///   p max
262 266
  /// \endcode
263 267
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
264 268
  /// capacities are written to the \c capacity arc map and \c s and
265 269
  /// \c t are set to the source and the target nodes.
266 270
  ///
267 271
  /// If the capacity of an arc is negative, it will
268 272
  /// be set to "infinite" instead. The actual value of "infinite" is
269 273
  /// contolled by the \c infty parameter. If it is 0 (the default value),
270 274
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
271 275
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
272 276
  /// a non-zero value, that value will be used as "infinite".
273 277
  ///
274 278
  /// If the file type was previously evaluated by dimacsType(), then
275 279
  /// the descriptor struct should be given by the \c dest parameter.
276 280
  template<typename Digraph, typename CapacityMap>
277 281
  void readDimacsMax(std::istream& is,
278 282
                     Digraph &g,
279 283
                     CapacityMap& capacity,
280 284
                     typename Digraph::Node &s,
281 285
                     typename Digraph::Node &t,
282 286
                     typename CapacityMap::Value infty = 0,
283 287
                     DimacsDescriptor desc=DimacsDescriptor()) {
284 288
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
285 289
    if(desc.type!=DimacsDescriptor::MAX)
286 290
      throw FormatError("Problem type mismatch");
287 291
    _readDimacs(is,g,capacity,s,t,infty,desc);
288 292
  }
289 293

	
290
  /// DIMACS shortest path reader function.
294
  /// \brief DIMACS shortest path reader function.
291 295
  ///
292 296
  /// This function reads a shortest path instance from DIMACS format,
293 297
  /// i.e. from a DIMACS file having a line starting with
294 298
  /// \code
295 299
  ///   p sp
296 300
  /// \endcode
297 301
  /// At the beginning, \c g is cleared by \c g.clear(). The arc
298 302
  /// lengths are written to the \c length arc map and \c s is set to the
299 303
  /// source node.
300 304
  ///
301 305
  /// If the file type was previously evaluated by dimacsType(), then
302 306
  /// the descriptor struct should be given by the \c dest parameter.
303 307
  template<typename Digraph, typename LengthMap>
304 308
  void readDimacsSp(std::istream& is,
305 309
                    Digraph &g,
306 310
                    LengthMap& length,
307 311
                    typename Digraph::Node &s,
308 312
                    DimacsDescriptor desc=DimacsDescriptor()) {
309 313
    typename Digraph::Node t;
310 314
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
311 315
    if(desc.type!=DimacsDescriptor::SP)
312 316
      throw FormatError("Problem type mismatch");
313 317
    _readDimacs(is, g, length, s, t, 0, desc);
314 318
  }
315 319

	
316
  /// DIMACS capacitated digraph reader function.
320
  /// \brief DIMACS capacitated digraph reader function.
317 321
  ///
318 322
  /// This function reads an arc capacitated digraph instance from
319 323
  /// DIMACS 'max' or 'sp' format.
320 324
  /// At the beginning, \c g is cleared by \c g.clear()
321 325
  /// and the arc capacities/lengths are written to the \c capacity
322 326
  /// arc map.
323 327
  ///
324 328
  /// In case of the 'max' format, if the capacity of an arc is negative,
325 329
  /// it will
326 330
  /// be set to "infinite" instead. The actual value of "infinite" is
327 331
  /// contolled by the \c infty parameter. If it is 0 (the default value),
328 332
  /// \c std::numeric_limits<Capacity>::infinity() will be used if available,
329 333
  /// \c std::numeric_limits<Capacity>::max() otherwise. If \c infty is set to
330 334
  /// a non-zero value, that value will be used as "infinite".
331 335
  ///
332 336
  /// If the file type was previously evaluated by dimacsType(), then
333 337
  /// the descriptor struct should be given by the \c dest parameter.
334 338
  template<typename Digraph, typename CapacityMap>
335 339
  void readDimacsCap(std::istream& is,
336 340
                     Digraph &g,
337 341
                     CapacityMap& capacity,
338 342
                     typename CapacityMap::Value infty = 0,
339 343
                     DimacsDescriptor desc=DimacsDescriptor()) {
340 344
    typename Digraph::Node u,v;
341 345
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
342 346
    if(desc.type!=DimacsDescriptor::MAX || desc.type!=DimacsDescriptor::SP)
343 347
      throw FormatError("Problem type mismatch");
344 348
    _readDimacs(is, g, capacity, u, v, infty, desc);
345 349
  }
346 350

	
347 351
  template<typename Graph>
348 352
  typename enable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
349 353
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
350 354
              dummy<0> = 0)
351 355
  {
352 356
    g.addEdge(s,t);
353 357
  }
354 358
  template<typename Graph>
355 359
  typename disable_if<lemon::UndirectedTagIndicator<Graph>,void>::type
356 360
  _addArcEdge(Graph &g, typename Graph::Node s, typename Graph::Node t,
357 361
              dummy<1> = 1)
358 362
  {
359 363
    g.addArc(s,t);
360 364
  }
361 365
  
362
  /// DIMACS plain (di)graph reader function.
366
  /// \brief DIMACS plain (di)graph reader function.
363 367
  ///
364
  /// This function reads a (di)graph without any designated nodes and
365
  /// maps from DIMACS format, i.e. from DIMACS files having a line
366
  /// starting with
368
  /// This function reads a plain (di)graph without any designated nodes
369
  /// and maps (e.g. a matching instance) from DIMACS format, i.e. from 
370
  /// DIMACS files having a line starting with
367 371
  /// \code
368 372
  ///   p mat
369 373
  /// \endcode
370 374
  /// At the beginning, \c g is cleared by \c g.clear().
371 375
  ///
372 376
  /// If the file type was previously evaluated by dimacsType(), then
373 377
  /// the descriptor struct should be given by the \c dest parameter.
374 378
  template<typename Graph>
375 379
  void readDimacsMat(std::istream& is, Graph &g,
376 380
                     DimacsDescriptor desc=DimacsDescriptor())
377 381
  {
378 382
    if(desc.type==DimacsDescriptor::NONE) desc=dimacsType(is);
379 383
    if(desc.type!=DimacsDescriptor::MAT)
380 384
      throw FormatError("Problem type mismatch");
381 385

	
382 386
    g.clear();
383 387
    std::vector<typename Graph::Node> nodes;
384 388
    char c;
385 389
    int i, j;
386 390
    std::string str;
387 391
    nodes.resize(desc.nodeNum + 1);
388 392
    for (int k = 1; k <= desc.nodeNum; ++k) {
389 393
      nodes[k] = g.addNode();
390 394
    }
391 395
    
392 396
    while (is >> c) {
393 397
      switch (c) {
394 398
      case 'c': // comment line
395 399
        getline(is, str);
396 400
        break;
397 401
      case 'n': // node definition line
398 402
        break;
399 403
      case 'a': // arc definition line
400 404
        is >> i >> j;
401 405
        getline(is, str);
402 406
        _addArcEdge(g,nodes[i], nodes[j]);
403 407
        break;
404 408
      }
405 409
    }
406 410
  }
407 411

	
408 412
  /// DIMACS plain digraph writer function.
409 413
  ///
410 414
  /// This function writes a digraph without any designated nodes and
411 415
  /// maps into DIMACS format, i.e. into DIMACS file having a line
412 416
  /// starting with
413 417
  /// \code
414 418
  ///   p mat
415 419
  /// \endcode
416 420
  /// If \c comment is not empty, then it will be printed in the first line
417 421
  /// prefixed by 'c'.
418 422
  template<typename Digraph>
419 423
  void writeDimacsMat(std::ostream& os, const Digraph &g,
420 424
                      std::string comment="") {
421 425
    typedef typename Digraph::NodeIt NodeIt;
422 426
    typedef typename Digraph::ArcIt ArcIt;
423 427

	
424 428
    if(!comment.empty())
425 429
      os << "c " << comment << std::endl;
426 430
    os << "p mat " << g.nodeNum() << " " << g.arcNum() << std::endl;
427 431

	
428 432
    typename Digraph::template NodeMap<int> nodes(g);
429 433
    int i = 1;
430 434
    for(NodeIt v(g); v != INVALID; ++v) {
431 435
      nodes.set(v, i);
432 436
      ++i;
433 437
    }
434 438
    for(ArcIt e(g); e != INVALID; ++e) {
435 439
      os << "a " << nodes[g.source(e)] << " " << nodes[g.target(e)]
436 440
         << std::endl;
437 441
    }
438 442
  }
439 443

	
440 444
  /// @}
441 445

	
442 446
} //namespace lemon
443 447

	
444 448
#endif //LEMON_DIMACS_H
Ignore white space 384 line context
... ...
@@ -79,400 +79,396 @@
79 79

	
80 80
  const Graph &g;
81 81

	
82 82
  std::ostream& os;
83 83

	
84 84
  typedef ConstMap<typename Graph::Node,dim2::Point<double> > CoordsMapType;
85 85
  CoordsMapType _coords;
86 86
  ConstMap<typename Graph::Node,double > _nodeSizes;
87 87
  ConstMap<typename Graph::Node,int > _nodeShapes;
88 88

	
89 89
  ConstMap<typename Graph::Node,Color > _nodeColors;
90 90
  ConstMap<typename Graph::Arc,Color > _arcColors;
91 91

	
92 92
  ConstMap<typename Graph::Arc,double > _arcWidths;
93 93

	
94 94
  double _arcWidthScale;
95 95

	
96 96
  double _nodeScale;
97 97
  double _xBorder, _yBorder;
98 98
  double _scale;
99 99
  double _nodeBorderQuotient;
100 100

	
101 101
  bool _drawArrows;
102 102
  double _arrowLength, _arrowWidth;
103 103

	
104 104
  bool _showNodes, _showArcs;
105 105

	
106 106
  bool _enableParallel;
107 107
  double _parArcDist;
108 108

	
109 109
  bool _showNodeText;
110 110
  ConstMap<typename Graph::Node,bool > _nodeTexts;
111 111
  double _nodeTextSize;
112 112

	
113 113
  bool _showNodePsText;
114 114
  ConstMap<typename Graph::Node,bool > _nodePsTexts;
115 115
  char *_nodePsTextsPreamble;
116 116

	
117 117
  bool _undirected;
118 118

	
119 119
  bool _pleaseRemoveOsStream;
120 120

	
121 121
  bool _scaleToA4;
122 122

	
123 123
  std::string _title;
124 124
  std::string _copyright;
125 125

	
126 126
  enum NodeTextColorType
127 127
    { DIST_COL=0, DIST_BW=1, CUST_COL=2, SAME_COL=3 } _nodeTextColorType;
128 128
  ConstMap<typename Graph::Node,Color > _nodeTextColors;
129 129

	
130 130
  bool _autoNodeScale;
131 131
  bool _autoArcWidthScale;
132 132

	
133 133
  bool _absoluteNodeSizes;
134 134
  bool _absoluteArcWidths;
135 135

	
136 136
  bool _negY;
137 137

	
138 138
  bool _preScale;
139 139
  ///Constructor
140 140

	
141 141
  ///Constructor
142 142
  ///\param gr  Reference to the graph to be printed.
143 143
  ///\param ost Reference to the output stream.
144 144
  ///By default it is <tt>std::cout</tt>.
145 145
  ///\param pros If it is \c true, then the \c ostream referenced by \c os
146 146
  ///will be explicitly deallocated by the destructor.
147 147
  DefaultGraphToEpsTraits(const GR &gr, std::ostream& ost = std::cout,
148 148
                          bool pros = false) :
149 149
    g(gr), os(ost),
150 150
    _coords(dim2::Point<double>(1,1)), _nodeSizes(1), _nodeShapes(0),
151 151
    _nodeColors(WHITE), _arcColors(BLACK),
152 152
    _arcWidths(1.0), _arcWidthScale(0.003),
153 153
    _nodeScale(.01), _xBorder(10), _yBorder(10), _scale(1.0),
154 154
    _nodeBorderQuotient(.1),
155 155
    _drawArrows(false), _arrowLength(1), _arrowWidth(0.3),
156 156
    _showNodes(true), _showArcs(true),
157 157
    _enableParallel(false), _parArcDist(1),
158 158
    _showNodeText(false), _nodeTexts(false), _nodeTextSize(1),
159 159
    _showNodePsText(false), _nodePsTexts(false), _nodePsTextsPreamble(0),
160 160
    _undirected(lemon::UndirectedTagIndicator<GR>::value),
161 161
    _pleaseRemoveOsStream(pros), _scaleToA4(false),
162 162
    _nodeTextColorType(SAME_COL), _nodeTextColors(BLACK),
163 163
    _autoNodeScale(false),
164 164
    _autoArcWidthScale(false),
165 165
    _absoluteNodeSizes(false),
166 166
    _absoluteArcWidths(false),
167 167
    _negY(false),
168 168
    _preScale(true)
169 169
  {}
170 170
};
171 171

	
172 172
///Auxiliary class to implement the named parameters of \ref graphToEps()
173 173

	
174 174
///Auxiliary class to implement the named parameters of \ref graphToEps().
175 175
///
176 176
///For detailed examples see the \ref graph_to_eps_demo.cc demo file.
177 177
template<class T> class GraphToEps : public T
178 178
{
179 179
  // Can't believe it is required by the C++ standard
180 180
  using T::g;
181 181
  using T::os;
182 182

	
183 183
  using T::_coords;
184 184
  using T::_nodeSizes;
185 185
  using T::_nodeShapes;
186 186
  using T::_nodeColors;
187 187
  using T::_arcColors;
188 188
  using T::_arcWidths;
189 189

	
190 190
  using T::_arcWidthScale;
191 191
  using T::_nodeScale;
192 192
  using T::_xBorder;
193 193
  using T::_yBorder;
194 194
  using T::_scale;
195 195
  using T::_nodeBorderQuotient;
196 196

	
197 197
  using T::_drawArrows;
198 198
  using T::_arrowLength;
199 199
  using T::_arrowWidth;
200 200

	
201 201
  using T::_showNodes;
202 202
  using T::_showArcs;
203 203

	
204 204
  using T::_enableParallel;
205 205
  using T::_parArcDist;
206 206

	
207 207
  using T::_showNodeText;
208 208
  using T::_nodeTexts;
209 209
  using T::_nodeTextSize;
210 210

	
211 211
  using T::_showNodePsText;
212 212
  using T::_nodePsTexts;
213 213
  using T::_nodePsTextsPreamble;
214 214

	
215 215
  using T::_undirected;
216 216

	
217 217
  using T::_pleaseRemoveOsStream;
218 218

	
219 219
  using T::_scaleToA4;
220 220

	
221 221
  using T::_title;
222 222
  using T::_copyright;
223 223

	
224 224
  using T::NodeTextColorType;
225 225
  using T::CUST_COL;
226 226
  using T::DIST_COL;
227 227
  using T::DIST_BW;
228 228
  using T::_nodeTextColorType;
229 229
  using T::_nodeTextColors;
230 230

	
231 231
  using T::_autoNodeScale;
232 232
  using T::_autoArcWidthScale;
233 233

	
234 234
  using T::_absoluteNodeSizes;
235 235
  using T::_absoluteArcWidths;
236 236

	
237 237

	
238 238
  using T::_negY;
239 239
  using T::_preScale;
240 240

	
241 241
  // dradnats ++C eht yb deriuqer si ti eveileb t'naC
242 242

	
243 243
  typedef typename T::Graph Graph;
244 244
  typedef typename Graph::Node Node;
245 245
  typedef typename Graph::NodeIt NodeIt;
246 246
  typedef typename Graph::Arc Arc;
247 247
  typedef typename Graph::ArcIt ArcIt;
248 248
  typedef typename Graph::InArcIt InArcIt;
249 249
  typedef typename Graph::OutArcIt OutArcIt;
250 250

	
251 251
  static const int INTERPOL_PREC;
252 252
  static const double A4HEIGHT;
253 253
  static const double A4WIDTH;
254 254
  static const double A4BORDER;
255 255

	
256 256
  bool dontPrint;
257 257

	
258 258
public:
259 259
  ///Node shapes
260 260

	
261 261
  ///Node shapes.
262 262
  ///
263 263
  enum NodeShapes {
264 264
    /// = 0
265 265
    ///\image html nodeshape_0.png
266 266
    ///\image latex nodeshape_0.eps "CIRCLE shape (0)" width=2cm
267 267
    CIRCLE=0,
268 268
    /// = 1
269 269
    ///\image html nodeshape_1.png
270 270
    ///\image latex nodeshape_1.eps "SQUARE shape (1)" width=2cm
271
    ///
272 271
    SQUARE=1,
273 272
    /// = 2
274 273
    ///\image html nodeshape_2.png
275 274
    ///\image latex nodeshape_2.eps "DIAMOND shape (2)" width=2cm
276
    ///
277 275
    DIAMOND=2,
278 276
    /// = 3
279 277
    ///\image html nodeshape_3.png
280
    ///\image latex nodeshape_2.eps "MALE shape (4)" width=2cm
281
    ///
278
    ///\image latex nodeshape_3.eps "MALE shape (3)" width=2cm
282 279
    MALE=3,
283 280
    /// = 4
284 281
    ///\image html nodeshape_4.png
285
    ///\image latex nodeshape_2.eps "FEMALE shape (4)" width=2cm
286
    ///
282
    ///\image latex nodeshape_4.eps "FEMALE shape (4)" width=2cm
287 283
    FEMALE=4
288 284
  };
289 285

	
290 286
private:
291 287
  class arcLess {
292 288
    const Graph &g;
293 289
  public:
294 290
    arcLess(const Graph &_g) : g(_g) {}
295 291
    bool operator()(Arc a,Arc b) const
296 292
    {
297 293
      Node ai=std::min(g.source(a),g.target(a));
298 294
      Node aa=std::max(g.source(a),g.target(a));
299 295
      Node bi=std::min(g.source(b),g.target(b));
300 296
      Node ba=std::max(g.source(b),g.target(b));
301 297
      return ai<bi ||
302 298
        (ai==bi && (aa < ba ||
303 299
                    (aa==ba && ai==g.source(a) && bi==g.target(b))));
304 300
    }
305 301
  };
306 302
  bool isParallel(Arc e,Arc f) const
307 303
  {
308 304
    return (g.source(e)==g.source(f)&&
309 305
            g.target(e)==g.target(f)) ||
310 306
      (g.source(e)==g.target(f)&&
311 307
       g.target(e)==g.source(f));
312 308
  }
313 309
  template<class TT>
314 310
  static std::string psOut(const dim2::Point<TT> &p)
315 311
    {
316 312
      std::ostringstream os;
317 313
      os << p.x << ' ' << p.y;
318 314
      return os.str();
319 315
    }
320 316
  static std::string psOut(const Color &c)
321 317
    {
322 318
      std::ostringstream os;
323 319
      os << c.red() << ' ' << c.green() << ' ' << c.blue();
324 320
      return os.str();
325 321
    }
326 322

	
327 323
public:
328 324
  GraphToEps(const T &t) : T(t), dontPrint(false) {};
329 325

	
330 326
  template<class X> struct CoordsTraits : public T {
331 327
  typedef X CoordsMapType;
332 328
    const X &_coords;
333 329
    CoordsTraits(const T &t,const X &x) : T(t), _coords(x) {}
334 330
  };
335 331
  ///Sets the map of the node coordinates
336 332

	
337 333
  ///Sets the map of the node coordinates.
338 334
  ///\param x must be a node map with \ref dim2::Point "dim2::Point<double>" or
339 335
  ///\ref dim2::Point "dim2::Point<int>" values.
340 336
  template<class X> GraphToEps<CoordsTraits<X> > coords(const X &x) {
341 337
    dontPrint=true;
342 338
    return GraphToEps<CoordsTraits<X> >(CoordsTraits<X>(*this,x));
343 339
  }
344 340
  template<class X> struct NodeSizesTraits : public T {
345 341
    const X &_nodeSizes;
346 342
    NodeSizesTraits(const T &t,const X &x) : T(t), _nodeSizes(x) {}
347 343
  };
348 344
  ///Sets the map of the node sizes
349 345

	
350 346
  ///Sets the map of the node sizes.
351 347
  ///\param x must be a node map with \c double (or convertible) values.
352 348
  template<class X> GraphToEps<NodeSizesTraits<X> > nodeSizes(const X &x)
353 349
  {
354 350
    dontPrint=true;
355 351
    return GraphToEps<NodeSizesTraits<X> >(NodeSizesTraits<X>(*this,x));
356 352
  }
357 353
  template<class X> struct NodeShapesTraits : public T {
358 354
    const X &_nodeShapes;
359 355
    NodeShapesTraits(const T &t,const X &x) : T(t), _nodeShapes(x) {}
360 356
  };
361 357
  ///Sets the map of the node shapes
362 358

	
363 359
  ///Sets the map of the node shapes.
364 360
  ///The available shape values
365 361
  ///can be found in \ref NodeShapes "enum NodeShapes".
366 362
  ///\param x must be a node map with \c int (or convertible) values.
367 363
  ///\sa NodeShapes
368 364
  template<class X> GraphToEps<NodeShapesTraits<X> > nodeShapes(const X &x)
369 365
  {
370 366
    dontPrint=true;
371 367
    return GraphToEps<NodeShapesTraits<X> >(NodeShapesTraits<X>(*this,x));
372 368
  }
373 369
  template<class X> struct NodeTextsTraits : public T {
374 370
    const X &_nodeTexts;
375 371
    NodeTextsTraits(const T &t,const X &x) : T(t), _nodeTexts(x) {}
376 372
  };
377 373
  ///Sets the text printed on the nodes
378 374

	
379 375
  ///Sets the text printed on the nodes.
380 376
  ///\param x must be a node map with type that can be pushed to a standard
381 377
  ///\c ostream.
382 378
  template<class X> GraphToEps<NodeTextsTraits<X> > nodeTexts(const X &x)
383 379
  {
384 380
    dontPrint=true;
385 381
    _showNodeText=true;
386 382
    return GraphToEps<NodeTextsTraits<X> >(NodeTextsTraits<X>(*this,x));
387 383
  }
388 384
  template<class X> struct NodePsTextsTraits : public T {
389 385
    const X &_nodePsTexts;
390 386
    NodePsTextsTraits(const T &t,const X &x) : T(t), _nodePsTexts(x) {}
391 387
  };
392 388
  ///Inserts a PostScript block to the nodes
393 389

	
394 390
  ///With this command it is possible to insert a verbatim PostScript
395 391
  ///block to the nodes.
396 392
  ///The PS current point will be moved to the center of the node before
397 393
  ///the PostScript block inserted.
398 394
  ///
399 395
  ///Before and after the block a newline character is inserted so you
400 396
  ///don't have to bother with the separators.
401 397
  ///
402 398
  ///\param x must be a node map with type that can be pushed to a standard
403 399
  ///\c ostream.
404 400
  ///
405 401
  ///\sa nodePsTextsPreamble()
406 402
  template<class X> GraphToEps<NodePsTextsTraits<X> > nodePsTexts(const X &x)
407 403
  {
408 404
    dontPrint=true;
409 405
    _showNodePsText=true;
410 406
    return GraphToEps<NodePsTextsTraits<X> >(NodePsTextsTraits<X>(*this,x));
411 407
  }
412 408
  template<class X> struct ArcWidthsTraits : public T {
413 409
    const X &_arcWidths;
414 410
    ArcWidthsTraits(const T &t,const X &x) : T(t), _arcWidths(x) {}
415 411
  };
416 412
  ///Sets the map of the arc widths
417 413

	
418 414
  ///Sets the map of the arc widths.
419 415
  ///\param x must be an arc map with \c double (or convertible) values.
420 416
  template<class X> GraphToEps<ArcWidthsTraits<X> > arcWidths(const X &x)
421 417
  {
422 418
    dontPrint=true;
423 419
    return GraphToEps<ArcWidthsTraits<X> >(ArcWidthsTraits<X>(*this,x));
424 420
  }
425 421

	
426 422
  template<class X> struct NodeColorsTraits : public T {
427 423
    const X &_nodeColors;
428 424
    NodeColorsTraits(const T &t,const X &x) : T(t), _nodeColors(x) {}
429 425
  };
430 426
  ///Sets the map of the node colors
431 427

	
432 428
  ///Sets the map of the node colors.
433 429
  ///\param x must be a node map with \ref Color values.
434 430
  ///
435 431
  ///\sa Palette
436 432
  template<class X> GraphToEps<NodeColorsTraits<X> >
437 433
  nodeColors(const X &x)
438 434
  {
439 435
    dontPrint=true;
440 436
    return GraphToEps<NodeColorsTraits<X> >(NodeColorsTraits<X>(*this,x));
441 437
  }
442 438
  template<class X> struct NodeTextColorsTraits : public T {
443 439
    const X &_nodeTextColors;
444 440
    NodeTextColorsTraits(const T &t,const X &x) : T(t), _nodeTextColors(x) {}
445 441
  };
446 442
  ///Sets the map of the node text colors
447 443

	
448 444
  ///Sets the map of the node text colors.
449 445
  ///\param x must be a node map with \ref Color values.
450 446
  ///
451 447
  ///\sa Palette
452 448
  template<class X> GraphToEps<NodeTextColorsTraits<X> >
453 449
  nodeTextColors(const X &x)
454 450
  {
455 451
    dontPrint=true;
456 452
    _nodeTextColorType=CUST_COL;
457 453
    return GraphToEps<NodeTextColorsTraits<X> >
458 454
      (NodeTextColorsTraits<X>(*this,x));
459 455
  }
460 456
  template<class X> struct ArcColorsTraits : public T {
461 457
    const X &_arcColors;
462 458
    ArcColorsTraits(const T &t,const X &x) : T(t), _arcColors(x) {}
463 459
  };
464 460
  ///Sets the map of the arc colors
465 461

	
466 462
  ///Sets the map of the arc colors.
467 463
  ///\param x must be an arc map with \ref Color values.
468 464
  ///
469 465
  ///\sa Palette
470 466
  template<class X> GraphToEps<ArcColorsTraits<X> >
471 467
  arcColors(const X &x)
472 468
  {
473 469
    dontPrint=true;
474 470
    return GraphToEps<ArcColorsTraits<X> >(ArcColorsTraits<X>(*this,x));
475 471
  }
476 472
  ///Sets a global scale factor for node sizes
477 473

	
478 474
  ///Sets a global scale factor for node sizes.
Ignore white space 384 line context
... ...
@@ -59,271 +59,269 @@
59 59
        if (uf.join(digraph.target(it->first),digraph.source(it->first))) {
60 60
          out.set(it->first, true);
61 61
          tree_value += it->second;
62 62
        }
63 63
        else {
64 64
          out.set(it->first, false);
65 65
        }
66 66
      }
67 67
      return tree_value;
68 68
    }
69 69

	
70 70
    // Kruskal for undirected graphs.
71 71

	
72 72
    template <typename Graph, typename In, typename Out>
73 73
    typename enable_if<lemon::UndirectedTagIndicator<Graph>,
74 74
                       typename In::value_type::second_type >::type
75 75
    kruskal(const Graph& graph, const In& in, Out& out,dummy<1> = 1) {
76 76
      typedef typename In::value_type::second_type Value;
77 77
      typedef typename Graph::template NodeMap<int> IndexMap;
78 78
      typedef typename Graph::Node Node;
79 79

	
80 80
      IndexMap index(graph);
81 81
      UnionFind<IndexMap> uf(index);
82 82
      for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
83 83
        uf.insert(it);
84 84
      }
85 85

	
86 86
      Value tree_value = 0;
87 87
      for (typename In::const_iterator it = in.begin(); it != in.end(); ++it) {
88 88
        if (uf.join(graph.u(it->first),graph.v(it->first))) {
89 89
          out.set(it->first, true);
90 90
          tree_value += it->second;
91 91
        }
92 92
        else {
93 93
          out.set(it->first, false);
94 94
        }
95 95
      }
96 96
      return tree_value;
97 97
    }
98 98

	
99 99

	
100 100
    template <typename Sequence>
101 101
    struct PairComp {
102 102
      typedef typename Sequence::value_type Value;
103 103
      bool operator()(const Value& left, const Value& right) {
104 104
        return left.second < right.second;
105 105
      }
106 106
    };
107 107

	
108 108
    template <typename In, typename Enable = void>
109 109
    struct SequenceInputIndicator {
110 110
      static const bool value = false;
111 111
    };
112 112

	
113 113
    template <typename In>
114 114
    struct SequenceInputIndicator<In,
115 115
      typename exists<typename In::value_type::first_type>::type> {
116 116
      static const bool value = true;
117 117
    };
118 118

	
119 119
    template <typename In, typename Enable = void>
120 120
    struct MapInputIndicator {
121 121
      static const bool value = false;
122 122
    };
123 123

	
124 124
    template <typename In>
125 125
    struct MapInputIndicator<In,
126 126
      typename exists<typename In::Value>::type> {
127 127
      static const bool value = true;
128 128
    };
129 129

	
130 130
    template <typename In, typename Enable = void>
131 131
    struct SequenceOutputIndicator {
132 132
      static const bool value = false;
133 133
    };
134 134

	
135 135
    template <typename Out>
136 136
    struct SequenceOutputIndicator<Out,
137 137
      typename exists<typename Out::value_type>::type> {
138 138
      static const bool value = true;
139 139
    };
140 140

	
141 141
    template <typename Out, typename Enable = void>
142 142
    struct MapOutputIndicator {
143 143
      static const bool value = false;
144 144
    };
145 145

	
146 146
    template <typename Out>
147 147
    struct MapOutputIndicator<Out,
148 148
      typename exists<typename Out::Value>::type> {
149 149
      static const bool value = true;
150 150
    };
151 151

	
152 152
    template <typename In, typename InEnable = void>
153 153
    struct KruskalValueSelector {};
154 154

	
155 155
    template <typename In>
156 156
    struct KruskalValueSelector<In,
157 157
      typename enable_if<SequenceInputIndicator<In>, void>::type>
158 158
    {
159 159
      typedef typename In::value_type::second_type Value;
160 160
    };
161 161

	
162 162
    template <typename In>
163 163
    struct KruskalValueSelector<In,
164 164
      typename enable_if<MapInputIndicator<In>, void>::type>
165 165
    {
166 166
      typedef typename In::Value Value;
167 167
    };
168 168

	
169 169
    template <typename Graph, typename In, typename Out,
170 170
              typename InEnable = void>
171 171
    struct KruskalInputSelector {};
172 172

	
173 173
    template <typename Graph, typename In, typename Out,
174 174
              typename InEnable = void>
175 175
    struct KruskalOutputSelector {};
176 176

	
177 177
    template <typename Graph, typename In, typename Out>
178 178
    struct KruskalInputSelector<Graph, In, Out,
179 179
      typename enable_if<SequenceInputIndicator<In>, void>::type >
180 180
    {
181 181
      typedef typename In::value_type::second_type Value;
182 182

	
183 183
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
184 184
        return KruskalOutputSelector<Graph, In, Out>::
185 185
          kruskal(graph, in, out);
186 186
      }
187 187

	
188 188
    };
189 189

	
190 190
    template <typename Graph, typename In, typename Out>
191 191
    struct KruskalInputSelector<Graph, In, Out,
192 192
      typename enable_if<MapInputIndicator<In>, void>::type >
193 193
    {
194 194
      typedef typename In::Value Value;
195 195
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
196 196
        typedef typename In::Key MapArc;
197 197
        typedef typename In::Value Value;
198 198
        typedef typename ItemSetTraits<Graph, MapArc>::ItemIt MapArcIt;
199 199
        typedef std::vector<std::pair<MapArc, Value> > Sequence;
200 200
        Sequence seq;
201 201

	
202 202
        for (MapArcIt it(graph); it != INVALID; ++it) {
203 203
          seq.push_back(std::make_pair(it, in[it]));
204 204
        }
205 205

	
206 206
        std::sort(seq.begin(), seq.end(), PairComp<Sequence>());
207 207
        return KruskalOutputSelector<Graph, Sequence, Out>::
208 208
          kruskal(graph, seq, out);
209 209
      }
210 210
    };
211 211

	
212 212
    template <typename T>
213 213
    struct RemoveConst {
214 214
      typedef T type;
215 215
    };
216 216

	
217 217
    template <typename T>
218 218
    struct RemoveConst<const T> {
219 219
      typedef T type;
220 220
    };
221 221

	
222 222
    template <typename Graph, typename In, typename Out>
223 223
    struct KruskalOutputSelector<Graph, In, Out,
224 224
      typename enable_if<SequenceOutputIndicator<Out>, void>::type >
225 225
    {
226 226
      typedef typename In::value_type::second_type Value;
227 227

	
228 228
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
229 229
        typedef LoggerBoolMap<typename RemoveConst<Out>::type> Map;
230 230
        Map map(out);
231 231
        return _kruskal_bits::kruskal(graph, in, map);
232 232
      }
233 233

	
234 234
    };
235 235

	
236 236
    template <typename Graph, typename In, typename Out>
237 237
    struct KruskalOutputSelector<Graph, In, Out,
238 238
      typename enable_if<MapOutputIndicator<Out>, void>::type >
239 239
    {
240 240
      typedef typename In::value_type::second_type Value;
241 241

	
242 242
      static Value kruskal(const Graph& graph, const In& in, Out& out) {
243 243
        return _kruskal_bits::kruskal(graph, in, out);
244 244
      }
245 245
    };
246 246

	
247 247
  }
248 248

	
249 249
  /// \ingroup spantree
250 250
  ///
251
  /// \brief Kruskal algorithm to find a minimum cost spanning tree of
251
  /// \brief Kruskal's algorithm for finding a minimum cost spanning tree of
252 252
  /// a graph.
253 253
  ///
254 254
  /// This function runs Kruskal's algorithm to find a minimum cost
255
  /// spanning tree.
255
  /// spanning tree of a graph.
256 256
  /// Due to some C++ hacking, it accepts various input and output types.
257 257
  ///
258 258
  /// \param g The graph the algorithm runs on.
259 259
  /// It can be either \ref concepts::Digraph "directed" or
260 260
  /// \ref concepts::Graph "undirected".
261 261
  /// If the graph is directed, the algorithm consider it to be
262 262
  /// undirected by disregarding the direction of the arcs.
263 263
  ///
264 264
  /// \param in This object is used to describe the arc/edge costs.
265 265
  /// It can be one of the following choices.
266 266
  /// - An STL compatible 'Forward Container' with
267
  /// <tt>std::pair<GR::Arc,X></tt> or
268
  /// <tt>std::pair<GR::Edge,X></tt> as its <tt>value_type</tt>, where
269
  /// \c X is the type of the costs. The pairs indicates the arcs/edges
267
  /// <tt>std::pair<GR::Arc,C></tt> or
268
  /// <tt>std::pair<GR::Edge,C></tt> as its <tt>value_type</tt>, where
269
  /// \c C is the type of the costs. The pairs indicates the arcs/edges
270 270
  /// along with the assigned cost. <em>They must be in a
271 271
  /// cost-ascending order.</em>
272 272
  /// - Any readable arc/edge map. The values of the map indicate the
273 273
  /// arc/edge costs.
274 274
  ///
275 275
  /// \retval out Here we also have a choice.
276
  /// - It can be a writable \c bool arc/edge map. After running the
277
  /// algorithm it will contain the found minimum cost spanning
276
  /// - It can be a writable arc/edge map with \c bool value type. After
277
  /// running the algorithm it will contain the found minimum cost spanning
278 278
  /// tree: the value of an arc/edge will be set to \c true if it belongs
279 279
  /// to the tree, otherwise it will be set to \c false. The value of
280 280
  /// each arc/edge will be set exactly once.
281 281
  /// - It can also be an iteraror of an STL Container with
282 282
  /// <tt>GR::Arc</tt> or <tt>GR::Edge</tt> as its
283 283
  /// <tt>value_type</tt>.  The algorithm copies the elements of the
284 284
  /// found tree into this sequence.  For example, if we know that the
285 285
  /// spanning tree of the graph \c g has say 53 arcs, then we can
286 286
  /// put its arcs into an STL vector \c tree with a code like this.
287 287
  ///\code
288 288
  /// std::vector<Arc> tree(53);
289 289
  /// kruskal(g,cost,tree.begin());
290 290
  ///\endcode
291 291
  /// Or if we don't know in advance the size of the tree, we can
292 292
  /// write this.
293 293
  ///\code
294 294
  /// std::vector<Arc> tree;
295 295
  /// kruskal(g,cost,std::back_inserter(tree));
296 296
  ///\endcode
297 297
  ///
298 298
  /// \return The total cost of the found spanning tree.
299 299
  ///
300 300
  /// \note If the input graph is not (weakly) connected, a spanning
301 301
  /// forest is calculated instead of a spanning tree.
302 302

	
303 303
#ifdef DOXYGEN
304
  template <class Graph, class In, class Out>
305
  Value kruskal(GR const& g, const In& in, Out& out)
304
  template <typename Graph, typename In, typename Out>
305
  Value kruskal(const Graph& g, const In& in, Out& out)
306 306
#else
307 307
  template <class Graph, class In, class Out>
308 308
  inline typename _kruskal_bits::KruskalValueSelector<In>::Value
309 309
  kruskal(const Graph& graph, const In& in, Out& out)
310 310
#endif
311 311
  {
312 312
    return _kruskal_bits::KruskalInputSelector<Graph, In, Out>::
313 313
      kruskal(graph, in, out);
314 314
  }
315 315

	
316 316

	
317

	
318

	
319 317
  template <class Graph, class In, class Out>
320 318
  inline typename _kruskal_bits::KruskalValueSelector<In>::Value
321 319
  kruskal(const Graph& graph, const In& in, const Out& out)
322 320
  {
323 321
    return _kruskal_bits::KruskalInputSelector<Graph, In, const Out>::
324 322
      kruskal(graph, in, out);
325 323
  }
326 324

	
327 325
} //namespace lemon
328 326

	
329 327
#endif //LEMON_KRUSKAL_H
Ignore white space 384 line context
... ...
@@ -404,519 +404,519 @@
404 404
  ///
405 405
  /// This utility reads an \ref lgf-format "LGF" file.
406 406
  ///
407 407
  /// The reading method does a batch processing. The user creates a
408 408
  /// reader object, then various reading rules can be added to the
409 409
  /// reader, and eventually the reading is executed with the \c run()
410 410
  /// member function. A map reading rule can be added to the reader
411 411
  /// with the \c nodeMap() or \c arcMap() members. An optional
412 412
  /// converter parameter can also be added as a standard functor
413 413
  /// converting from \c std::string to the value type of the map. If it
414 414
  /// is set, it will determine how the tokens in the file should be
415 415
  /// converted to the value type of the map. If the functor is not set,
416 416
  /// then a default conversion will be used. One map can be read into
417 417
  /// multiple map objects at the same time. The \c attribute(), \c
418 418
  /// node() and \c arc() functions are used to add attribute reading
419 419
  /// rules.
420 420
  ///
421 421
  ///\code
422 422
  /// DigraphReader<Digraph>(digraph, std::cin).
423 423
  ///   nodeMap("coordinates", coord_map).
424 424
  ///   arcMap("capacity", cap_map).
425 425
  ///   node("source", src).
426 426
  ///   node("target", trg).
427 427
  ///   attribute("caption", caption).
428 428
  ///   run();
429 429
  ///\endcode
430 430
  ///
431 431
  /// By default the reader uses the first section in the file of the
432 432
  /// proper type. If a section has an optional name, then it can be
433 433
  /// selected for reading by giving an optional name parameter to the
434 434
  /// \c nodes(), \c arcs() or \c attributes() functions.
435 435
  ///
436 436
  /// The \c useNodes() and \c useArcs() functions are used to tell the reader
437 437
  /// that the nodes or arcs should not be constructed (added to the
438 438
  /// graph) during the reading, but instead the label map of the items
439 439
  /// are given as a parameter of these functions. An
440 440
  /// application of these functions is multipass reading, which is
441 441
  /// important if two \c \@arcs sections must be read from the
442 442
  /// file. In this case the first phase would read the node set and one
443 443
  /// of the arc sets, while the second phase would read the second arc
444 444
  /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet).
445 445
  /// The previously read label node map should be passed to the \c
446 446
  /// useNodes() functions. Another application of multipass reading when
447 447
  /// paths are given as a node map or an arc map.
448 448
  /// It is impossible to read this in
449 449
  /// a single pass, because the arcs are not constructed when the node
450 450
  /// maps are read.
451 451
  template <typename GR>
452 452
  class DigraphReader {
453 453
  public:
454 454

	
455 455
    typedef GR Digraph;
456 456

	
457 457
  private:
458 458

	
459 459
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
460 460

	
461 461
    std::istream* _is;
462 462
    bool local_is;
463 463
    std::string _filename;
464 464

	
465 465
    Digraph& _digraph;
466 466

	
467 467
    std::string _nodes_caption;
468 468
    std::string _arcs_caption;
469 469
    std::string _attributes_caption;
470 470

	
471 471
    typedef std::map<std::string, Node> NodeIndex;
472 472
    NodeIndex _node_index;
473 473
    typedef std::map<std::string, Arc> ArcIndex;
474 474
    ArcIndex _arc_index;
475 475

	
476 476
    typedef std::vector<std::pair<std::string,
477 477
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
478 478
    NodeMaps _node_maps;
479 479

	
480 480
    typedef std::vector<std::pair<std::string,
481 481
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
482 482
    ArcMaps _arc_maps;
483 483

	
484 484
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
485 485
      Attributes;
486 486
    Attributes _attributes;
487 487

	
488 488
    bool _use_nodes;
489 489
    bool _use_arcs;
490 490

	
491 491
    bool _skip_nodes;
492 492
    bool _skip_arcs;
493 493

	
494 494
    int line_num;
495 495
    std::istringstream line;
496 496

	
497 497
  public:
498 498

	
499 499
    /// \brief Constructor
500 500
    ///
501 501
    /// Construct a directed graph reader, which reads from the given
502 502
    /// input stream.
503 503
    DigraphReader(Digraph& digraph, std::istream& is = std::cin)
504 504
      : _is(&is), local_is(false), _digraph(digraph),
505 505
        _use_nodes(false), _use_arcs(false),
506 506
        _skip_nodes(false), _skip_arcs(false) {}
507 507

	
508 508
    /// \brief Constructor
509 509
    ///
510 510
    /// Construct a directed graph reader, which reads from the given
511 511
    /// file.
512 512
    DigraphReader(Digraph& digraph, const std::string& fn)
513 513
      : _is(new std::ifstream(fn.c_str())), local_is(true),
514 514
        _filename(fn), _digraph(digraph),
515 515
        _use_nodes(false), _use_arcs(false),
516 516
        _skip_nodes(false), _skip_arcs(false) {
517 517
      if (!(*_is)) {
518 518
        delete _is;
519 519
        throw IoError("Cannot open file", fn);
520 520
      }
521 521
    }
522 522

	
523 523
    /// \brief Constructor
524 524
    ///
525 525
    /// Construct a directed graph reader, which reads from the given
526 526
    /// file.
527 527
    DigraphReader(Digraph& digraph, const char* fn)
528 528
      : _is(new std::ifstream(fn)), local_is(true),
529 529
        _filename(fn), _digraph(digraph),
530 530
        _use_nodes(false), _use_arcs(false),
531 531
        _skip_nodes(false), _skip_arcs(false) {
532 532
      if (!(*_is)) {
533 533
        delete _is;
534 534
        throw IoError("Cannot open file", fn);
535 535
      }
536 536
    }
537 537

	
538 538
    /// \brief Destructor
539 539
    ~DigraphReader() {
540 540
      for (typename NodeMaps::iterator it = _node_maps.begin();
541 541
           it != _node_maps.end(); ++it) {
542 542
        delete it->second;
543 543
      }
544 544

	
545 545
      for (typename ArcMaps::iterator it = _arc_maps.begin();
546 546
           it != _arc_maps.end(); ++it) {
547 547
        delete it->second;
548 548
      }
549 549

	
550 550
      for (typename Attributes::iterator it = _attributes.begin();
551 551
           it != _attributes.end(); ++it) {
552 552
        delete it->second;
553 553
      }
554 554

	
555 555
      if (local_is) {
556 556
        delete _is;
557 557
      }
558 558

	
559 559
    }
560 560

	
561 561
  private:
562 562

	
563 563
    template <typename DGR>
564 564
    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
565 565
    template <typename DGR>
566 566
    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
567 567
                                            const std::string& fn);
568 568
    template <typename DGR>
569 569
    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
570 570

	
571 571
    DigraphReader(DigraphReader& other)
572 572
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
573 573
        _use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
574 574
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
575 575

	
576 576
      other._is = 0;
577 577
      other.local_is = false;
578 578

	
579 579
      _node_index.swap(other._node_index);
580 580
      _arc_index.swap(other._arc_index);
581 581

	
582 582
      _node_maps.swap(other._node_maps);
583 583
      _arc_maps.swap(other._arc_maps);
584 584
      _attributes.swap(other._attributes);
585 585

	
586 586
      _nodes_caption = other._nodes_caption;
587 587
      _arcs_caption = other._arcs_caption;
588 588
      _attributes_caption = other._attributes_caption;
589 589

	
590 590
    }
591 591

	
592 592
    DigraphReader& operator=(const DigraphReader&);
593 593

	
594 594
  public:
595 595

	
596
    /// \name Reading rules
596
    /// \name Reading Rules
597 597
    /// @{
598 598

	
599 599
    /// \brief Node map reading rule
600 600
    ///
601 601
    /// Add a node map reading rule to the reader.
602 602
    template <typename Map>
603 603
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
604 604
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
605 605
      _reader_bits::MapStorageBase<Node>* storage =
606 606
        new _reader_bits::MapStorage<Node, Map>(map);
607 607
      _node_maps.push_back(std::make_pair(caption, storage));
608 608
      return *this;
609 609
    }
610 610

	
611 611
    /// \brief Node map reading rule
612 612
    ///
613 613
    /// Add a node map reading rule with specialized converter to the
614 614
    /// reader.
615 615
    template <typename Map, typename Converter>
616 616
    DigraphReader& nodeMap(const std::string& caption, Map& map,
617 617
                           const Converter& converter = Converter()) {
618 618
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
619 619
      _reader_bits::MapStorageBase<Node>* storage =
620 620
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
621 621
      _node_maps.push_back(std::make_pair(caption, storage));
622 622
      return *this;
623 623
    }
624 624

	
625 625
    /// \brief Arc map reading rule
626 626
    ///
627 627
    /// Add an arc map reading rule to the reader.
628 628
    template <typename Map>
629 629
    DigraphReader& arcMap(const std::string& caption, Map& map) {
630 630
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
631 631
      _reader_bits::MapStorageBase<Arc>* storage =
632 632
        new _reader_bits::MapStorage<Arc, Map>(map);
633 633
      _arc_maps.push_back(std::make_pair(caption, storage));
634 634
      return *this;
635 635
    }
636 636

	
637 637
    /// \brief Arc map reading rule
638 638
    ///
639 639
    /// Add an arc map reading rule with specialized converter to the
640 640
    /// reader.
641 641
    template <typename Map, typename Converter>
642 642
    DigraphReader& arcMap(const std::string& caption, Map& map,
643 643
                          const Converter& converter = Converter()) {
644 644
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
645 645
      _reader_bits::MapStorageBase<Arc>* storage =
646 646
        new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
647 647
      _arc_maps.push_back(std::make_pair(caption, storage));
648 648
      return *this;
649 649
    }
650 650

	
651 651
    /// \brief Attribute reading rule
652 652
    ///
653 653
    /// Add an attribute reading rule to the reader.
654 654
    template <typename Value>
655 655
    DigraphReader& attribute(const std::string& caption, Value& value) {
656 656
      _reader_bits::ValueStorageBase* storage =
657 657
        new _reader_bits::ValueStorage<Value>(value);
658 658
      _attributes.insert(std::make_pair(caption, storage));
659 659
      return *this;
660 660
    }
661 661

	
662 662
    /// \brief Attribute reading rule
663 663
    ///
664 664
    /// Add an attribute reading rule with specialized converter to the
665 665
    /// reader.
666 666
    template <typename Value, typename Converter>
667 667
    DigraphReader& attribute(const std::string& caption, Value& value,
668 668
                             const Converter& converter = Converter()) {
669 669
      _reader_bits::ValueStorageBase* storage =
670 670
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
671 671
      _attributes.insert(std::make_pair(caption, storage));
672 672
      return *this;
673 673
    }
674 674

	
675 675
    /// \brief Node reading rule
676 676
    ///
677 677
    /// Add a node reading rule to reader.
678 678
    DigraphReader& node(const std::string& caption, Node& node) {
679 679
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
680 680
      Converter converter(_node_index);
681 681
      _reader_bits::ValueStorageBase* storage =
682 682
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
683 683
      _attributes.insert(std::make_pair(caption, storage));
684 684
      return *this;
685 685
    }
686 686

	
687 687
    /// \brief Arc reading rule
688 688
    ///
689 689
    /// Add an arc reading rule to reader.
690 690
    DigraphReader& arc(const std::string& caption, Arc& arc) {
691 691
      typedef _reader_bits::MapLookUpConverter<Arc> Converter;
692 692
      Converter converter(_arc_index);
693 693
      _reader_bits::ValueStorageBase* storage =
694 694
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
695 695
      _attributes.insert(std::make_pair(caption, storage));
696 696
      return *this;
697 697
    }
698 698

	
699 699
    /// @}
700 700

	
701
    /// \name Select section by name
701
    /// \name Select Section by Name
702 702
    /// @{
703 703

	
704 704
    /// \brief Set \c \@nodes section to be read
705 705
    ///
706 706
    /// Set \c \@nodes section to be read
707 707
    DigraphReader& nodes(const std::string& caption) {
708 708
      _nodes_caption = caption;
709 709
      return *this;
710 710
    }
711 711

	
712 712
    /// \brief Set \c \@arcs section to be read
713 713
    ///
714 714
    /// Set \c \@arcs section to be read
715 715
    DigraphReader& arcs(const std::string& caption) {
716 716
      _arcs_caption = caption;
717 717
      return *this;
718 718
    }
719 719

	
720 720
    /// \brief Set \c \@attributes section to be read
721 721
    ///
722 722
    /// Set \c \@attributes section to be read
723 723
    DigraphReader& attributes(const std::string& caption) {
724 724
      _attributes_caption = caption;
725 725
      return *this;
726 726
    }
727 727

	
728 728
    /// @}
729 729

	
730
    /// \name Using previously constructed node or arc set
730
    /// \name Using Previously Constructed Node or Arc Set
731 731
    /// @{
732 732

	
733 733
    /// \brief Use previously constructed node set
734 734
    ///
735 735
    /// Use previously constructed node set, and specify the node
736 736
    /// label map.
737 737
    template <typename Map>
738 738
    DigraphReader& useNodes(const Map& map) {
739 739
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
740 740
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
741 741
      _use_nodes = true;
742 742
      _writer_bits::DefaultConverter<typename Map::Value> converter;
743 743
      for (NodeIt n(_digraph); n != INVALID; ++n) {
744 744
        _node_index.insert(std::make_pair(converter(map[n]), n));
745 745
      }
746 746
      return *this;
747 747
    }
748 748

	
749 749
    /// \brief Use previously constructed node set
750 750
    ///
751 751
    /// Use previously constructed node set, and specify the node
752 752
    /// label map and a functor which converts the label map values to
753 753
    /// \c std::string.
754 754
    template <typename Map, typename Converter>
755 755
    DigraphReader& useNodes(const Map& map,
756 756
                            const Converter& converter = Converter()) {
757 757
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
758 758
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
759 759
      _use_nodes = true;
760 760
      for (NodeIt n(_digraph); n != INVALID; ++n) {
761 761
        _node_index.insert(std::make_pair(converter(map[n]), n));
762 762
      }
763 763
      return *this;
764 764
    }
765 765

	
766 766
    /// \brief Use previously constructed arc set
767 767
    ///
768 768
    /// Use previously constructed arc set, and specify the arc
769 769
    /// label map.
770 770
    template <typename Map>
771 771
    DigraphReader& useArcs(const Map& map) {
772 772
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
773 773
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
774 774
      _use_arcs = true;
775 775
      _writer_bits::DefaultConverter<typename Map::Value> converter;
776 776
      for (ArcIt a(_digraph); a != INVALID; ++a) {
777 777
        _arc_index.insert(std::make_pair(converter(map[a]), a));
778 778
      }
779 779
      return *this;
780 780
    }
781 781

	
782 782
    /// \brief Use previously constructed arc set
783 783
    ///
784 784
    /// Use previously constructed arc set, and specify the arc
785 785
    /// label map and a functor which converts the label map values to
786 786
    /// \c std::string.
787 787
    template <typename Map, typename Converter>
788 788
    DigraphReader& useArcs(const Map& map,
789 789
                           const Converter& converter = Converter()) {
790 790
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
791 791
      LEMON_ASSERT(!_use_arcs, "Multiple usage of useArcs() member");
792 792
      _use_arcs = true;
793 793
      for (ArcIt a(_digraph); a != INVALID; ++a) {
794 794
        _arc_index.insert(std::make_pair(converter(map[a]), a));
795 795
      }
796 796
      return *this;
797 797
    }
798 798

	
799 799
    /// \brief Skips the reading of node section
800 800
    ///
801 801
    /// Omit the reading of the node section. This implies that each node
802 802
    /// map reading rule will be abandoned, and the nodes of the graph
803 803
    /// will not be constructed, which usually cause that the arc set
804 804
    /// could not be read due to lack of node name resolving.
805 805
    /// Therefore \c skipArcs() function should also be used, or
806 806
    /// \c useNodes() should be used to specify the label of the nodes.
807 807
    DigraphReader& skipNodes() {
808 808
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
809 809
      _skip_nodes = true;
810 810
      return *this;
811 811
    }
812 812

	
813 813
    /// \brief Skips the reading of arc section
814 814
    ///
815 815
    /// Omit the reading of the arc section. This implies that each arc
816 816
    /// map reading rule will be abandoned, and the arcs of the graph
817 817
    /// will not be constructed.
818 818
    DigraphReader& skipArcs() {
819 819
      LEMON_ASSERT(!_skip_arcs, "Skip arcs already set");
820 820
      _skip_arcs = true;
821 821
      return *this;
822 822
    }
823 823

	
824 824
    /// @}
825 825

	
826 826
  private:
827 827

	
828 828
    bool readLine() {
829 829
      std::string str;
830 830
      while(++line_num, std::getline(*_is, str)) {
831 831
        line.clear(); line.str(str);
832 832
        char c;
833 833
        if (line >> std::ws >> c && c != '#') {
834 834
          line.putback(c);
835 835
          return true;
836 836
        }
837 837
      }
838 838
      return false;
839 839
    }
840 840

	
841 841
    bool readSuccess() {
842 842
      return static_cast<bool>(*_is);
843 843
    }
844 844

	
845 845
    void skipSection() {
846 846
      char c;
847 847
      while (readSuccess() && line >> c && c != '@') {
848 848
        readLine();
849 849
      }
850 850
      if (readSuccess()) {
851 851
        line.putback(c);
852 852
      }
853 853
    }
854 854

	
855 855
    void readNodes() {
856 856

	
857 857
      std::vector<int> map_index(_node_maps.size());
858 858
      int map_num, label_index;
859 859

	
860 860
      char c;
861 861
      if (!readLine() || !(line >> c) || c == '@') {
862 862
        if (readSuccess() && line) line.putback(c);
863 863
        if (!_node_maps.empty())
864 864
          throw FormatError("Cannot find map names");
865 865
        return;
866 866
      }
867 867
      line.putback(c);
868 868

	
869 869
      {
870 870
        std::map<std::string, int> maps;
871 871

	
872 872
        std::string map;
873 873
        int index = 0;
874 874
        while (_reader_bits::readToken(line, map)) {
875 875
          if (maps.find(map) != maps.end()) {
876 876
            std::ostringstream msg;
877 877
            msg << "Multiple occurence of node map: " << map;
878 878
            throw FormatError(msg.str());
879 879
          }
880 880
          maps.insert(std::make_pair(map, index));
881 881
          ++index;
882 882
        }
883 883

	
884 884
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
885 885
          std::map<std::string, int>::iterator jt =
886 886
            maps.find(_node_maps[i].first);
887 887
          if (jt == maps.end()) {
888 888
            std::ostringstream msg;
889 889
            msg << "Map not found: " << _node_maps[i].first;
890 890
            throw FormatError(msg.str());
891 891
          }
892 892
          map_index[i] = jt->second;
893 893
        }
894 894

	
895 895
        {
896 896
          std::map<std::string, int>::iterator jt = maps.find("label");
897 897
          if (jt != maps.end()) {
898 898
            label_index = jt->second;
899 899
          } else {
900 900
            label_index = -1;
901 901
          }
902 902
        }
903 903
        map_num = maps.size();
904 904
      }
905 905

	
906 906
      while (readLine() && line >> c && c != '@') {
907 907
        line.putback(c);
908 908

	
909 909
        std::vector<std::string> tokens(map_num);
910 910
        for (int i = 0; i < map_num; ++i) {
911 911
          if (!_reader_bits::readToken(line, tokens[i])) {
912 912
            std::ostringstream msg;
913 913
            msg << "Column not found (" << i + 1 << ")";
914 914
            throw FormatError(msg.str());
915 915
          }
916 916
        }
917 917
        if (line >> std::ws >> c)
918 918
          throw FormatError("Extra character at the end of line");
919 919

	
920 920
        Node n;
921 921
        if (!_use_nodes) {
922 922
          n = _digraph.addNode();
... ...
@@ -927,838 +927,838 @@
927 927
            throw FormatError("Label map not found");
928 928
          typename std::map<std::string, Node>::iterator it =
929 929
            _node_index.find(tokens[label_index]);
930 930
          if (it == _node_index.end()) {
931 931
            std::ostringstream msg;
932 932
            msg << "Node with label not found: " << tokens[label_index];
933 933
            throw FormatError(msg.str());
934 934
          }
935 935
          n = it->second;
936 936
        }
937 937

	
938 938
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
939 939
          _node_maps[i].second->set(n, tokens[map_index[i]]);
940 940
        }
941 941

	
942 942
      }
943 943
      if (readSuccess()) {
944 944
        line.putback(c);
945 945
      }
946 946
    }
947 947

	
948 948
    void readArcs() {
949 949

	
950 950
      std::vector<int> map_index(_arc_maps.size());
951 951
      int map_num, label_index;
952 952

	
953 953
      char c;
954 954
      if (!readLine() || !(line >> c) || c == '@') {
955 955
        if (readSuccess() && line) line.putback(c);
956 956
        if (!_arc_maps.empty())
957 957
          throw FormatError("Cannot find map names");
958 958
        return;
959 959
      }
960 960
      line.putback(c);
961 961

	
962 962
      {
963 963
        std::map<std::string, int> maps;
964 964

	
965 965
        std::string map;
966 966
        int index = 0;
967 967
        while (_reader_bits::readToken(line, map)) {
968 968
          if (maps.find(map) != maps.end()) {
969 969
            std::ostringstream msg;
970 970
            msg << "Multiple occurence of arc map: " << map;
971 971
            throw FormatError(msg.str());
972 972
          }
973 973
          maps.insert(std::make_pair(map, index));
974 974
          ++index;
975 975
        }
976 976

	
977 977
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
978 978
          std::map<std::string, int>::iterator jt =
979 979
            maps.find(_arc_maps[i].first);
980 980
          if (jt == maps.end()) {
981 981
            std::ostringstream msg;
982 982
            msg << "Map not found: " << _arc_maps[i].first;
983 983
            throw FormatError(msg.str());
984 984
          }
985 985
          map_index[i] = jt->second;
986 986
        }
987 987

	
988 988
        {
989 989
          std::map<std::string, int>::iterator jt = maps.find("label");
990 990
          if (jt != maps.end()) {
991 991
            label_index = jt->second;
992 992
          } else {
993 993
            label_index = -1;
994 994
          }
995 995
        }
996 996
        map_num = maps.size();
997 997
      }
998 998

	
999 999
      while (readLine() && line >> c && c != '@') {
1000 1000
        line.putback(c);
1001 1001

	
1002 1002
        std::string source_token;
1003 1003
        std::string target_token;
1004 1004

	
1005 1005
        if (!_reader_bits::readToken(line, source_token))
1006 1006
          throw FormatError("Source not found");
1007 1007

	
1008 1008
        if (!_reader_bits::readToken(line, target_token))
1009 1009
          throw FormatError("Target not found");
1010 1010

	
1011 1011
        std::vector<std::string> tokens(map_num);
1012 1012
        for (int i = 0; i < map_num; ++i) {
1013 1013
          if (!_reader_bits::readToken(line, tokens[i])) {
1014 1014
            std::ostringstream msg;
1015 1015
            msg << "Column not found (" << i + 1 << ")";
1016 1016
            throw FormatError(msg.str());
1017 1017
          }
1018 1018
        }
1019 1019
        if (line >> std::ws >> c)
1020 1020
          throw FormatError("Extra character at the end of line");
1021 1021

	
1022 1022
        Arc a;
1023 1023
        if (!_use_arcs) {
1024 1024

	
1025 1025
          typename NodeIndex::iterator it;
1026 1026

	
1027 1027
          it = _node_index.find(source_token);
1028 1028
          if (it == _node_index.end()) {
1029 1029
            std::ostringstream msg;
1030 1030
            msg << "Item not found: " << source_token;
1031 1031
            throw FormatError(msg.str());
1032 1032
          }
1033 1033
          Node source = it->second;
1034 1034

	
1035 1035
          it = _node_index.find(target_token);
1036 1036
          if (it == _node_index.end()) {
1037 1037
            std::ostringstream msg;
1038 1038
            msg << "Item not found: " << target_token;
1039 1039
            throw FormatError(msg.str());
1040 1040
          }
1041 1041
          Node target = it->second;
1042 1042

	
1043 1043
          a = _digraph.addArc(source, target);
1044 1044
          if (label_index != -1)
1045 1045
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1046 1046
        } else {
1047 1047
          if (label_index == -1)
1048 1048
            throw FormatError("Label map not found");
1049 1049
          typename std::map<std::string, Arc>::iterator it =
1050 1050
            _arc_index.find(tokens[label_index]);
1051 1051
          if (it == _arc_index.end()) {
1052 1052
            std::ostringstream msg;
1053 1053
            msg << "Arc with label not found: " << tokens[label_index];
1054 1054
            throw FormatError(msg.str());
1055 1055
          }
1056 1056
          a = it->second;
1057 1057
        }
1058 1058

	
1059 1059
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1060 1060
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1061 1061
        }
1062 1062

	
1063 1063
      }
1064 1064
      if (readSuccess()) {
1065 1065
        line.putback(c);
1066 1066
      }
1067 1067
    }
1068 1068

	
1069 1069
    void readAttributes() {
1070 1070

	
1071 1071
      std::set<std::string> read_attr;
1072 1072

	
1073 1073
      char c;
1074 1074
      while (readLine() && line >> c && c != '@') {
1075 1075
        line.putback(c);
1076 1076

	
1077 1077
        std::string attr, token;
1078 1078
        if (!_reader_bits::readToken(line, attr))
1079 1079
          throw FormatError("Attribute name not found");
1080 1080
        if (!_reader_bits::readToken(line, token))
1081 1081
          throw FormatError("Attribute value not found");
1082 1082
        if (line >> c)
1083 1083
          throw FormatError("Extra character at the end of line");
1084 1084

	
1085 1085
        {
1086 1086
          std::set<std::string>::iterator it = read_attr.find(attr);
1087 1087
          if (it != read_attr.end()) {
1088 1088
            std::ostringstream msg;
1089 1089
            msg << "Multiple occurence of attribute: " << attr;
1090 1090
            throw FormatError(msg.str());
1091 1091
          }
1092 1092
          read_attr.insert(attr);
1093 1093
        }
1094 1094

	
1095 1095
        {
1096 1096
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1097 1097
          while (it != _attributes.end() && it->first == attr) {
1098 1098
            it->second->set(token);
1099 1099
            ++it;
1100 1100
          }
1101 1101
        }
1102 1102

	
1103 1103
      }
1104 1104
      if (readSuccess()) {
1105 1105
        line.putback(c);
1106 1106
      }
1107 1107
      for (typename Attributes::iterator it = _attributes.begin();
1108 1108
           it != _attributes.end(); ++it) {
1109 1109
        if (read_attr.find(it->first) == read_attr.end()) {
1110 1110
          std::ostringstream msg;
1111 1111
          msg << "Attribute not found: " << it->first;
1112 1112
          throw FormatError(msg.str());
1113 1113
        }
1114 1114
      }
1115 1115
    }
1116 1116

	
1117 1117
  public:
1118 1118

	
1119
    /// \name Execution of the reader
1119
    /// \name Execution of the Reader
1120 1120
    /// @{
1121 1121

	
1122 1122
    /// \brief Start the batch processing
1123 1123
    ///
1124 1124
    /// This function starts the batch processing
1125 1125
    void run() {
1126 1126
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1127 1127

	
1128 1128
      bool nodes_done = _skip_nodes;
1129 1129
      bool arcs_done = _skip_arcs;
1130 1130
      bool attributes_done = false;
1131 1131

	
1132 1132
      line_num = 0;
1133 1133
      readLine();
1134 1134
      skipSection();
1135 1135

	
1136 1136
      while (readSuccess()) {
1137 1137
        try {
1138 1138
          char c;
1139 1139
          std::string section, caption;
1140 1140
          line >> c;
1141 1141
          _reader_bits::readToken(line, section);
1142 1142
          _reader_bits::readToken(line, caption);
1143 1143

	
1144 1144
          if (line >> c)
1145 1145
            throw FormatError("Extra character at the end of line");
1146 1146

	
1147 1147
          if (section == "nodes" && !nodes_done) {
1148 1148
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1149 1149
              readNodes();
1150 1150
              nodes_done = true;
1151 1151
            }
1152 1152
          } else if ((section == "arcs" || section == "edges") &&
1153 1153
                     !arcs_done) {
1154 1154
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1155 1155
              readArcs();
1156 1156
              arcs_done = true;
1157 1157
            }
1158 1158
          } else if (section == "attributes" && !attributes_done) {
1159 1159
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1160 1160
              readAttributes();
1161 1161
              attributes_done = true;
1162 1162
            }
1163 1163
          } else {
1164 1164
            readLine();
1165 1165
            skipSection();
1166 1166
          }
1167 1167
        } catch (FormatError& error) {
1168 1168
          error.line(line_num);
1169 1169
          error.file(_filename);
1170 1170
          throw;
1171 1171
        }
1172 1172
      }
1173 1173

	
1174 1174
      if (!nodes_done) {
1175 1175
        throw FormatError("Section @nodes not found");
1176 1176
      }
1177 1177

	
1178 1178
      if (!arcs_done) {
1179 1179
        throw FormatError("Section @arcs not found");
1180 1180
      }
1181 1181

	
1182 1182
      if (!attributes_done && !_attributes.empty()) {
1183 1183
        throw FormatError("Section @attributes not found");
1184 1184
      }
1185 1185

	
1186 1186
    }
1187 1187

	
1188 1188
    /// @}
1189 1189

	
1190 1190
  };
1191 1191

	
1192 1192
  /// \brief Return a \ref DigraphReader class
1193 1193
  ///
1194 1194
  /// This function just returns a \ref DigraphReader class.
1195 1195
  /// \relates DigraphReader
1196 1196
  template <typename Digraph>
1197 1197
  DigraphReader<Digraph> digraphReader(Digraph& digraph, std::istream& is) {
1198 1198
    DigraphReader<Digraph> tmp(digraph, is);
1199 1199
    return tmp;
1200 1200
  }
1201 1201

	
1202 1202
  /// \brief Return a \ref DigraphReader class
1203 1203
  ///
1204 1204
  /// This function just returns a \ref DigraphReader class.
1205 1205
  /// \relates DigraphReader
1206 1206
  template <typename Digraph>
1207 1207
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
1208 1208
                                       const std::string& fn) {
1209 1209
    DigraphReader<Digraph> tmp(digraph, fn);
1210 1210
    return tmp;
1211 1211
  }
1212 1212

	
1213 1213
  /// \brief Return a \ref DigraphReader class
1214 1214
  ///
1215 1215
  /// This function just returns a \ref DigraphReader class.
1216 1216
  /// \relates DigraphReader
1217 1217
  template <typename Digraph>
1218 1218
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
1219 1219
    DigraphReader<Digraph> tmp(digraph, fn);
1220 1220
    return tmp;
1221 1221
  }
1222 1222

	
1223 1223
  template <typename Graph>
1224 1224
  class GraphReader;
1225 1225
 
1226 1226
  template <typename Graph>
1227 1227
  GraphReader<Graph> graphReader(Graph& graph, 
1228 1228
                                 std::istream& is = std::cin);
1229 1229
  template <typename Graph>
1230 1230
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1231 1231
  template <typename Graph>
1232 1232
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1233 1233

	
1234 1234
  /// \ingroup lemon_io
1235 1235
  ///
1236 1236
  /// \brief \ref lgf-format "LGF" reader for undirected graphs
1237 1237
  ///
1238 1238
  /// This utility reads an \ref lgf-format "LGF" file.
1239 1239
  ///
1240 1240
  /// It can be used almost the same way as \c DigraphReader.
1241 1241
  /// The only difference is that this class can handle edges and
1242 1242
  /// edge maps as well as arcs and arc maps.
1243 1243
  ///
1244 1244
  /// The columns in the \c \@edges (or \c \@arcs) section are the
1245 1245
  /// edge maps. However, if there are two maps with the same name
1246 1246
  /// prefixed with \c '+' and \c '-', then these can be read into an
1247 1247
  /// arc map.  Similarly, an attribute can be read into an arc, if
1248 1248
  /// it's value is an edge label prefixed with \c '+' or \c '-'.
1249 1249
  template <typename GR>
1250 1250
  class GraphReader {
1251 1251
  public:
1252 1252

	
1253 1253
    typedef GR Graph;
1254 1254

	
1255 1255
  private:
1256 1256

	
1257 1257
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1258 1258

	
1259 1259
    std::istream* _is;
1260 1260
    bool local_is;
1261 1261
    std::string _filename;
1262 1262

	
1263 1263
    Graph& _graph;
1264 1264

	
1265 1265
    std::string _nodes_caption;
1266 1266
    std::string _edges_caption;
1267 1267
    std::string _attributes_caption;
1268 1268

	
1269 1269
    typedef std::map<std::string, Node> NodeIndex;
1270 1270
    NodeIndex _node_index;
1271 1271
    typedef std::map<std::string, Edge> EdgeIndex;
1272 1272
    EdgeIndex _edge_index;
1273 1273

	
1274 1274
    typedef std::vector<std::pair<std::string,
1275 1275
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1276 1276
    NodeMaps _node_maps;
1277 1277

	
1278 1278
    typedef std::vector<std::pair<std::string,
1279 1279
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1280 1280
    EdgeMaps _edge_maps;
1281 1281

	
1282 1282
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1283 1283
      Attributes;
1284 1284
    Attributes _attributes;
1285 1285

	
1286 1286
    bool _use_nodes;
1287 1287
    bool _use_edges;
1288 1288

	
1289 1289
    bool _skip_nodes;
1290 1290
    bool _skip_edges;
1291 1291

	
1292 1292
    int line_num;
1293 1293
    std::istringstream line;
1294 1294

	
1295 1295
  public:
1296 1296

	
1297 1297
    /// \brief Constructor
1298 1298
    ///
1299 1299
    /// Construct an undirected graph reader, which reads from the given
1300 1300
    /// input stream.
1301 1301
    GraphReader(Graph& graph, std::istream& is = std::cin)
1302 1302
      : _is(&is), local_is(false), _graph(graph),
1303 1303
        _use_nodes(false), _use_edges(false),
1304 1304
        _skip_nodes(false), _skip_edges(false) {}
1305 1305

	
1306 1306
    /// \brief Constructor
1307 1307
    ///
1308 1308
    /// Construct an undirected graph reader, which reads from the given
1309 1309
    /// file.
1310 1310
    GraphReader(Graph& graph, const std::string& fn)
1311 1311
      : _is(new std::ifstream(fn.c_str())), local_is(true),
1312 1312
        _filename(fn), _graph(graph),
1313 1313
        _use_nodes(false), _use_edges(false),
1314 1314
        _skip_nodes(false), _skip_edges(false) {
1315 1315
      if (!(*_is)) {
1316 1316
        delete _is;
1317 1317
        throw IoError("Cannot open file", fn);
1318 1318
      }
1319 1319
    }
1320 1320

	
1321 1321
    /// \brief Constructor
1322 1322
    ///
1323 1323
    /// Construct an undirected graph reader, which reads from the given
1324 1324
    /// file.
1325 1325
    GraphReader(Graph& graph, const char* fn)
1326 1326
      : _is(new std::ifstream(fn)), local_is(true),
1327 1327
        _filename(fn), _graph(graph),
1328 1328
        _use_nodes(false), _use_edges(false),
1329 1329
        _skip_nodes(false), _skip_edges(false) {
1330 1330
      if (!(*_is)) {
1331 1331
        delete _is;
1332 1332
        throw IoError("Cannot open file", fn);
1333 1333
      }
1334 1334
    }
1335 1335

	
1336 1336
    /// \brief Destructor
1337 1337
    ~GraphReader() {
1338 1338
      for (typename NodeMaps::iterator it = _node_maps.begin();
1339 1339
           it != _node_maps.end(); ++it) {
1340 1340
        delete it->second;
1341 1341
      }
1342 1342

	
1343 1343
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1344 1344
           it != _edge_maps.end(); ++it) {
1345 1345
        delete it->second;
1346 1346
      }
1347 1347

	
1348 1348
      for (typename Attributes::iterator it = _attributes.begin();
1349 1349
           it != _attributes.end(); ++it) {
1350 1350
        delete it->second;
1351 1351
      }
1352 1352

	
1353 1353
      if (local_is) {
1354 1354
        delete _is;
1355 1355
      }
1356 1356

	
1357 1357
    }
1358 1358

	
1359 1359
  private:
1360 1360
    template <typename Graph>
1361 1361
    friend GraphReader<Graph> graphReader(Graph& graph, std::istream& is);
1362 1362
    template <typename Graph>
1363 1363
    friend GraphReader<Graph> graphReader(Graph& graph, const std::string& fn); 
1364 1364
    template <typename Graph>
1365 1365
    friend GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1366 1366

	
1367 1367
    GraphReader(GraphReader& other)
1368 1368
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1369 1369
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1370 1370
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1371 1371

	
1372 1372
      other._is = 0;
1373 1373
      other.local_is = false;
1374 1374

	
1375 1375
      _node_index.swap(other._node_index);
1376 1376
      _edge_index.swap(other._edge_index);
1377 1377

	
1378 1378
      _node_maps.swap(other._node_maps);
1379 1379
      _edge_maps.swap(other._edge_maps);
1380 1380
      _attributes.swap(other._attributes);
1381 1381

	
1382 1382
      _nodes_caption = other._nodes_caption;
1383 1383
      _edges_caption = other._edges_caption;
1384 1384
      _attributes_caption = other._attributes_caption;
1385 1385

	
1386 1386
    }
1387 1387

	
1388 1388
    GraphReader& operator=(const GraphReader&);
1389 1389

	
1390 1390
  public:
1391 1391

	
1392
    /// \name Reading rules
1392
    /// \name Reading Rules
1393 1393
    /// @{
1394 1394

	
1395 1395
    /// \brief Node map reading rule
1396 1396
    ///
1397 1397
    /// Add a node map reading rule to the reader.
1398 1398
    template <typename Map>
1399 1399
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1400 1400
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1401 1401
      _reader_bits::MapStorageBase<Node>* storage =
1402 1402
        new _reader_bits::MapStorage<Node, Map>(map);
1403 1403
      _node_maps.push_back(std::make_pair(caption, storage));
1404 1404
      return *this;
1405 1405
    }
1406 1406

	
1407 1407
    /// \brief Node map reading rule
1408 1408
    ///
1409 1409
    /// Add a node map reading rule with specialized converter to the
1410 1410
    /// reader.
1411 1411
    template <typename Map, typename Converter>
1412 1412
    GraphReader& nodeMap(const std::string& caption, Map& map,
1413 1413
                           const Converter& converter = Converter()) {
1414 1414
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1415 1415
      _reader_bits::MapStorageBase<Node>* storage =
1416 1416
        new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1417 1417
      _node_maps.push_back(std::make_pair(caption, storage));
1418 1418
      return *this;
1419 1419
    }
1420 1420

	
1421 1421
    /// \brief Edge map reading rule
1422 1422
    ///
1423 1423
    /// Add an edge map reading rule to the reader.
1424 1424
    template <typename Map>
1425 1425
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1426 1426
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1427 1427
      _reader_bits::MapStorageBase<Edge>* storage =
1428 1428
        new _reader_bits::MapStorage<Edge, Map>(map);
1429 1429
      _edge_maps.push_back(std::make_pair(caption, storage));
1430 1430
      return *this;
1431 1431
    }
1432 1432

	
1433 1433
    /// \brief Edge map reading rule
1434 1434
    ///
1435 1435
    /// Add an edge map reading rule with specialized converter to the
1436 1436
    /// reader.
1437 1437
    template <typename Map, typename Converter>
1438 1438
    GraphReader& edgeMap(const std::string& caption, Map& map,
1439 1439
                          const Converter& converter = Converter()) {
1440 1440
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1441 1441
      _reader_bits::MapStorageBase<Edge>* storage =
1442 1442
        new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1443 1443
      _edge_maps.push_back(std::make_pair(caption, storage));
1444 1444
      return *this;
1445 1445
    }
1446 1446

	
1447 1447
    /// \brief Arc map reading rule
1448 1448
    ///
1449 1449
    /// Add an arc map reading rule to the reader.
1450 1450
    template <typename Map>
1451 1451
    GraphReader& arcMap(const std::string& caption, Map& map) {
1452 1452
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1453 1453
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1454 1454
        new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1455 1455
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1456 1456
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1457 1457
        new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1458 1458
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1459 1459
      return *this;
1460 1460
    }
1461 1461

	
1462 1462
    /// \brief Arc map reading rule
1463 1463
    ///
1464 1464
    /// Add an arc map reading rule with specialized converter to the
1465 1465
    /// reader.
1466 1466
    template <typename Map, typename Converter>
1467 1467
    GraphReader& arcMap(const std::string& caption, Map& map,
1468 1468
                          const Converter& converter = Converter()) {
1469 1469
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1470 1470
      _reader_bits::MapStorageBase<Edge>* forward_storage =
1471 1471
        new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1472 1472
        (_graph, map, converter);
1473 1473
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1474 1474
      _reader_bits::MapStorageBase<Edge>* backward_storage =
1475 1475
        new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1476 1476
        (_graph, map, converter);
1477 1477
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1478 1478
      return *this;
1479 1479
    }
1480 1480

	
1481 1481
    /// \brief Attribute reading rule
1482 1482
    ///
1483 1483
    /// Add an attribute reading rule to the reader.
1484 1484
    template <typename Value>
1485 1485
    GraphReader& attribute(const std::string& caption, Value& value) {
1486 1486
      _reader_bits::ValueStorageBase* storage =
1487 1487
        new _reader_bits::ValueStorage<Value>(value);
1488 1488
      _attributes.insert(std::make_pair(caption, storage));
1489 1489
      return *this;
1490 1490
    }
1491 1491

	
1492 1492
    /// \brief Attribute reading rule
1493 1493
    ///
1494 1494
    /// Add an attribute reading rule with specialized converter to the
1495 1495
    /// reader.
1496 1496
    template <typename Value, typename Converter>
1497 1497
    GraphReader& attribute(const std::string& caption, Value& value,
1498 1498
                             const Converter& converter = Converter()) {
1499 1499
      _reader_bits::ValueStorageBase* storage =
1500 1500
        new _reader_bits::ValueStorage<Value, Converter>(value, converter);
1501 1501
      _attributes.insert(std::make_pair(caption, storage));
1502 1502
      return *this;
1503 1503
    }
1504 1504

	
1505 1505
    /// \brief Node reading rule
1506 1506
    ///
1507 1507
    /// Add a node reading rule to reader.
1508 1508
    GraphReader& node(const std::string& caption, Node& node) {
1509 1509
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
1510 1510
      Converter converter(_node_index);
1511 1511
      _reader_bits::ValueStorageBase* storage =
1512 1512
        new _reader_bits::ValueStorage<Node, Converter>(node, converter);
1513 1513
      _attributes.insert(std::make_pair(caption, storage));
1514 1514
      return *this;
1515 1515
    }
1516 1516

	
1517 1517
    /// \brief Edge reading rule
1518 1518
    ///
1519 1519
    /// Add an edge reading rule to reader.
1520 1520
    GraphReader& edge(const std::string& caption, Edge& edge) {
1521 1521
      typedef _reader_bits::MapLookUpConverter<Edge> Converter;
1522 1522
      Converter converter(_edge_index);
1523 1523
      _reader_bits::ValueStorageBase* storage =
1524 1524
        new _reader_bits::ValueStorage<Edge, Converter>(edge, converter);
1525 1525
      _attributes.insert(std::make_pair(caption, storage));
1526 1526
      return *this;
1527 1527
    }
1528 1528

	
1529 1529
    /// \brief Arc reading rule
1530 1530
    ///
1531 1531
    /// Add an arc reading rule to reader.
1532 1532
    GraphReader& arc(const std::string& caption, Arc& arc) {
1533 1533
      typedef _reader_bits::GraphArcLookUpConverter<Graph> Converter;
1534 1534
      Converter converter(_graph, _edge_index);
1535 1535
      _reader_bits::ValueStorageBase* storage =
1536 1536
        new _reader_bits::ValueStorage<Arc, Converter>(arc, converter);
1537 1537
      _attributes.insert(std::make_pair(caption, storage));
1538 1538
      return *this;
1539 1539
    }
1540 1540

	
1541 1541
    /// @}
1542 1542

	
1543
    /// \name Select section by name
1543
    /// \name Select Section by Name
1544 1544
    /// @{
1545 1545

	
1546 1546
    /// \brief Set \c \@nodes section to be read
1547 1547
    ///
1548 1548
    /// Set \c \@nodes section to be read.
1549 1549
    GraphReader& nodes(const std::string& caption) {
1550 1550
      _nodes_caption = caption;
1551 1551
      return *this;
1552 1552
    }
1553 1553

	
1554 1554
    /// \brief Set \c \@edges section to be read
1555 1555
    ///
1556 1556
    /// Set \c \@edges section to be read.
1557 1557
    GraphReader& edges(const std::string& caption) {
1558 1558
      _edges_caption = caption;
1559 1559
      return *this;
1560 1560
    }
1561 1561

	
1562 1562
    /// \brief Set \c \@attributes section to be read
1563 1563
    ///
1564 1564
    /// Set \c \@attributes section to be read.
1565 1565
    GraphReader& attributes(const std::string& caption) {
1566 1566
      _attributes_caption = caption;
1567 1567
      return *this;
1568 1568
    }
1569 1569

	
1570 1570
    /// @}
1571 1571

	
1572
    /// \name Using previously constructed node or edge set
1572
    /// \name Using Previously Constructed Node or Edge Set
1573 1573
    /// @{
1574 1574

	
1575 1575
    /// \brief Use previously constructed node set
1576 1576
    ///
1577 1577
    /// Use previously constructed node set, and specify the node
1578 1578
    /// label map.
1579 1579
    template <typename Map>
1580 1580
    GraphReader& useNodes(const Map& map) {
1581 1581
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1582 1582
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1583 1583
      _use_nodes = true;
1584 1584
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1585 1585
      for (NodeIt n(_graph); n != INVALID; ++n) {
1586 1586
        _node_index.insert(std::make_pair(converter(map[n]), n));
1587 1587
      }
1588 1588
      return *this;
1589 1589
    }
1590 1590

	
1591 1591
    /// \brief Use previously constructed node set
1592 1592
    ///
1593 1593
    /// Use previously constructed node set, and specify the node
1594 1594
    /// label map and a functor which converts the label map values to
1595 1595
    /// \c std::string.
1596 1596
    template <typename Map, typename Converter>
1597 1597
    GraphReader& useNodes(const Map& map,
1598 1598
                            const Converter& converter = Converter()) {
1599 1599
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1600 1600
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
1601 1601
      _use_nodes = true;
1602 1602
      for (NodeIt n(_graph); n != INVALID; ++n) {
1603 1603
        _node_index.insert(std::make_pair(converter(map[n]), n));
1604 1604
      }
1605 1605
      return *this;
1606 1606
    }
1607 1607

	
1608 1608
    /// \brief Use previously constructed edge set
1609 1609
    ///
1610 1610
    /// Use previously constructed edge set, and specify the edge
1611 1611
    /// label map.
1612 1612
    template <typename Map>
1613 1613
    GraphReader& useEdges(const Map& map) {
1614 1614
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1615 1615
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1616 1616
      _use_edges = true;
1617 1617
      _writer_bits::DefaultConverter<typename Map::Value> converter;
1618 1618
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1619 1619
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1620 1620
      }
1621 1621
      return *this;
1622 1622
    }
1623 1623

	
1624 1624
    /// \brief Use previously constructed edge set
1625 1625
    ///
1626 1626
    /// Use previously constructed edge set, and specify the edge
1627 1627
    /// label map and a functor which converts the label map values to
1628 1628
    /// \c std::string.
1629 1629
    template <typename Map, typename Converter>
1630 1630
    GraphReader& useEdges(const Map& map,
1631 1631
                            const Converter& converter = Converter()) {
1632 1632
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1633 1633
      LEMON_ASSERT(!_use_edges, "Multiple usage of useEdges() member");
1634 1634
      _use_edges = true;
1635 1635
      for (EdgeIt a(_graph); a != INVALID; ++a) {
1636 1636
        _edge_index.insert(std::make_pair(converter(map[a]), a));
1637 1637
      }
1638 1638
      return *this;
1639 1639
    }
1640 1640

	
1641 1641
    /// \brief Skip the reading of node section
1642 1642
    ///
1643 1643
    /// Omit the reading of the node section. This implies that each node
1644 1644
    /// map reading rule will be abandoned, and the nodes of the graph
1645 1645
    /// will not be constructed, which usually cause that the edge set
1646 1646
    /// could not be read due to lack of node name
1647 1647
    /// could not be read due to lack of node name resolving.
1648 1648
    /// Therefore \c skipEdges() function should also be used, or
1649 1649
    /// \c useNodes() should be used to specify the label of the nodes.
1650 1650
    GraphReader& skipNodes() {
1651 1651
      LEMON_ASSERT(!_skip_nodes, "Skip nodes already set");
1652 1652
      _skip_nodes = true;
1653 1653
      return *this;
1654 1654
    }
1655 1655

	
1656 1656
    /// \brief Skip the reading of edge section
1657 1657
    ///
1658 1658
    /// Omit the reading of the edge section. This implies that each edge
1659 1659
    /// map reading rule will be abandoned, and the edges of the graph
1660 1660
    /// will not be constructed.
1661 1661
    GraphReader& skipEdges() {
1662 1662
      LEMON_ASSERT(!_skip_edges, "Skip edges already set");
1663 1663
      _skip_edges = true;
1664 1664
      return *this;
1665 1665
    }
1666 1666

	
1667 1667
    /// @}
1668 1668

	
1669 1669
  private:
1670 1670

	
1671 1671
    bool readLine() {
1672 1672
      std::string str;
1673 1673
      while(++line_num, std::getline(*_is, str)) {
1674 1674
        line.clear(); line.str(str);
1675 1675
        char c;
1676 1676
        if (line >> std::ws >> c && c != '#') {
1677 1677
          line.putback(c);
1678 1678
          return true;
1679 1679
        }
1680 1680
      }
1681 1681
      return false;
1682 1682
    }
1683 1683

	
1684 1684
    bool readSuccess() {
1685 1685
      return static_cast<bool>(*_is);
1686 1686
    }
1687 1687

	
1688 1688
    void skipSection() {
1689 1689
      char c;
1690 1690
      while (readSuccess() && line >> c && c != '@') {
1691 1691
        readLine();
1692 1692
      }
1693 1693
      if (readSuccess()) {
1694 1694
        line.putback(c);
1695 1695
      }
1696 1696
    }
1697 1697

	
1698 1698
    void readNodes() {
1699 1699

	
1700 1700
      std::vector<int> map_index(_node_maps.size());
1701 1701
      int map_num, label_index;
1702 1702

	
1703 1703
      char c;
1704 1704
      if (!readLine() || !(line >> c) || c == '@') {
1705 1705
        if (readSuccess() && line) line.putback(c);
1706 1706
        if (!_node_maps.empty())
1707 1707
          throw FormatError("Cannot find map names");
1708 1708
        return;
1709 1709
      }
1710 1710
      line.putback(c);
1711 1711

	
1712 1712
      {
1713 1713
        std::map<std::string, int> maps;
1714 1714

	
1715 1715
        std::string map;
1716 1716
        int index = 0;
1717 1717
        while (_reader_bits::readToken(line, map)) {
1718 1718
          if (maps.find(map) != maps.end()) {
1719 1719
            std::ostringstream msg;
1720 1720
            msg << "Multiple occurence of node map: " << map;
1721 1721
            throw FormatError(msg.str());
1722 1722
          }
1723 1723
          maps.insert(std::make_pair(map, index));
1724 1724
          ++index;
1725 1725
        }
1726 1726

	
1727 1727
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1728 1728
          std::map<std::string, int>::iterator jt =
1729 1729
            maps.find(_node_maps[i].first);
1730 1730
          if (jt == maps.end()) {
1731 1731
            std::ostringstream msg;
1732 1732
            msg << "Map not found: " << _node_maps[i].first;
1733 1733
            throw FormatError(msg.str());
1734 1734
          }
1735 1735
          map_index[i] = jt->second;
1736 1736
        }
1737 1737

	
1738 1738
        {
1739 1739
          std::map<std::string, int>::iterator jt = maps.find("label");
1740 1740
          if (jt != maps.end()) {
1741 1741
            label_index = jt->second;
1742 1742
          } else {
1743 1743
            label_index = -1;
1744 1744
          }
1745 1745
        }
1746 1746
        map_num = maps.size();
1747 1747
      }
1748 1748

	
1749 1749
      while (readLine() && line >> c && c != '@') {
1750 1750
        line.putback(c);
1751 1751

	
1752 1752
        std::vector<std::string> tokens(map_num);
1753 1753
        for (int i = 0; i < map_num; ++i) {
1754 1754
          if (!_reader_bits::readToken(line, tokens[i])) {
1755 1755
            std::ostringstream msg;
1756 1756
            msg << "Column not found (" << i + 1 << ")";
1757 1757
            throw FormatError(msg.str());
1758 1758
          }
1759 1759
        }
1760 1760
        if (line >> std::ws >> c)
1761 1761
          throw FormatError("Extra character at the end of line");
1762 1762

	
1763 1763
        Node n;
1764 1764
        if (!_use_nodes) {
... ...
@@ -1770,906 +1770,906 @@
1770 1770
            throw FormatError("Label map not found");
1771 1771
          typename std::map<std::string, Node>::iterator it =
1772 1772
            _node_index.find(tokens[label_index]);
1773 1773
          if (it == _node_index.end()) {
1774 1774
            std::ostringstream msg;
1775 1775
            msg << "Node with label not found: " << tokens[label_index];
1776 1776
            throw FormatError(msg.str());
1777 1777
          }
1778 1778
          n = it->second;
1779 1779
        }
1780 1780

	
1781 1781
        for (int i = 0; i < static_cast<int>(_node_maps.size()); ++i) {
1782 1782
          _node_maps[i].second->set(n, tokens[map_index[i]]);
1783 1783
        }
1784 1784

	
1785 1785
      }
1786 1786
      if (readSuccess()) {
1787 1787
        line.putback(c);
1788 1788
      }
1789 1789
    }
1790 1790

	
1791 1791
    void readEdges() {
1792 1792

	
1793 1793
      std::vector<int> map_index(_edge_maps.size());
1794 1794
      int map_num, label_index;
1795 1795

	
1796 1796
      char c;
1797 1797
      if (!readLine() || !(line >> c) || c == '@') {
1798 1798
        if (readSuccess() && line) line.putback(c);
1799 1799
        if (!_edge_maps.empty())
1800 1800
          throw FormatError("Cannot find map names");
1801 1801
        return;
1802 1802
      }
1803 1803
      line.putback(c);
1804 1804

	
1805 1805
      {
1806 1806
        std::map<std::string, int> maps;
1807 1807

	
1808 1808
        std::string map;
1809 1809
        int index = 0;
1810 1810
        while (_reader_bits::readToken(line, map)) {
1811 1811
          if (maps.find(map) != maps.end()) {
1812 1812
            std::ostringstream msg;
1813 1813
            msg << "Multiple occurence of edge map: " << map;
1814 1814
            throw FormatError(msg.str());
1815 1815
          }
1816 1816
          maps.insert(std::make_pair(map, index));
1817 1817
          ++index;
1818 1818
        }
1819 1819

	
1820 1820
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1821 1821
          std::map<std::string, int>::iterator jt =
1822 1822
            maps.find(_edge_maps[i].first);
1823 1823
          if (jt == maps.end()) {
1824 1824
            std::ostringstream msg;
1825 1825
            msg << "Map not found: " << _edge_maps[i].first;
1826 1826
            throw FormatError(msg.str());
1827 1827
          }
1828 1828
          map_index[i] = jt->second;
1829 1829
        }
1830 1830

	
1831 1831
        {
1832 1832
          std::map<std::string, int>::iterator jt = maps.find("label");
1833 1833
          if (jt != maps.end()) {
1834 1834
            label_index = jt->second;
1835 1835
          } else {
1836 1836
            label_index = -1;
1837 1837
          }
1838 1838
        }
1839 1839
        map_num = maps.size();
1840 1840
      }
1841 1841

	
1842 1842
      while (readLine() && line >> c && c != '@') {
1843 1843
        line.putback(c);
1844 1844

	
1845 1845
        std::string source_token;
1846 1846
        std::string target_token;
1847 1847

	
1848 1848
        if (!_reader_bits::readToken(line, source_token))
1849 1849
          throw FormatError("Node u not found");
1850 1850

	
1851 1851
        if (!_reader_bits::readToken(line, target_token))
1852 1852
          throw FormatError("Node v not found");
1853 1853

	
1854 1854
        std::vector<std::string> tokens(map_num);
1855 1855
        for (int i = 0; i < map_num; ++i) {
1856 1856
          if (!_reader_bits::readToken(line, tokens[i])) {
1857 1857
            std::ostringstream msg;
1858 1858
            msg << "Column not found (" << i + 1 << ")";
1859 1859
            throw FormatError(msg.str());
1860 1860
          }
1861 1861
        }
1862 1862
        if (line >> std::ws >> c)
1863 1863
          throw FormatError("Extra character at the end of line");
1864 1864

	
1865 1865
        Edge e;
1866 1866
        if (!_use_edges) {
1867 1867

	
1868 1868
          typename NodeIndex::iterator it;
1869 1869

	
1870 1870
          it = _node_index.find(source_token);
1871 1871
          if (it == _node_index.end()) {
1872 1872
            std::ostringstream msg;
1873 1873
            msg << "Item not found: " << source_token;
1874 1874
            throw FormatError(msg.str());
1875 1875
          }
1876 1876
          Node source = it->second;
1877 1877

	
1878 1878
          it = _node_index.find(target_token);
1879 1879
          if (it == _node_index.end()) {
1880 1880
            std::ostringstream msg;
1881 1881
            msg << "Item not found: " << target_token;
1882 1882
            throw FormatError(msg.str());
1883 1883
          }
1884 1884
          Node target = it->second;
1885 1885

	
1886 1886
          e = _graph.addEdge(source, target);
1887 1887
          if (label_index != -1)
1888 1888
            _edge_index.insert(std::make_pair(tokens[label_index], e));
1889 1889
        } else {
1890 1890
          if (label_index == -1)
1891 1891
            throw FormatError("Label map not found");
1892 1892
          typename std::map<std::string, Edge>::iterator it =
1893 1893
            _edge_index.find(tokens[label_index]);
1894 1894
          if (it == _edge_index.end()) {
1895 1895
            std::ostringstream msg;
1896 1896
            msg << "Edge with label not found: " << tokens[label_index];
1897 1897
            throw FormatError(msg.str());
1898 1898
          }
1899 1899
          e = it->second;
1900 1900
        }
1901 1901

	
1902 1902
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1903 1903
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1904 1904
        }
1905 1905

	
1906 1906
      }
1907 1907
      if (readSuccess()) {
1908 1908
        line.putback(c);
1909 1909
      }
1910 1910
    }
1911 1911

	
1912 1912
    void readAttributes() {
1913 1913

	
1914 1914
      std::set<std::string> read_attr;
1915 1915

	
1916 1916
      char c;
1917 1917
      while (readLine() && line >> c && c != '@') {
1918 1918
        line.putback(c);
1919 1919

	
1920 1920
        std::string attr, token;
1921 1921
        if (!_reader_bits::readToken(line, attr))
1922 1922
          throw FormatError("Attribute name not found");
1923 1923
        if (!_reader_bits::readToken(line, token))
1924 1924
          throw FormatError("Attribute value not found");
1925 1925
        if (line >> c)
1926 1926
          throw FormatError("Extra character at the end of line");
1927 1927

	
1928 1928
        {
1929 1929
          std::set<std::string>::iterator it = read_attr.find(attr);
1930 1930
          if (it != read_attr.end()) {
1931 1931
            std::ostringstream msg;
1932 1932
            msg << "Multiple occurence of attribute: " << attr;
1933 1933
            throw FormatError(msg.str());
1934 1934
          }
1935 1935
          read_attr.insert(attr);
1936 1936
        }
1937 1937

	
1938 1938
        {
1939 1939
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1940 1940
          while (it != _attributes.end() && it->first == attr) {
1941 1941
            it->second->set(token);
1942 1942
            ++it;
1943 1943
          }
1944 1944
        }
1945 1945

	
1946 1946
      }
1947 1947
      if (readSuccess()) {
1948 1948
        line.putback(c);
1949 1949
      }
1950 1950
      for (typename Attributes::iterator it = _attributes.begin();
1951 1951
           it != _attributes.end(); ++it) {
1952 1952
        if (read_attr.find(it->first) == read_attr.end()) {
1953 1953
          std::ostringstream msg;
1954 1954
          msg << "Attribute not found: " << it->first;
1955 1955
          throw FormatError(msg.str());
1956 1956
        }
1957 1957
      }
1958 1958
    }
1959 1959

	
1960 1960
  public:
1961 1961

	
1962
    /// \name Execution of the reader
1962
    /// \name Execution of the Reader
1963 1963
    /// @{
1964 1964

	
1965 1965
    /// \brief Start the batch processing
1966 1966
    ///
1967 1967
    /// This function starts the batch processing
1968 1968
    void run() {
1969 1969

	
1970 1970
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1971 1971

	
1972 1972
      bool nodes_done = _skip_nodes;
1973 1973
      bool edges_done = _skip_edges;
1974 1974
      bool attributes_done = false;
1975 1975

	
1976 1976
      line_num = 0;
1977 1977
      readLine();
1978 1978
      skipSection();
1979 1979

	
1980 1980
      while (readSuccess()) {
1981 1981
        try {
1982 1982
          char c;
1983 1983
          std::string section, caption;
1984 1984
          line >> c;
1985 1985
          _reader_bits::readToken(line, section);
1986 1986
          _reader_bits::readToken(line, caption);
1987 1987

	
1988 1988
          if (line >> c)
1989 1989
            throw FormatError("Extra character at the end of line");
1990 1990

	
1991 1991
          if (section == "nodes" && !nodes_done) {
1992 1992
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1993 1993
              readNodes();
1994 1994
              nodes_done = true;
1995 1995
            }
1996 1996
          } else if ((section == "edges" || section == "arcs") &&
1997 1997
                     !edges_done) {
1998 1998
            if (_edges_caption.empty() || _edges_caption == caption) {
1999 1999
              readEdges();
2000 2000
              edges_done = true;
2001 2001
            }
2002 2002
          } else if (section == "attributes" && !attributes_done) {
2003 2003
            if (_attributes_caption.empty() || _attributes_caption == caption) {
2004 2004
              readAttributes();
2005 2005
              attributes_done = true;
2006 2006
            }
2007 2007
          } else {
2008 2008
            readLine();
2009 2009
            skipSection();
2010 2010
          }
2011 2011
        } catch (FormatError& error) {
2012 2012
          error.line(line_num);
2013 2013
          error.file(_filename);
2014 2014
          throw;
2015 2015
        }
2016 2016
      }
2017 2017

	
2018 2018
      if (!nodes_done) {
2019 2019
        throw FormatError("Section @nodes not found");
2020 2020
      }
2021 2021

	
2022 2022
      if (!edges_done) {
2023 2023
        throw FormatError("Section @edges not found");
2024 2024
      }
2025 2025

	
2026 2026
      if (!attributes_done && !_attributes.empty()) {
2027 2027
        throw FormatError("Section @attributes not found");
2028 2028
      }
2029 2029

	
2030 2030
    }
2031 2031

	
2032 2032
    /// @}
2033 2033

	
2034 2034
  };
2035 2035

	
2036 2036
  /// \brief Return a \ref GraphReader class
2037 2037
  ///
2038 2038
  /// This function just returns a \ref GraphReader class.
2039 2039
  /// \relates GraphReader
2040 2040
  template <typename Graph>
2041 2041
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
2042 2042
    GraphReader<Graph> tmp(graph, is);
2043 2043
    return tmp;
2044 2044
  }
2045 2045

	
2046 2046
  /// \brief Return a \ref GraphReader class
2047 2047
  ///
2048 2048
  /// This function just returns a \ref GraphReader class.
2049 2049
  /// \relates GraphReader
2050 2050
  template <typename Graph>
2051 2051
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
2052 2052
    GraphReader<Graph> tmp(graph, fn);
2053 2053
    return tmp;
2054 2054
  }
2055 2055

	
2056 2056
  /// \brief Return a \ref GraphReader class
2057 2057
  ///
2058 2058
  /// This function just returns a \ref GraphReader class.
2059 2059
  /// \relates GraphReader
2060 2060
  template <typename Graph>
2061 2061
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2062 2062
    GraphReader<Graph> tmp(graph, fn);
2063 2063
    return tmp;
2064 2064
  }
2065 2065

	
2066 2066
  class SectionReader;
2067 2067

	
2068 2068
  SectionReader sectionReader(std::istream& is);
2069 2069
  SectionReader sectionReader(const std::string& fn);
2070 2070
  SectionReader sectionReader(const char* fn);
2071 2071

	
2072 2072
  /// \ingroup lemon_io
2073 2073
  ///
2074 2074
  /// \brief Section reader class
2075 2075
  ///
2076 2076
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2077 2077
  /// which contain any data in arbitrary format. Such sections can be
2078 2078
  /// read with this class. A reading rule can be added to the class
2079 2079
  /// with two different functions. With the \c sectionLines() function a
2080 2080
  /// functor can process the section line-by-line, while with the \c
2081 2081
  /// sectionStream() member the section can be read from an input
2082 2082
  /// stream.
2083 2083
  class SectionReader {
2084 2084
  private:
2085 2085

	
2086 2086
    std::istream* _is;
2087 2087
    bool local_is;
2088 2088
    std::string _filename;
2089 2089

	
2090 2090
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2091 2091
    Sections _sections;
2092 2092

	
2093 2093
    int line_num;
2094 2094
    std::istringstream line;
2095 2095

	
2096 2096
  public:
2097 2097

	
2098 2098
    /// \brief Constructor
2099 2099
    ///
2100 2100
    /// Construct a section reader, which reads from the given input
2101 2101
    /// stream.
2102 2102
    SectionReader(std::istream& is)
2103 2103
      : _is(&is), local_is(false) {}
2104 2104

	
2105 2105
    /// \brief Constructor
2106 2106
    ///
2107 2107
    /// Construct a section reader, which reads from the given file.
2108 2108
    SectionReader(const std::string& fn)
2109 2109
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2110 2110
        _filename(fn) {
2111 2111
      if (!(*_is)) {
2112 2112
        delete _is;
2113 2113
        throw IoError("Cannot open file", fn);
2114 2114
      }
2115 2115
    }
2116 2116

	
2117 2117
    /// \brief Constructor
2118 2118
    ///
2119 2119
    /// Construct a section reader, which reads from the given file.
2120 2120
    SectionReader(const char* fn)
2121 2121
      : _is(new std::ifstream(fn)), local_is(true),
2122 2122
        _filename(fn) {
2123 2123
      if (!(*_is)) {
2124 2124
        delete _is;
2125 2125
        throw IoError("Cannot open file", fn);
2126 2126
      }
2127 2127
    }
2128 2128

	
2129 2129
    /// \brief Destructor
2130 2130
    ~SectionReader() {
2131 2131
      for (Sections::iterator it = _sections.begin();
2132 2132
           it != _sections.end(); ++it) {
2133 2133
        delete it->second;
2134 2134
      }
2135 2135

	
2136 2136
      if (local_is) {
2137 2137
        delete _is;
2138 2138
      }
2139 2139

	
2140 2140
    }
2141 2141

	
2142 2142
  private:
2143 2143

	
2144 2144
    friend SectionReader sectionReader(std::istream& is);
2145 2145
    friend SectionReader sectionReader(const std::string& fn);
2146 2146
    friend SectionReader sectionReader(const char* fn);
2147 2147

	
2148 2148
    SectionReader(SectionReader& other)
2149 2149
      : _is(other._is), local_is(other.local_is) {
2150 2150

	
2151 2151
      other._is = 0;
2152 2152
      other.local_is = false;
2153 2153

	
2154 2154
      _sections.swap(other._sections);
2155 2155
    }
2156 2156

	
2157 2157
    SectionReader& operator=(const SectionReader&);
2158 2158

	
2159 2159
  public:
2160 2160

	
2161
    /// \name Section readers
2161
    /// \name Section Readers
2162 2162
    /// @{
2163 2163

	
2164 2164
    /// \brief Add a section processor with line oriented reading
2165 2165
    ///
2166 2166
    /// The first parameter is the type descriptor of the section, the
2167 2167
    /// second is a functor, which takes just one \c std::string
2168 2168
    /// parameter. At the reading process, each line of the section
2169 2169
    /// will be given to the functor object. However, the empty lines
2170 2170
    /// and the comment lines are filtered out, and the leading
2171 2171
    /// whitespaces are trimmed from each processed string.
2172 2172
    ///
2173 2173
    /// For example let's see a section, which contain several
2174 2174
    /// integers, which should be inserted into a vector.
2175 2175
    ///\code
2176 2176
    ///  @numbers
2177 2177
    ///  12 45 23
2178 2178
    ///  4
2179 2179
    ///  23 6
2180 2180
    ///\endcode
2181 2181
    ///
2182 2182
    /// The functor is implemented as a struct:
2183 2183
    ///\code
2184 2184
    ///  struct NumberSection {
2185 2185
    ///    std::vector<int>& _data;
2186 2186
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2187 2187
    ///    void operator()(const std::string& line) {
2188 2188
    ///      std::istringstream ls(line);
2189 2189
    ///      int value;
2190 2190
    ///      while (ls >> value) _data.push_back(value);
2191 2191
    ///    }
2192 2192
    ///  };
2193 2193
    ///
2194 2194
    ///  // ...
2195 2195
    ///
2196 2196
    ///  reader.sectionLines("numbers", NumberSection(vec));
2197 2197
    ///\endcode
2198 2198
    template <typename Functor>
2199 2199
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2200 2200
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2201 2201
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2202 2202
                   "Multiple reading of section.");
2203 2203
      _sections.insert(std::make_pair(type,
2204 2204
        new _reader_bits::LineSection<Functor>(functor)));
2205 2205
      return *this;
2206 2206
    }
2207 2207

	
2208 2208

	
2209 2209
    /// \brief Add a section processor with stream oriented reading
2210 2210
    ///
2211 2211
    /// The first parameter is the type of the section, the second is
2212 2212
    /// a functor, which takes an \c std::istream& and an \c int&
2213 2213
    /// parameter, the latter regard to the line number of stream. The
2214 2214
    /// functor can read the input while the section go on, and the
2215 2215
    /// line number should be modified accordingly.
2216 2216
    template <typename Functor>
2217 2217
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2218 2218
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2219 2219
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2220 2220
                   "Multiple reading of section.");
2221 2221
      _sections.insert(std::make_pair(type,
2222 2222
         new _reader_bits::StreamSection<Functor>(functor)));
2223 2223
      return *this;
2224 2224
    }
2225 2225

	
2226 2226
    /// @}
2227 2227

	
2228 2228
  private:
2229 2229

	
2230 2230
    bool readLine() {
2231 2231
      std::string str;
2232 2232
      while(++line_num, std::getline(*_is, str)) {
2233 2233
        line.clear(); line.str(str);
2234 2234
        char c;
2235 2235
        if (line >> std::ws >> c && c != '#') {
2236 2236
          line.putback(c);
2237 2237
          return true;
2238 2238
        }
2239 2239
      }
2240 2240
      return false;
2241 2241
    }
2242 2242

	
2243 2243
    bool readSuccess() {
2244 2244
      return static_cast<bool>(*_is);
2245 2245
    }
2246 2246

	
2247 2247
    void skipSection() {
2248 2248
      char c;
2249 2249
      while (readSuccess() && line >> c && c != '@') {
2250 2250
        readLine();
2251 2251
      }
2252 2252
      if (readSuccess()) {
2253 2253
        line.putback(c);
2254 2254
      }
2255 2255
    }
2256 2256

	
2257 2257
  public:
2258 2258

	
2259 2259

	
2260
    /// \name Execution of the reader
2260
    /// \name Execution of the Reader
2261 2261
    /// @{
2262 2262

	
2263 2263
    /// \brief Start the batch processing
2264 2264
    ///
2265 2265
    /// This function starts the batch processing.
2266 2266
    void run() {
2267 2267

	
2268 2268
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
2269 2269

	
2270 2270
      std::set<std::string> extra_sections;
2271 2271

	
2272 2272
      line_num = 0;
2273 2273
      readLine();
2274 2274
      skipSection();
2275 2275

	
2276 2276
      while (readSuccess()) {
2277 2277
        try {
2278 2278
          char c;
2279 2279
          std::string section, caption;
2280 2280
          line >> c;
2281 2281
          _reader_bits::readToken(line, section);
2282 2282
          _reader_bits::readToken(line, caption);
2283 2283

	
2284 2284
          if (line >> c)
2285 2285
            throw FormatError("Extra character at the end of line");
2286 2286

	
2287 2287
          if (extra_sections.find(section) != extra_sections.end()) {
2288 2288
            std::ostringstream msg;
2289 2289
            msg << "Multiple occurence of section: " << section;
2290 2290
            throw FormatError(msg.str());
2291 2291
          }
2292 2292
          Sections::iterator it = _sections.find(section);
2293 2293
          if (it != _sections.end()) {
2294 2294
            extra_sections.insert(section);
2295 2295
            it->second->process(*_is, line_num);
2296 2296
          }
2297 2297
          readLine();
2298 2298
          skipSection();
2299 2299
        } catch (FormatError& error) {
2300 2300
          error.line(line_num);
2301 2301
          error.file(_filename);
2302 2302
          throw;
2303 2303
        }
2304 2304
      }
2305 2305
      for (Sections::iterator it = _sections.begin();
2306 2306
           it != _sections.end(); ++it) {
2307 2307
        if (extra_sections.find(it->first) == extra_sections.end()) {
2308 2308
          std::ostringstream os;
2309 2309
          os << "Cannot find section: " << it->first;
2310 2310
          throw FormatError(os.str());
2311 2311
        }
2312 2312
      }
2313 2313
    }
2314 2314

	
2315 2315
    /// @}
2316 2316

	
2317 2317
  };
2318 2318

	
2319 2319
  /// \brief Return a \ref SectionReader class
2320 2320
  ///
2321 2321
  /// This function just returns a \ref SectionReader class.
2322 2322
  /// \relates SectionReader
2323 2323
  inline SectionReader sectionReader(std::istream& is) {
2324 2324
    SectionReader tmp(is);
2325 2325
    return tmp;
2326 2326
  }
2327 2327

	
2328 2328
  /// \brief Return a \ref SectionReader class
2329 2329
  ///
2330 2330
  /// This function just returns a \ref SectionReader class.
2331 2331
  /// \relates SectionReader
2332 2332
  inline SectionReader sectionReader(const std::string& fn) {
2333 2333
    SectionReader tmp(fn);
2334 2334
    return tmp;
2335 2335
  }
2336 2336

	
2337 2337
  /// \brief Return a \ref SectionReader class
2338 2338
  ///
2339 2339
  /// This function just returns a \ref SectionReader class.
2340 2340
  /// \relates SectionReader
2341 2341
  inline SectionReader sectionReader(const char* fn) {
2342 2342
    SectionReader tmp(fn);
2343 2343
    return tmp;
2344 2344
  }
2345 2345

	
2346 2346
  /// \ingroup lemon_io
2347 2347
  ///
2348 2348
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file
2349 2349
  ///
2350 2350
  /// This class can be used to read the sections, the map names and
2351 2351
  /// the attributes from a file. Usually, the LEMON programs know
2352 2352
  /// that, which type of graph, which maps and which attributes
2353 2353
  /// should be read from a file, but in general tools (like glemon)
2354 2354
  /// the contents of an LGF file should be guessed somehow. This class
2355 2355
  /// reads the graph and stores the appropriate information for
2356 2356
  /// reading the graph.
2357 2357
  ///
2358 2358
  ///\code
2359 2359
  /// LgfContents contents("graph.lgf");
2360 2360
  /// contents.run();
2361 2361
  ///
2362 2362
  /// // Does it contain any node section and arc section?
2363 2363
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2364 2364
  ///   std::cerr << "Failure, cannot find graph." << std::endl;
2365 2365
  ///   return -1;
2366 2366
  /// }
2367 2367
  /// std::cout << "The name of the default node section: "
2368 2368
  ///           << contents.nodeSection(0) << std::endl;
2369 2369
  /// std::cout << "The number of the arc maps: "
2370 2370
  ///           << contents.arcMaps(0).size() << std::endl;
2371 2371
  /// std::cout << "The name of second arc map: "
2372 2372
  ///           << contents.arcMaps(0)[1] << std::endl;
2373 2373
  ///\endcode
2374 2374
  class LgfContents {
2375 2375
  private:
2376 2376

	
2377 2377
    std::istream* _is;
2378 2378
    bool local_is;
2379 2379

	
2380 2380
    std::vector<std::string> _node_sections;
2381 2381
    std::vector<std::string> _edge_sections;
2382 2382
    std::vector<std::string> _attribute_sections;
2383 2383
    std::vector<std::string> _extra_sections;
2384 2384

	
2385 2385
    std::vector<bool> _arc_sections;
2386 2386

	
2387 2387
    std::vector<std::vector<std::string> > _node_maps;
2388 2388
    std::vector<std::vector<std::string> > _edge_maps;
2389 2389

	
2390 2390
    std::vector<std::vector<std::string> > _attributes;
2391 2391

	
2392 2392

	
2393 2393
    int line_num;
2394 2394
    std::istringstream line;
2395 2395

	
2396 2396
  public:
2397 2397

	
2398 2398
    /// \brief Constructor
2399 2399
    ///
2400 2400
    /// Construct an \e LGF contents reader, which reads from the given
2401 2401
    /// input stream.
2402 2402
    LgfContents(std::istream& is)
2403 2403
      : _is(&is), local_is(false) {}
2404 2404

	
2405 2405
    /// \brief Constructor
2406 2406
    ///
2407 2407
    /// Construct an \e LGF contents reader, which reads from the given
2408 2408
    /// file.
2409 2409
    LgfContents(const std::string& fn)
2410 2410
      : _is(new std::ifstream(fn.c_str())), local_is(true) {
2411 2411
      if (!(*_is)) {
2412 2412
        delete _is;
2413 2413
        throw IoError("Cannot open file", fn);
2414 2414
      }
2415 2415
    }
2416 2416

	
2417 2417
    /// \brief Constructor
2418 2418
    ///
2419 2419
    /// Construct an \e LGF contents reader, which reads from the given
2420 2420
    /// file.
2421 2421
    LgfContents(const char* fn)
2422 2422
      : _is(new std::ifstream(fn)), local_is(true) {
2423 2423
      if (!(*_is)) {
2424 2424
        delete _is;
2425 2425
        throw IoError("Cannot open file", fn);
2426 2426
      }
2427 2427
    }
2428 2428

	
2429 2429
    /// \brief Destructor
2430 2430
    ~LgfContents() {
2431 2431
      if (local_is) delete _is;
2432 2432
    }
2433 2433

	
2434 2434
  private:
2435 2435

	
2436 2436
    LgfContents(const LgfContents&);
2437 2437
    LgfContents& operator=(const LgfContents&);
2438 2438

	
2439 2439
  public:
2440 2440

	
2441 2441

	
2442
    /// \name Node sections
2442
    /// \name Node Sections
2443 2443
    /// @{
2444 2444

	
2445 2445
    /// \brief Gives back the number of node sections in the file.
2446 2446
    ///
2447 2447
    /// Gives back the number of node sections in the file.
2448 2448
    int nodeSectionNum() const {
2449 2449
      return _node_sections.size();
2450 2450
    }
2451 2451

	
2452 2452
    /// \brief Returns the node section name at the given position.
2453 2453
    ///
2454 2454
    /// Returns the node section name at the given position.
2455 2455
    const std::string& nodeSection(int i) const {
2456 2456
      return _node_sections[i];
2457 2457
    }
2458 2458

	
2459 2459
    /// \brief Gives back the node maps for the given section.
2460 2460
    ///
2461 2461
    /// Gives back the node maps for the given section.
2462 2462
    const std::vector<std::string>& nodeMapNames(int i) const {
2463 2463
      return _node_maps[i];
2464 2464
    }
2465 2465

	
2466 2466
    /// @}
2467 2467

	
2468
    /// \name Arc/Edge sections
2468
    /// \name Arc/Edge Sections
2469 2469
    /// @{
2470 2470

	
2471 2471
    /// \brief Gives back the number of arc/edge sections in the file.
2472 2472
    ///
2473 2473
    /// Gives back the number of arc/edge sections in the file.
2474 2474
    /// \note It is synonym of \c edgeSectionNum().
2475 2475
    int arcSectionNum() const {
2476 2476
      return _edge_sections.size();
2477 2477
    }
2478 2478

	
2479 2479
    /// \brief Returns the arc/edge section name at the given position.
2480 2480
    ///
2481 2481
    /// Returns the arc/edge section name at the given position.
2482 2482
    /// \note It is synonym of \c edgeSection().
2483 2483
    const std::string& arcSection(int i) const {
2484 2484
      return _edge_sections[i];
2485 2485
    }
2486 2486

	
2487 2487
    /// \brief Gives back the arc/edge maps for the given section.
2488 2488
    ///
2489 2489
    /// Gives back the arc/edge maps for the given section.
2490 2490
    /// \note It is synonym of \c edgeMapNames().
2491 2491
    const std::vector<std::string>& arcMapNames(int i) const {
2492 2492
      return _edge_maps[i];
2493 2493
    }
2494 2494

	
2495 2495
    /// @}
2496 2496

	
2497 2497
    /// \name Synonyms
2498 2498
    /// @{
2499 2499

	
2500 2500
    /// \brief Gives back the number of arc/edge sections in the file.
2501 2501
    ///
2502 2502
    /// Gives back the number of arc/edge sections in the file.
2503 2503
    /// \note It is synonym of \c arcSectionNum().
2504 2504
    int edgeSectionNum() const {
2505 2505
      return _edge_sections.size();
2506 2506
    }
2507 2507

	
2508 2508
    /// \brief Returns the section name at the given position.
2509 2509
    ///
2510 2510
    /// Returns the section name at the given position.
2511 2511
    /// \note It is synonym of \c arcSection().
2512 2512
    const std::string& edgeSection(int i) const {
2513 2513
      return _edge_sections[i];
2514 2514
    }
2515 2515

	
2516 2516
    /// \brief Gives back the edge maps for the given section.
2517 2517
    ///
2518 2518
    /// Gives back the edge maps for the given section.
2519 2519
    /// \note It is synonym of \c arcMapNames().
2520 2520
    const std::vector<std::string>& edgeMapNames(int i) const {
2521 2521
      return _edge_maps[i];
2522 2522
    }
2523 2523

	
2524 2524
    /// @}
2525 2525

	
2526
    /// \name Attribute sections
2526
    /// \name Attribute Sections
2527 2527
    /// @{
2528 2528

	
2529 2529
    /// \brief Gives back the number of attribute sections in the file.
2530 2530
    ///
2531 2531
    /// Gives back the number of attribute sections in the file.
2532 2532
    int attributeSectionNum() const {
2533 2533
      return _attribute_sections.size();
2534 2534
    }
2535 2535

	
2536 2536
    /// \brief Returns the attribute section name at the given position.
2537 2537
    ///
2538 2538
    /// Returns the attribute section name at the given position.
2539 2539
    const std::string& attributeSectionNames(int i) const {
2540 2540
      return _attribute_sections[i];
2541 2541
    }
2542 2542

	
2543 2543
    /// \brief Gives back the attributes for the given section.
2544 2544
    ///
2545 2545
    /// Gives back the attributes for the given section.
2546 2546
    const std::vector<std::string>& attributes(int i) const {
2547 2547
      return _attributes[i];
2548 2548
    }
2549 2549

	
2550 2550
    /// @}
2551 2551

	
2552
    /// \name Extra sections
2552
    /// \name Extra Sections
2553 2553
    /// @{
2554 2554

	
2555 2555
    /// \brief Gives back the number of extra sections in the file.
2556 2556
    ///
2557 2557
    /// Gives back the number of extra sections in the file.
2558 2558
    int extraSectionNum() const {
2559 2559
      return _extra_sections.size();
2560 2560
    }
2561 2561

	
2562 2562
    /// \brief Returns the extra section type at the given position.
2563 2563
    ///
2564 2564
    /// Returns the section type at the given position.
2565 2565
    const std::string& extraSection(int i) const {
2566 2566
      return _extra_sections[i];
2567 2567
    }
2568 2568

	
2569 2569
    /// @}
2570 2570

	
2571 2571
  private:
2572 2572

	
2573 2573
    bool readLine() {
2574 2574
      std::string str;
2575 2575
      while(++line_num, std::getline(*_is, str)) {
2576 2576
        line.clear(); line.str(str);
2577 2577
        char c;
2578 2578
        if (line >> std::ws >> c && c != '#') {
2579 2579
          line.putback(c);
2580 2580
          return true;
2581 2581
        }
2582 2582
      }
2583 2583
      return false;
2584 2584
    }
2585 2585

	
2586 2586
    bool readSuccess() {
2587 2587
      return static_cast<bool>(*_is);
2588 2588
    }
2589 2589

	
2590 2590
    void skipSection() {
2591 2591
      char c;
2592 2592
      while (readSuccess() && line >> c && c != '@') {
2593 2593
        readLine();
2594 2594
      }
2595 2595
      if (readSuccess()) {
2596 2596
        line.putback(c);
2597 2597
      }
2598 2598
    }
2599 2599

	
2600 2600
    void readMaps(std::vector<std::string>& maps) {
2601 2601
      char c;
2602 2602
      if (!readLine() || !(line >> c) || c == '@') {
2603 2603
        if (readSuccess() && line) line.putback(c);
2604 2604
        return;
2605 2605
      }
2606 2606
      line.putback(c);
2607 2607
      std::string map;
2608 2608
      while (_reader_bits::readToken(line, map)) {
2609 2609
        maps.push_back(map);
2610 2610
      }
2611 2611
    }
2612 2612

	
2613 2613
    void readAttributes(std::vector<std::string>& attrs) {
2614 2614
      readLine();
2615 2615
      char c;
2616 2616
      while (readSuccess() && line >> c && c != '@') {
2617 2617
        line.putback(c);
2618 2618
        std::string attr;
2619 2619
        _reader_bits::readToken(line, attr);
2620 2620
        attrs.push_back(attr);
2621 2621
        readLine();
2622 2622
      }
2623 2623
      line.putback(c);
2624 2624
    }
2625 2625

	
2626 2626
  public:
2627 2627

	
2628
    /// \name Execution of the contents reader
2628
    /// \name Execution of the Contents Reader
2629 2629
    /// @{
2630 2630

	
2631 2631
    /// \brief Starts the reading
2632 2632
    ///
2633 2633
    /// This function starts the reading.
2634 2634
    void run() {
2635 2635

	
2636 2636
      readLine();
2637 2637
      skipSection();
2638 2638

	
2639 2639
      while (readSuccess()) {
2640 2640

	
2641 2641
        char c;
2642 2642
        line >> c;
2643 2643

	
2644 2644
        std::string section, caption;
2645 2645
        _reader_bits::readToken(line, section);
2646 2646
        _reader_bits::readToken(line, caption);
2647 2647

	
2648 2648
        if (section == "nodes") {
2649 2649
          _node_sections.push_back(caption);
2650 2650
          _node_maps.push_back(std::vector<std::string>());
2651 2651
          readMaps(_node_maps.back());
2652 2652
          readLine(); skipSection();
2653 2653
        } else if (section == "arcs" || section == "edges") {
2654 2654
          _edge_sections.push_back(caption);
2655 2655
          _arc_sections.push_back(section == "arcs");
2656 2656
          _edge_maps.push_back(std::vector<std::string>());
2657 2657
          readMaps(_edge_maps.back());
2658 2658
          readLine(); skipSection();
2659 2659
        } else if (section == "attributes") {
2660 2660
          _attribute_sections.push_back(caption);
2661 2661
          _attributes.push_back(std::vector<std::string>());
2662 2662
          readAttributes(_attributes.back());
2663 2663
        } else {
2664 2664
          _extra_sections.push_back(section);
2665 2665
          readLine(); skipSection();
2666 2666
        }
2667 2667
      }
2668 2668
    }
2669 2669

	
2670 2670
    /// @}
2671 2671

	
2672 2672
  };
2673 2673
}
2674 2674

	
2675 2675
#endif
Ignore white space 384 line context
... ...
@@ -349,1429 +349,1429 @@
349 349

	
350 350
  template <typename Digraph>
351 351
  class DigraphWriter;
352 352

	
353 353
  template <typename Digraph>
354 354
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
355 355
                                       std::ostream& os = std::cout);
356 356
  template <typename Digraph>
357 357
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
358 358
                                       const std::string& fn);
359 359

	
360 360
  template <typename Digraph>
361 361
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
362 362
                                       const char* fn);
363 363

	
364 364

	
365 365
  /// \ingroup lemon_io
366 366
  ///
367 367
  /// \brief \ref lgf-format "LGF" writer for directed graphs
368 368
  ///
369 369
  /// This utility writes an \ref lgf-format "LGF" file.
370 370
  ///
371 371
  /// The writing method does a batch processing. The user creates a
372 372
  /// writer object, then various writing rules can be added to the
373 373
  /// writer, and eventually the writing is executed with the \c run()
374 374
  /// member function. A map writing rule can be added to the writer
375 375
  /// with the \c nodeMap() or \c arcMap() members. An optional
376 376
  /// converter parameter can also be added as a standard functor
377 377
  /// converting from the value type of the map to \c std::string. If it
378 378
  /// is set, it will determine how the value type of the map is written to
379 379
  /// the output stream. If the functor is not set, then a default
380 380
  /// conversion will be used. The \c attribute(), \c node() and \c
381 381
  /// arc() functions are used to add attribute writing rules.
382 382
  ///
383 383
  ///\code
384 384
  /// DigraphWriter<Digraph>(digraph, std::cout).
385 385
  ///   nodeMap("coordinates", coord_map).
386 386
  ///   nodeMap("size", size).
387 387
  ///   nodeMap("title", title).
388 388
  ///   arcMap("capacity", cap_map).
389 389
  ///   node("source", src).
390 390
  ///   node("target", trg).
391 391
  ///   attribute("caption", caption).
392 392
  ///   run();
393 393
  ///\endcode
394 394
  ///
395 395
  ///
396 396
  /// By default, the writer does not write additional captions to the
397 397
  /// sections, but they can be give as an optional parameter of
398 398
  /// the \c nodes(), \c arcs() or \c
399 399
  /// attributes() functions.
400 400
  ///
401 401
  /// The \c skipNodes() and \c skipArcs() functions forbid the
402 402
  /// writing of the sections. If two arc sections should be written
403 403
  /// to the output, it can be done in two passes, the first pass
404 404
  /// writes the node section and the first arc section, then the
405 405
  /// second pass skips the node section and writes just the arc
406 406
  /// section to the stream. The output stream can be retrieved with
407 407
  /// the \c ostream() function, hence the second pass can append its
408 408
  /// output to the output of the first pass.
409 409
  template <typename GR>
410 410
  class DigraphWriter {
411 411
  public:
412 412

	
413 413
    typedef GR Digraph;
414 414
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
415 415

	
416 416
  private:
417 417

	
418 418

	
419 419
    std::ostream* _os;
420 420
    bool local_os;
421 421

	
422 422
    const Digraph& _digraph;
423 423

	
424 424
    std::string _nodes_caption;
425 425
    std::string _arcs_caption;
426 426
    std::string _attributes_caption;
427 427

	
428 428
    typedef std::map<Node, std::string> NodeIndex;
429 429
    NodeIndex _node_index;
430 430
    typedef std::map<Arc, std::string> ArcIndex;
431 431
    ArcIndex _arc_index;
432 432

	
433 433
    typedef std::vector<std::pair<std::string,
434 434
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
435 435
    NodeMaps _node_maps;
436 436

	
437 437
    typedef std::vector<std::pair<std::string,
438 438
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
439 439
    ArcMaps _arc_maps;
440 440

	
441 441
    typedef std::vector<std::pair<std::string,
442 442
      _writer_bits::ValueStorageBase*> > Attributes;
443 443
    Attributes _attributes;
444 444

	
445 445
    bool _skip_nodes;
446 446
    bool _skip_arcs;
447 447

	
448 448
  public:
449 449

	
450 450
    /// \brief Constructor
451 451
    ///
452 452
    /// Construct a directed graph writer, which writes to the given
453 453
    /// output stream.
454 454
    DigraphWriter(const Digraph& digraph, std::ostream& os = std::cout)
455 455
      : _os(&os), local_os(false), _digraph(digraph),
456 456
        _skip_nodes(false), _skip_arcs(false) {}
457 457

	
458 458
    /// \brief Constructor
459 459
    ///
460 460
    /// Construct a directed graph writer, which writes to the given
461 461
    /// output file.
462 462
    DigraphWriter(const Digraph& digraph, const std::string& fn)
463 463
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
464 464
        _skip_nodes(false), _skip_arcs(false) {
465 465
      if (!(*_os)) {
466 466
        delete _os;
467 467
        throw IoError("Cannot write file", fn);
468 468
      }
469 469
    }
470 470

	
471 471
    /// \brief Constructor
472 472
    ///
473 473
    /// Construct a directed graph writer, which writes to the given
474 474
    /// output file.
475 475
    DigraphWriter(const Digraph& digraph, const char* fn)
476 476
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
477 477
        _skip_nodes(false), _skip_arcs(false) {
478 478
      if (!(*_os)) {
479 479
        delete _os;
480 480
        throw IoError("Cannot write file", fn);
481 481
      }
482 482
    }
483 483

	
484 484
    /// \brief Destructor
485 485
    ~DigraphWriter() {
486 486
      for (typename NodeMaps::iterator it = _node_maps.begin();
487 487
           it != _node_maps.end(); ++it) {
488 488
        delete it->second;
489 489
      }
490 490

	
491 491
      for (typename ArcMaps::iterator it = _arc_maps.begin();
492 492
           it != _arc_maps.end(); ++it) {
493 493
        delete it->second;
494 494
      }
495 495

	
496 496
      for (typename Attributes::iterator it = _attributes.begin();
497 497
           it != _attributes.end(); ++it) {
498 498
        delete it->second;
499 499
      }
500 500

	
501 501
      if (local_os) {
502 502
        delete _os;
503 503
      }
504 504
    }
505 505

	
506 506
  private:
507 507

	
508 508
    template <typename DGR>
509 509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
510 510
                                            std::ostream& os);
511 511
    template <typename DGR>
512 512
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
513 513
                                            const std::string& fn);
514 514
    template <typename DGR>
515 515
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
516 516
                                            const char *fn);
517 517

	
518 518
    DigraphWriter(DigraphWriter& other)
519 519
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
520 520
        _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
521 521

	
522 522
      other._os = 0;
523 523
      other.local_os = false;
524 524

	
525 525
      _node_index.swap(other._node_index);
526 526
      _arc_index.swap(other._arc_index);
527 527

	
528 528
      _node_maps.swap(other._node_maps);
529 529
      _arc_maps.swap(other._arc_maps);
530 530
      _attributes.swap(other._attributes);
531 531

	
532 532
      _nodes_caption = other._nodes_caption;
533 533
      _arcs_caption = other._arcs_caption;
534 534
      _attributes_caption = other._attributes_caption;
535 535
    }
536 536

	
537 537
    DigraphWriter& operator=(const DigraphWriter&);
538 538

	
539 539
  public:
540 540

	
541
    /// \name Writing rules
541
    /// \name Writing Rules
542 542
    /// @{
543 543

	
544 544
    /// \brief Node map writing rule
545 545
    ///
546 546
    /// Add a node map writing rule to the writer.
547 547
    template <typename Map>
548 548
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
549 549
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
550 550
      _writer_bits::MapStorageBase<Node>* storage =
551 551
        new _writer_bits::MapStorage<Node, Map>(map);
552 552
      _node_maps.push_back(std::make_pair(caption, storage));
553 553
      return *this;
554 554
    }
555 555

	
556 556
    /// \brief Node map writing rule
557 557
    ///
558 558
    /// Add a node map writing rule with specialized converter to the
559 559
    /// writer.
560 560
    template <typename Map, typename Converter>
561 561
    DigraphWriter& nodeMap(const std::string& caption, const Map& map,
562 562
                           const Converter& converter = Converter()) {
563 563
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
564 564
      _writer_bits::MapStorageBase<Node>* storage =
565 565
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
566 566
      _node_maps.push_back(std::make_pair(caption, storage));
567 567
      return *this;
568 568
    }
569 569

	
570 570
    /// \brief Arc map writing rule
571 571
    ///
572 572
    /// Add an arc map writing rule to the writer.
573 573
    template <typename Map>
574 574
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
575 575
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
576 576
      _writer_bits::MapStorageBase<Arc>* storage =
577 577
        new _writer_bits::MapStorage<Arc, Map>(map);
578 578
      _arc_maps.push_back(std::make_pair(caption, storage));
579 579
      return *this;
580 580
    }
581 581

	
582 582
    /// \brief Arc map writing rule
583 583
    ///
584 584
    /// Add an arc map writing rule with specialized converter to the
585 585
    /// writer.
586 586
    template <typename Map, typename Converter>
587 587
    DigraphWriter& arcMap(const std::string& caption, const Map& map,
588 588
                          const Converter& converter = Converter()) {
589 589
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
590 590
      _writer_bits::MapStorageBase<Arc>* storage =
591 591
        new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
592 592
      _arc_maps.push_back(std::make_pair(caption, storage));
593 593
      return *this;
594 594
    }
595 595

	
596 596
    /// \brief Attribute writing rule
597 597
    ///
598 598
    /// Add an attribute writing rule to the writer.
599 599
    template <typename Value>
600 600
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
601 601
      _writer_bits::ValueStorageBase* storage =
602 602
        new _writer_bits::ValueStorage<Value>(value);
603 603
      _attributes.push_back(std::make_pair(caption, storage));
604 604
      return *this;
605 605
    }
606 606

	
607 607
    /// \brief Attribute writing rule
608 608
    ///
609 609
    /// Add an attribute writing rule with specialized converter to the
610 610
    /// writer.
611 611
    template <typename Value, typename Converter>
612 612
    DigraphWriter& attribute(const std::string& caption, const Value& value,
613 613
                             const Converter& converter = Converter()) {
614 614
      _writer_bits::ValueStorageBase* storage =
615 615
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
616 616
      _attributes.push_back(std::make_pair(caption, storage));
617 617
      return *this;
618 618
    }
619 619

	
620 620
    /// \brief Node writing rule
621 621
    ///
622 622
    /// Add a node writing rule to the writer.
623 623
    DigraphWriter& node(const std::string& caption, const Node& node) {
624 624
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
625 625
      Converter converter(_node_index);
626 626
      _writer_bits::ValueStorageBase* storage =
627 627
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
628 628
      _attributes.push_back(std::make_pair(caption, storage));
629 629
      return *this;
630 630
    }
631 631

	
632 632
    /// \brief Arc writing rule
633 633
    ///
634 634
    /// Add an arc writing rule to writer.
635 635
    DigraphWriter& arc(const std::string& caption, const Arc& arc) {
636 636
      typedef _writer_bits::MapLookUpConverter<Arc> Converter;
637 637
      Converter converter(_arc_index);
638 638
      _writer_bits::ValueStorageBase* storage =
639 639
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
640 640
      _attributes.push_back(std::make_pair(caption, storage));
641 641
      return *this;
642 642
    }
643 643

	
644
    /// \name Section captions
644
    /// \name Section Captions
645 645
    /// @{
646 646

	
647 647
    /// \brief Add an additional caption to the \c \@nodes section
648 648
    ///
649 649
    /// Add an additional caption to the \c \@nodes section.
650 650
    DigraphWriter& nodes(const std::string& caption) {
651 651
      _nodes_caption = caption;
652 652
      return *this;
653 653
    }
654 654

	
655 655
    /// \brief Add an additional caption to the \c \@arcs section
656 656
    ///
657 657
    /// Add an additional caption to the \c \@arcs section.
658 658
    DigraphWriter& arcs(const std::string& caption) {
659 659
      _arcs_caption = caption;
660 660
      return *this;
661 661
    }
662 662

	
663 663
    /// \brief Add an additional caption to the \c \@attributes section
664 664
    ///
665 665
    /// Add an additional caption to the \c \@attributes section.
666 666
    DigraphWriter& attributes(const std::string& caption) {
667 667
      _attributes_caption = caption;
668 668
      return *this;
669 669
    }
670 670

	
671
    /// \name Skipping section
671
    /// \name Skipping Section
672 672
    /// @{
673 673

	
674 674
    /// \brief Skip writing the node set
675 675
    ///
676 676
    /// The \c \@nodes section will not be written to the stream.
677 677
    DigraphWriter& skipNodes() {
678 678
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
679 679
      _skip_nodes = true;
680 680
      return *this;
681 681
    }
682 682

	
683 683
    /// \brief Skip writing arc set
684 684
    ///
685 685
    /// The \c \@arcs section will not be written to the stream.
686 686
    DigraphWriter& skipArcs() {
687 687
      LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
688 688
      _skip_arcs = true;
689 689
      return *this;
690 690
    }
691 691

	
692 692
    /// @}
693 693

	
694 694
  private:
695 695

	
696 696
    void writeNodes() {
697 697
      _writer_bits::MapStorageBase<Node>* label = 0;
698 698
      for (typename NodeMaps::iterator it = _node_maps.begin();
699 699
           it != _node_maps.end(); ++it) {
700 700
        if (it->first == "label") {
701 701
          label = it->second;
702 702
          break;
703 703
        }
704 704
      }
705 705

	
706 706
      *_os << "@nodes";
707 707
      if (!_nodes_caption.empty()) {
708 708
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
709 709
      }
710 710
      *_os << std::endl;
711 711

	
712 712
      if (label == 0) {
713 713
        *_os << "label" << '\t';
714 714
      }
715 715
      for (typename NodeMaps::iterator it = _node_maps.begin();
716 716
           it != _node_maps.end(); ++it) {
717 717
        _writer_bits::writeToken(*_os, it->first) << '\t';
718 718
      }
719 719
      *_os << std::endl;
720 720

	
721 721
      std::vector<Node> nodes;
722 722
      for (NodeIt n(_digraph); n != INVALID; ++n) {
723 723
        nodes.push_back(n);
724 724
      }
725 725

	
726 726
      if (label == 0) {
727 727
        IdMap<Digraph, Node> id_map(_digraph);
728 728
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
729 729
        std::sort(nodes.begin(), nodes.end(), id_less);
730 730
      } else {
731 731
        label->sort(nodes);
732 732
      }
733 733

	
734 734
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
735 735
        Node n = nodes[i];
736 736
        if (label == 0) {
737 737
          std::ostringstream os;
738 738
          os << _digraph.id(n);
739 739
          _writer_bits::writeToken(*_os, os.str());
740 740
          *_os << '\t';
741 741
          _node_index.insert(std::make_pair(n, os.str()));
742 742
        }
743 743
        for (typename NodeMaps::iterator it = _node_maps.begin();
744 744
             it != _node_maps.end(); ++it) {
745 745
          std::string value = it->second->get(n);
746 746
          _writer_bits::writeToken(*_os, value);
747 747
          if (it->first == "label") {
748 748
            _node_index.insert(std::make_pair(n, value));
749 749
          }
750 750
          *_os << '\t';
751 751
        }
752 752
        *_os << std::endl;
753 753
      }
754 754
    }
755 755

	
756 756
    void createNodeIndex() {
757 757
      _writer_bits::MapStorageBase<Node>* label = 0;
758 758
      for (typename NodeMaps::iterator it = _node_maps.begin();
759 759
           it != _node_maps.end(); ++it) {
760 760
        if (it->first == "label") {
761 761
          label = it->second;
762 762
          break;
763 763
        }
764 764
      }
765 765

	
766 766
      if (label == 0) {
767 767
        for (NodeIt n(_digraph); n != INVALID; ++n) {
768 768
          std::ostringstream os;
769 769
          os << _digraph.id(n);
770 770
          _node_index.insert(std::make_pair(n, os.str()));
771 771
        }
772 772
      } else {
773 773
        for (NodeIt n(_digraph); n != INVALID; ++n) {
774 774
          std::string value = label->get(n);
775 775
          _node_index.insert(std::make_pair(n, value));
776 776
        }
777 777
      }
778 778
    }
779 779

	
780 780
    void writeArcs() {
781 781
      _writer_bits::MapStorageBase<Arc>* label = 0;
782 782
      for (typename ArcMaps::iterator it = _arc_maps.begin();
783 783
           it != _arc_maps.end(); ++it) {
784 784
        if (it->first == "label") {
785 785
          label = it->second;
786 786
          break;
787 787
        }
788 788
      }
789 789

	
790 790
      *_os << "@arcs";
791 791
      if (!_arcs_caption.empty()) {
792 792
        _writer_bits::writeToken(*_os << ' ', _arcs_caption);
793 793
      }
794 794
      *_os << std::endl;
795 795

	
796 796
      *_os << '\t' << '\t';
797 797
      if (label == 0) {
798 798
        *_os << "label" << '\t';
799 799
      }
800 800
      for (typename ArcMaps::iterator it = _arc_maps.begin();
801 801
           it != _arc_maps.end(); ++it) {
802 802
        _writer_bits::writeToken(*_os, it->first) << '\t';
803 803
      }
804 804
      *_os << std::endl;
805 805

	
806 806
      std::vector<Arc> arcs;
807 807
      for (ArcIt n(_digraph); n != INVALID; ++n) {
808 808
        arcs.push_back(n);
809 809
      }
810 810

	
811 811
      if (label == 0) {
812 812
        IdMap<Digraph, Arc> id_map(_digraph);
813 813
        _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
814 814
        std::sort(arcs.begin(), arcs.end(), id_less);
815 815
      } else {
816 816
        label->sort(arcs);
817 817
      }
818 818

	
819 819
      for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
820 820
        Arc a = arcs[i];
821 821
        _writer_bits::writeToken(*_os, _node_index.
822 822
                                 find(_digraph.source(a))->second);
823 823
        *_os << '\t';
824 824
        _writer_bits::writeToken(*_os, _node_index.
825 825
                                 find(_digraph.target(a))->second);
826 826
        *_os << '\t';
827 827
        if (label == 0) {
828 828
          std::ostringstream os;
829 829
          os << _digraph.id(a);
830 830
          _writer_bits::writeToken(*_os, os.str());
831 831
          *_os << '\t';
832 832
          _arc_index.insert(std::make_pair(a, os.str()));
833 833
        }
834 834
        for (typename ArcMaps::iterator it = _arc_maps.begin();
835 835
             it != _arc_maps.end(); ++it) {
836 836
          std::string value = it->second->get(a);
837 837
          _writer_bits::writeToken(*_os, value);
838 838
          if (it->first == "label") {
839 839
            _arc_index.insert(std::make_pair(a, value));
840 840
          }
841 841
          *_os << '\t';
842 842
        }
843 843
        *_os << std::endl;
844 844
      }
845 845
    }
846 846

	
847 847
    void createArcIndex() {
848 848
      _writer_bits::MapStorageBase<Arc>* label = 0;
849 849
      for (typename ArcMaps::iterator it = _arc_maps.begin();
850 850
           it != _arc_maps.end(); ++it) {
851 851
        if (it->first == "label") {
852 852
          label = it->second;
853 853
          break;
854 854
        }
855 855
      }
856 856

	
857 857
      if (label == 0) {
858 858
        for (ArcIt a(_digraph); a != INVALID; ++a) {
859 859
          std::ostringstream os;
860 860
          os << _digraph.id(a);
861 861
          _arc_index.insert(std::make_pair(a, os.str()));
862 862
        }
863 863
      } else {
864 864
        for (ArcIt a(_digraph); a != INVALID; ++a) {
865 865
          std::string value = label->get(a);
866 866
          _arc_index.insert(std::make_pair(a, value));
867 867
        }
868 868
      }
869 869
    }
870 870

	
871 871
    void writeAttributes() {
872 872
      if (_attributes.empty()) return;
873 873
      *_os << "@attributes";
874 874
      if (!_attributes_caption.empty()) {
875 875
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
876 876
      }
877 877
      *_os << std::endl;
878 878
      for (typename Attributes::iterator it = _attributes.begin();
879 879
           it != _attributes.end(); ++it) {
880 880
        _writer_bits::writeToken(*_os, it->first) << ' ';
881 881
        _writer_bits::writeToken(*_os, it->second->get());
882 882
        *_os << std::endl;
883 883
      }
884 884
    }
885 885

	
886 886
  public:
887 887

	
888
    /// \name Execution of the writer
888
    /// \name Execution of the Writer
889 889
    /// @{
890 890

	
891 891
    /// \brief Start the batch processing
892 892
    ///
893 893
    /// This function starts the batch processing.
894 894
    void run() {
895 895
      if (!_skip_nodes) {
896 896
        writeNodes();
897 897
      } else {
898 898
        createNodeIndex();
899 899
      }
900 900
      if (!_skip_arcs) {
901 901
        writeArcs();
902 902
      } else {
903 903
        createArcIndex();
904 904
      }
905 905
      writeAttributes();
906 906
    }
907 907

	
908 908
    /// \brief Give back the stream of the writer
909 909
    ///
910 910
    /// Give back the stream of the writer.
911 911
    std::ostream& ostream() {
912 912
      return *_os;
913 913
    }
914 914

	
915 915
    /// @}
916 916
  };
917 917

	
918 918
  /// \brief Return a \ref DigraphWriter class
919 919
  ///
920 920
  /// This function just returns a \ref DigraphWriter class.
921 921
  /// \relates DigraphWriter
922 922
  template <typename Digraph>
923 923
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
924 924
                                       std::ostream& os) {
925 925
    DigraphWriter<Digraph> tmp(digraph, os);
926 926
    return tmp;
927 927
  }
928 928

	
929 929
  /// \brief Return a \ref DigraphWriter class
930 930
  ///
931 931
  /// This function just returns a \ref DigraphWriter class.
932 932
  /// \relates DigraphWriter
933 933
  template <typename Digraph>
934 934
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
935 935
                                       const std::string& fn) {
936 936
    DigraphWriter<Digraph> tmp(digraph, fn);
937 937
    return tmp;
938 938
  }
939 939

	
940 940
  /// \brief Return a \ref DigraphWriter class
941 941
  ///
942 942
  /// This function just returns a \ref DigraphWriter class.
943 943
  /// \relates DigraphWriter
944 944
  template <typename Digraph>
945 945
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
946 946
                                       const char* fn) {
947 947
    DigraphWriter<Digraph> tmp(digraph, fn);
948 948
    return tmp;
949 949
  }
950 950

	
951 951
  template <typename Graph>
952 952
  class GraphWriter;
953 953

	
954 954
  template <typename Graph>
955 955
  GraphWriter<Graph> graphWriter(const Graph& graph,
956 956
                                 std::ostream& os = std::cout);
957 957
  template <typename Graph>
958 958
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
959 959
  template <typename Graph>
960 960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
961 961

	
962 962
  /// \ingroup lemon_io
963 963
  ///
964 964
  /// \brief \ref lgf-format "LGF" writer for directed graphs
965 965
  ///
966 966
  /// This utility writes an \ref lgf-format "LGF" file.
967 967
  ///
968 968
  /// It can be used almost the same way as \c DigraphWriter.
969 969
  /// The only difference is that this class can handle edges and
970 970
  /// edge maps as well as arcs and arc maps.
971 971
  ///
972 972
  /// The arc maps are written into the file as two columns, the
973 973
  /// caption of the columns are the name of the map prefixed with \c
974 974
  /// '+' and \c '-'. The arcs are written into the \c \@attributes
975 975
  /// section as a \c '+' or a \c '-' prefix (depends on the direction
976 976
  /// of the arc) and the label of corresponding edge.
977 977
  template <typename GR>
978 978
  class GraphWriter {
979 979
  public:
980 980

	
981 981
    typedef GR Graph;
982 982
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
983 983

	
984 984
  private:
985 985

	
986 986

	
987 987
    std::ostream* _os;
988 988
    bool local_os;
989 989

	
990 990
    const Graph& _graph;
991 991

	
992 992
    std::string _nodes_caption;
993 993
    std::string _edges_caption;
994 994
    std::string _attributes_caption;
995 995

	
996 996
    typedef std::map<Node, std::string> NodeIndex;
997 997
    NodeIndex _node_index;
998 998
    typedef std::map<Edge, std::string> EdgeIndex;
999 999
    EdgeIndex _edge_index;
1000 1000

	
1001 1001
    typedef std::vector<std::pair<std::string,
1002 1002
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;
1003 1003
    NodeMaps _node_maps;
1004 1004

	
1005 1005
    typedef std::vector<std::pair<std::string,
1006 1006
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
1007 1007
    EdgeMaps _edge_maps;
1008 1008

	
1009 1009
    typedef std::vector<std::pair<std::string,
1010 1010
      _writer_bits::ValueStorageBase*> > Attributes;
1011 1011
    Attributes _attributes;
1012 1012

	
1013 1013
    bool _skip_nodes;
1014 1014
    bool _skip_edges;
1015 1015

	
1016 1016
  public:
1017 1017

	
1018 1018
    /// \brief Constructor
1019 1019
    ///
1020 1020
    /// Construct a directed graph writer, which writes to the given
1021 1021
    /// output stream.
1022 1022
    GraphWriter(const Graph& graph, std::ostream& os = std::cout)
1023 1023
      : _os(&os), local_os(false), _graph(graph),
1024 1024
        _skip_nodes(false), _skip_edges(false) {}
1025 1025

	
1026 1026
    /// \brief Constructor
1027 1027
    ///
1028 1028
    /// Construct a directed graph writer, which writes to the given
1029 1029
    /// output file.
1030 1030
    GraphWriter(const Graph& graph, const std::string& fn)
1031 1031
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
1032 1032
        _skip_nodes(false), _skip_edges(false) {
1033 1033
      if (!(*_os)) {
1034 1034
        delete _os;
1035 1035
        throw IoError("Cannot write file", fn);
1036 1036
      }
1037 1037
    }
1038 1038

	
1039 1039
    /// \brief Constructor
1040 1040
    ///
1041 1041
    /// Construct a directed graph writer, which writes to the given
1042 1042
    /// output file.
1043 1043
    GraphWriter(const Graph& graph, const char* fn)
1044 1044
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
1045 1045
        _skip_nodes(false), _skip_edges(false) {
1046 1046
      if (!(*_os)) {
1047 1047
        delete _os;
1048 1048
        throw IoError("Cannot write file", fn);
1049 1049
      }
1050 1050
    }
1051 1051

	
1052 1052
    /// \brief Destructor
1053 1053
    ~GraphWriter() {
1054 1054
      for (typename NodeMaps::iterator it = _node_maps.begin();
1055 1055
           it != _node_maps.end(); ++it) {
1056 1056
        delete it->second;
1057 1057
      }
1058 1058

	
1059 1059
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1060 1060
           it != _edge_maps.end(); ++it) {
1061 1061
        delete it->second;
1062 1062
      }
1063 1063

	
1064 1064
      for (typename Attributes::iterator it = _attributes.begin();
1065 1065
           it != _attributes.end(); ++it) {
1066 1066
        delete it->second;
1067 1067
      }
1068 1068

	
1069 1069
      if (local_os) {
1070 1070
        delete _os;
1071 1071
      }
1072 1072
    }
1073 1073

	
1074 1074
  private:
1075 1075

	
1076 1076
    template <typename Graph>
1077 1077
    friend GraphWriter<Graph> graphWriter(const Graph& graph,
1078 1078
                                          std::ostream& os);
1079 1079
    template <typename Graph>
1080 1080
    friend GraphWriter<Graph> graphWriter(const Graph& graph,
1081 1081
                                          const std::string& fn);
1082 1082
    template <typename Graph>
1083 1083
    friend GraphWriter<Graph> graphWriter(const Graph& graph,
1084 1084
                                          const char *fn);
1085 1085
    
1086 1086
    GraphWriter(GraphWriter& other)
1087 1087
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1088 1088
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1089 1089

	
1090 1090
      other._os = 0;
1091 1091
      other.local_os = false;
1092 1092

	
1093 1093
      _node_index.swap(other._node_index);
1094 1094
      _edge_index.swap(other._edge_index);
1095 1095

	
1096 1096
      _node_maps.swap(other._node_maps);
1097 1097
      _edge_maps.swap(other._edge_maps);
1098 1098
      _attributes.swap(other._attributes);
1099 1099

	
1100 1100
      _nodes_caption = other._nodes_caption;
1101 1101
      _edges_caption = other._edges_caption;
1102 1102
      _attributes_caption = other._attributes_caption;
1103 1103
    }
1104 1104

	
1105 1105
    GraphWriter& operator=(const GraphWriter&);
1106 1106

	
1107 1107
  public:
1108 1108

	
1109
    /// \name Writing rules
1109
    /// \name Writing Rules
1110 1110
    /// @{
1111 1111

	
1112 1112
    /// \brief Node map writing rule
1113 1113
    ///
1114 1114
    /// Add a node map writing rule to the writer.
1115 1115
    template <typename Map>
1116 1116
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1117 1117
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1118 1118
      _writer_bits::MapStorageBase<Node>* storage =
1119 1119
        new _writer_bits::MapStorage<Node, Map>(map);
1120 1120
      _node_maps.push_back(std::make_pair(caption, storage));
1121 1121
      return *this;
1122 1122
    }
1123 1123

	
1124 1124
    /// \brief Node map writing rule
1125 1125
    ///
1126 1126
    /// Add a node map writing rule with specialized converter to the
1127 1127
    /// writer.
1128 1128
    template <typename Map, typename Converter>
1129 1129
    GraphWriter& nodeMap(const std::string& caption, const Map& map,
1130 1130
                           const Converter& converter = Converter()) {
1131 1131
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1132 1132
      _writer_bits::MapStorageBase<Node>* storage =
1133 1133
        new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1134 1134
      _node_maps.push_back(std::make_pair(caption, storage));
1135 1135
      return *this;
1136 1136
    }
1137 1137

	
1138 1138
    /// \brief Edge map writing rule
1139 1139
    ///
1140 1140
    /// Add an edge map writing rule to the writer.
1141 1141
    template <typename Map>
1142 1142
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1143 1143
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1144 1144
      _writer_bits::MapStorageBase<Edge>* storage =
1145 1145
        new _writer_bits::MapStorage<Edge, Map>(map);
1146 1146
      _edge_maps.push_back(std::make_pair(caption, storage));
1147 1147
      return *this;
1148 1148
    }
1149 1149

	
1150 1150
    /// \brief Edge map writing rule
1151 1151
    ///
1152 1152
    /// Add an edge map writing rule with specialized converter to the
1153 1153
    /// writer.
1154 1154
    template <typename Map, typename Converter>
1155 1155
    GraphWriter& edgeMap(const std::string& caption, const Map& map,
1156 1156
                          const Converter& converter = Converter()) {
1157 1157
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1158 1158
      _writer_bits::MapStorageBase<Edge>* storage =
1159 1159
        new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1160 1160
      _edge_maps.push_back(std::make_pair(caption, storage));
1161 1161
      return *this;
1162 1162
    }
1163 1163

	
1164 1164
    /// \brief Arc map writing rule
1165 1165
    ///
1166 1166
    /// Add an arc map writing rule to the writer.
1167 1167
    template <typename Map>
1168 1168
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1169 1169
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1170 1170
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1171 1171
        new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1172 1172
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1173 1173
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1174 1174
        new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1175 1175
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1176 1176
      return *this;
1177 1177
    }
1178 1178

	
1179 1179
    /// \brief Arc map writing rule
1180 1180
    ///
1181 1181
    /// Add an arc map writing rule with specialized converter to the
1182 1182
    /// writer.
1183 1183
    template <typename Map, typename Converter>
1184 1184
    GraphWriter& arcMap(const std::string& caption, const Map& map,
1185 1185
                          const Converter& converter = Converter()) {
1186 1186
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1187 1187
      _writer_bits::MapStorageBase<Edge>* forward_storage =
1188 1188
        new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1189 1189
        (_graph, map, converter);
1190 1190
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1191 1191
      _writer_bits::MapStorageBase<Edge>* backward_storage =
1192 1192
        new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1193 1193
        (_graph, map, converter);
1194 1194
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1195 1195
      return *this;
1196 1196
    }
1197 1197

	
1198 1198
    /// \brief Attribute writing rule
1199 1199
    ///
1200 1200
    /// Add an attribute writing rule to the writer.
1201 1201
    template <typename Value>
1202 1202
    GraphWriter& attribute(const std::string& caption, const Value& value) {
1203 1203
      _writer_bits::ValueStorageBase* storage =
1204 1204
        new _writer_bits::ValueStorage<Value>(value);
1205 1205
      _attributes.push_back(std::make_pair(caption, storage));
1206 1206
      return *this;
1207 1207
    }
1208 1208

	
1209 1209
    /// \brief Attribute writing rule
1210 1210
    ///
1211 1211
    /// Add an attribute writing rule with specialized converter to the
1212 1212
    /// writer.
1213 1213
    template <typename Value, typename Converter>
1214 1214
    GraphWriter& attribute(const std::string& caption, const Value& value,
1215 1215
                             const Converter& converter = Converter()) {
1216 1216
      _writer_bits::ValueStorageBase* storage =
1217 1217
        new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1218 1218
      _attributes.push_back(std::make_pair(caption, storage));
1219 1219
      return *this;
1220 1220
    }
1221 1221

	
1222 1222
    /// \brief Node writing rule
1223 1223
    ///
1224 1224
    /// Add a node writing rule to the writer.
1225 1225
    GraphWriter& node(const std::string& caption, const Node& node) {
1226 1226
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
1227 1227
      Converter converter(_node_index);
1228 1228
      _writer_bits::ValueStorageBase* storage =
1229 1229
        new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1230 1230
      _attributes.push_back(std::make_pair(caption, storage));
1231 1231
      return *this;
1232 1232
    }
1233 1233

	
1234 1234
    /// \brief Edge writing rule
1235 1235
    ///
1236 1236
    /// Add an edge writing rule to writer.
1237 1237
    GraphWriter& edge(const std::string& caption, const Edge& edge) {
1238 1238
      typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1239 1239
      Converter converter(_edge_index);
1240 1240
      _writer_bits::ValueStorageBase* storage =
1241 1241
        new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1242 1242
      _attributes.push_back(std::make_pair(caption, storage));
1243 1243
      return *this;
1244 1244
    }
1245 1245

	
1246 1246
    /// \brief Arc writing rule
1247 1247
    ///
1248 1248
    /// Add an arc writing rule to writer.
1249 1249
    GraphWriter& arc(const std::string& caption, const Arc& arc) {
1250 1250
      typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1251 1251
      Converter converter(_graph, _edge_index);
1252 1252
      _writer_bits::ValueStorageBase* storage =
1253 1253
        new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1254 1254
      _attributes.push_back(std::make_pair(caption, storage));
1255 1255
      return *this;
1256 1256
    }
1257 1257

	
1258
    /// \name Section captions
1258
    /// \name Section Captions
1259 1259
    /// @{
1260 1260

	
1261 1261
    /// \brief Add an additional caption to the \c \@nodes section
1262 1262
    ///
1263 1263
    /// Add an additional caption to the \c \@nodes section.
1264 1264
    GraphWriter& nodes(const std::string& caption) {
1265 1265
      _nodes_caption = caption;
1266 1266
      return *this;
1267 1267
    }
1268 1268

	
1269 1269
    /// \brief Add an additional caption to the \c \@arcs section
1270 1270
    ///
1271 1271
    /// Add an additional caption to the \c \@arcs section.
1272 1272
    GraphWriter& edges(const std::string& caption) {
1273 1273
      _edges_caption = caption;
1274 1274
      return *this;
1275 1275
    }
1276 1276

	
1277 1277
    /// \brief Add an additional caption to the \c \@attributes section
1278 1278
    ///
1279 1279
    /// Add an additional caption to the \c \@attributes section.
1280 1280
    GraphWriter& attributes(const std::string& caption) {
1281 1281
      _attributes_caption = caption;
1282 1282
      return *this;
1283 1283
    }
1284 1284

	
1285
    /// \name Skipping section
1285
    /// \name Skipping Section
1286 1286
    /// @{
1287 1287

	
1288 1288
    /// \brief Skip writing the node set
1289 1289
    ///
1290 1290
    /// The \c \@nodes section will not be written to the stream.
1291 1291
    GraphWriter& skipNodes() {
1292 1292
      LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1293 1293
      _skip_nodes = true;
1294 1294
      return *this;
1295 1295
    }
1296 1296

	
1297 1297
    /// \brief Skip writing edge set
1298 1298
    ///
1299 1299
    /// The \c \@edges section will not be written to the stream.
1300 1300
    GraphWriter& skipEdges() {
1301 1301
      LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1302 1302
      _skip_edges = true;
1303 1303
      return *this;
1304 1304
    }
1305 1305

	
1306 1306
    /// @}
1307 1307

	
1308 1308
  private:
1309 1309

	
1310 1310
    void writeNodes() {
1311 1311
      _writer_bits::MapStorageBase<Node>* label = 0;
1312 1312
      for (typename NodeMaps::iterator it = _node_maps.begin();
1313 1313
           it != _node_maps.end(); ++it) {
1314 1314
        if (it->first == "label") {
1315 1315
          label = it->second;
1316 1316
          break;
1317 1317
        }
1318 1318
      }
1319 1319

	
1320 1320
      *_os << "@nodes";
1321 1321
      if (!_nodes_caption.empty()) {
1322 1322
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1323 1323
      }
1324 1324
      *_os << std::endl;
1325 1325

	
1326 1326
      if (label == 0) {
1327 1327
        *_os << "label" << '\t';
1328 1328
      }
1329 1329
      for (typename NodeMaps::iterator it = _node_maps.begin();
1330 1330
           it != _node_maps.end(); ++it) {
1331 1331
        _writer_bits::writeToken(*_os, it->first) << '\t';
1332 1332
      }
1333 1333
      *_os << std::endl;
1334 1334

	
1335 1335
      std::vector<Node> nodes;
1336 1336
      for (NodeIt n(_graph); n != INVALID; ++n) {
1337 1337
        nodes.push_back(n);
1338 1338
      }
1339 1339

	
1340 1340
      if (label == 0) {
1341 1341
        IdMap<Graph, Node> id_map(_graph);
1342 1342
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1343 1343
        std::sort(nodes.begin(), nodes.end(), id_less);
1344 1344
      } else {
1345 1345
        label->sort(nodes);
1346 1346
      }
1347 1347

	
1348 1348
      for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1349 1349
        Node n = nodes[i];
1350 1350
        if (label == 0) {
1351 1351
          std::ostringstream os;
1352 1352
          os << _graph.id(n);
1353 1353
          _writer_bits::writeToken(*_os, os.str());
1354 1354
          *_os << '\t';
1355 1355
          _node_index.insert(std::make_pair(n, os.str()));
1356 1356
        }
1357 1357
        for (typename NodeMaps::iterator it = _node_maps.begin();
1358 1358
             it != _node_maps.end(); ++it) {
1359 1359
          std::string value = it->second->get(n);
1360 1360
          _writer_bits::writeToken(*_os, value);
1361 1361
          if (it->first == "label") {
1362 1362
            _node_index.insert(std::make_pair(n, value));
1363 1363
          }
1364 1364
          *_os << '\t';
1365 1365
        }
1366 1366
        *_os << std::endl;
1367 1367
      }
1368 1368
    }
1369 1369

	
1370 1370
    void createNodeIndex() {
1371 1371
      _writer_bits::MapStorageBase<Node>* label = 0;
1372 1372
      for (typename NodeMaps::iterator it = _node_maps.begin();
1373 1373
           it != _node_maps.end(); ++it) {
1374 1374
        if (it->first == "label") {
1375 1375
          label = it->second;
1376 1376
          break;
1377 1377
        }
1378 1378
      }
1379 1379

	
1380 1380
      if (label == 0) {
1381 1381
        for (NodeIt n(_graph); n != INVALID; ++n) {
1382 1382
          std::ostringstream os;
1383 1383
          os << _graph.id(n);
1384 1384
          _node_index.insert(std::make_pair(n, os.str()));
1385 1385
        }
1386 1386
      } else {
1387 1387
        for (NodeIt n(_graph); n != INVALID; ++n) {
1388 1388
          std::string value = label->get(n);
1389 1389
          _node_index.insert(std::make_pair(n, value));
1390 1390
        }
1391 1391
      }
1392 1392
    }
1393 1393

	
1394 1394
    void writeEdges() {
1395 1395
      _writer_bits::MapStorageBase<Edge>* label = 0;
1396 1396
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1397 1397
           it != _edge_maps.end(); ++it) {
1398 1398
        if (it->first == "label") {
1399 1399
          label = it->second;
1400 1400
          break;
1401 1401
        }
1402 1402
      }
1403 1403

	
1404 1404
      *_os << "@edges";
1405 1405
      if (!_edges_caption.empty()) {
1406 1406
        _writer_bits::writeToken(*_os << ' ', _edges_caption);
1407 1407
      }
1408 1408
      *_os << std::endl;
1409 1409

	
1410 1410
      *_os << '\t' << '\t';
1411 1411
      if (label == 0) {
1412 1412
        *_os << "label" << '\t';
1413 1413
      }
1414 1414
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1415 1415
           it != _edge_maps.end(); ++it) {
1416 1416
        _writer_bits::writeToken(*_os, it->first) << '\t';
1417 1417
      }
1418 1418
      *_os << std::endl;
1419 1419

	
1420 1420
      std::vector<Edge> edges;
1421 1421
      for (EdgeIt n(_graph); n != INVALID; ++n) {
1422 1422
        edges.push_back(n);
1423 1423
      }
1424 1424

	
1425 1425
      if (label == 0) {
1426 1426
        IdMap<Graph, Edge> id_map(_graph);
1427 1427
        _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1428 1428
        std::sort(edges.begin(), edges.end(), id_less);
1429 1429
      } else {
1430 1430
        label->sort(edges);
1431 1431
      }
1432 1432

	
1433 1433
      for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1434 1434
        Edge e = edges[i];
1435 1435
        _writer_bits::writeToken(*_os, _node_index.
1436 1436
                                 find(_graph.u(e))->second);
1437 1437
        *_os << '\t';
1438 1438
        _writer_bits::writeToken(*_os, _node_index.
1439 1439
                                 find(_graph.v(e))->second);
1440 1440
        *_os << '\t';
1441 1441
        if (label == 0) {
1442 1442
          std::ostringstream os;
1443 1443
          os << _graph.id(e);
1444 1444
          _writer_bits::writeToken(*_os, os.str());
1445 1445
          *_os << '\t';
1446 1446
          _edge_index.insert(std::make_pair(e, os.str()));
1447 1447
        }
1448 1448
        for (typename EdgeMaps::iterator it = _edge_maps.begin();
1449 1449
             it != _edge_maps.end(); ++it) {
1450 1450
          std::string value = it->second->get(e);
1451 1451
          _writer_bits::writeToken(*_os, value);
1452 1452
          if (it->first == "label") {
1453 1453
            _edge_index.insert(std::make_pair(e, value));
1454 1454
          }
1455 1455
          *_os << '\t';
1456 1456
        }
1457 1457
        *_os << std::endl;
1458 1458
      }
1459 1459
    }
1460 1460

	
1461 1461
    void createEdgeIndex() {
1462 1462
      _writer_bits::MapStorageBase<Edge>* label = 0;
1463 1463
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1464 1464
           it != _edge_maps.end(); ++it) {
1465 1465
        if (it->first == "label") {
1466 1466
          label = it->second;
1467 1467
          break;
1468 1468
        }
1469 1469
      }
1470 1470

	
1471 1471
      if (label == 0) {
1472 1472
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1473 1473
          std::ostringstream os;
1474 1474
          os << _graph.id(e);
1475 1475
          _edge_index.insert(std::make_pair(e, os.str()));
1476 1476
        }
1477 1477
      } else {
1478 1478
        for (EdgeIt e(_graph); e != INVALID; ++e) {
1479 1479
          std::string value = label->get(e);
1480 1480
          _edge_index.insert(std::make_pair(e, value));
1481 1481
        }
1482 1482
      }
1483 1483
    }
1484 1484

	
1485 1485
    void writeAttributes() {
1486 1486
      if (_attributes.empty()) return;
1487 1487
      *_os << "@attributes";
1488 1488
      if (!_attributes_caption.empty()) {
1489 1489
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1490 1490
      }
1491 1491
      *_os << std::endl;
1492 1492
      for (typename Attributes::iterator it = _attributes.begin();
1493 1493
           it != _attributes.end(); ++it) {
1494 1494
        _writer_bits::writeToken(*_os, it->first) << ' ';
1495 1495
        _writer_bits::writeToken(*_os, it->second->get());
1496 1496
        *_os << std::endl;
1497 1497
      }
1498 1498
    }
1499 1499

	
1500 1500
  public:
1501 1501

	
1502
    /// \name Execution of the writer
1502
    /// \name Execution of the Writer
1503 1503
    /// @{
1504 1504

	
1505 1505
    /// \brief Start the batch processing
1506 1506
    ///
1507 1507
    /// This function starts the batch processing.
1508 1508
    void run() {
1509 1509
      if (!_skip_nodes) {
1510 1510
        writeNodes();
1511 1511
      } else {
1512 1512
        createNodeIndex();
1513 1513
      }
1514 1514
      if (!_skip_edges) {
1515 1515
        writeEdges();
1516 1516
      } else {
1517 1517
        createEdgeIndex();
1518 1518
      }
1519 1519
      writeAttributes();
1520 1520
    }
1521 1521

	
1522 1522
    /// \brief Give back the stream of the writer
1523 1523
    ///
1524 1524
    /// Give back the stream of the writer
1525 1525
    std::ostream& ostream() {
1526 1526
      return *_os;
1527 1527
    }
1528 1528

	
1529 1529
    /// @}
1530 1530
  };
1531 1531

	
1532 1532
  /// \brief Return a \ref GraphWriter class
1533 1533
  ///
1534 1534
  /// This function just returns a \ref GraphWriter class.
1535 1535
  /// \relates GraphWriter
1536 1536
  template <typename Graph>
1537 1537
  GraphWriter<Graph> graphWriter(const Graph& graph,
1538 1538
                                 std::ostream& os) {
1539 1539
    GraphWriter<Graph> tmp(graph, os);
1540 1540
    return tmp;
1541 1541
  }
1542 1542

	
1543 1543
  /// \brief Return a \ref GraphWriter class
1544 1544
  ///
1545 1545
  /// This function just returns a \ref GraphWriter class.
1546 1546
  /// \relates GraphWriter
1547 1547
  template <typename Graph>
1548 1548
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
1549 1549
    GraphWriter<Graph> tmp(graph, fn);
1550 1550
    return tmp;
1551 1551
  }
1552 1552

	
1553 1553
  /// \brief Return a \ref GraphWriter class
1554 1554
  ///
1555 1555
  /// This function just returns a \ref GraphWriter class.
1556 1556
  /// \relates GraphWriter
1557 1557
  template <typename Graph>
1558 1558
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
1559 1559
    GraphWriter<Graph> tmp(graph, fn);
1560 1560
    return tmp;
1561 1561
  }
1562 1562

	
1563 1563
  class SectionWriter;
1564 1564

	
1565 1565
  SectionWriter sectionWriter(std::istream& is);
1566 1566
  SectionWriter sectionWriter(const std::string& fn);
1567 1567
  SectionWriter sectionWriter(const char* fn);
1568 1568

	
1569 1569
  /// \ingroup lemon_io
1570 1570
  ///
1571 1571
  /// \brief Section writer class
1572 1572
  ///
1573 1573
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
1574 1574
  /// which contain any data in arbitrary format. Such sections can be
1575 1575
  /// written with this class. A writing rule can be added to the
1576 1576
  /// class with two different functions. With the \c sectionLines()
1577 1577
  /// function a generator can write the section line-by-line, while
1578 1578
  /// with the \c sectionStream() member the section can be written to
1579 1579
  /// an output stream.
1580 1580
  class SectionWriter {
1581 1581
  private:
1582 1582

	
1583 1583
    std::ostream* _os;
1584 1584
    bool local_os;
1585 1585

	
1586 1586
    typedef std::vector<std::pair<std::string, _writer_bits::Section*> >
1587 1587
    Sections;
1588 1588

	
1589 1589
    Sections _sections;
1590 1590

	
1591 1591
  public:
1592 1592

	
1593 1593
    /// \brief Constructor
1594 1594
    ///
1595 1595
    /// Construct a section writer, which writes to the given output
1596 1596
    /// stream.
1597 1597
    SectionWriter(std::ostream& os)
1598 1598
      : _os(&os), local_os(false) {}
1599 1599

	
1600 1600
    /// \brief Constructor
1601 1601
    ///
1602 1602
    /// Construct a section writer, which writes into the given file.
1603 1603
    SectionWriter(const std::string& fn)
1604 1604
      : _os(new std::ofstream(fn.c_str())), local_os(true) {
1605 1605
      if (!(*_os)) {
1606 1606
        delete _os;
1607 1607
        throw IoError("Cannot write file", fn);
1608 1608
      }
1609 1609
    }
1610 1610

	
1611 1611
    /// \brief Constructor
1612 1612
    ///
1613 1613
    /// Construct a section writer, which writes into the given file.
1614 1614
    SectionWriter(const char* fn)
1615 1615
      : _os(new std::ofstream(fn)), local_os(true) {
1616 1616
      if (!(*_os)) {
1617 1617
        delete _os;
1618 1618
        throw IoError("Cannot write file", fn);
1619 1619
      }
1620 1620
    }
1621 1621

	
1622 1622
    /// \brief Destructor
1623 1623
    ~SectionWriter() {
1624 1624
      for (Sections::iterator it = _sections.begin();
1625 1625
           it != _sections.end(); ++it) {
1626 1626
        delete it->second;
1627 1627
      }
1628 1628

	
1629 1629
      if (local_os) {
1630 1630
        delete _os;
1631 1631
      }
1632 1632

	
1633 1633
    }
1634 1634

	
1635 1635
  private:
1636 1636

	
1637 1637
    friend SectionWriter sectionWriter(std::ostream& os);
1638 1638
    friend SectionWriter sectionWriter(const std::string& fn);
1639 1639
    friend SectionWriter sectionWriter(const char* fn);
1640 1640

	
1641 1641
    SectionWriter(SectionWriter& other)
1642 1642
      : _os(other._os), local_os(other.local_os) {
1643 1643

	
1644 1644
      other._os = 0;
1645 1645
      other.local_os = false;
1646 1646

	
1647 1647
      _sections.swap(other._sections);
1648 1648
    }
1649 1649

	
1650 1650
    SectionWriter& operator=(const SectionWriter&);
1651 1651

	
1652 1652
  public:
1653 1653

	
1654
    /// \name Section writers
1654
    /// \name Section Writers
1655 1655
    /// @{
1656 1656

	
1657 1657
    /// \brief Add a section writer with line oriented writing
1658 1658
    ///
1659 1659
    /// The first parameter is the type descriptor of the section, the
1660 1660
    /// second is a generator with std::string values. At the writing
1661 1661
    /// process, the returned \c std::string will be written into the
1662 1662
    /// output file until it is an empty string.
1663 1663
    ///
1664 1664
    /// For example, an integer vector is written into a section.
1665 1665
    ///\code
1666 1666
    ///  @numbers
1667 1667
    ///  12 45 23 78
1668 1668
    ///  4 28 38 28
1669 1669
    ///  23 6 16
1670 1670
    ///\endcode
1671 1671
    ///
1672 1672
    /// The generator is implemented as a struct.
1673 1673
    ///\code
1674 1674
    ///  struct NumberSection {
1675 1675
    ///    std::vector<int>::const_iterator _it, _end;
1676 1676
    ///    NumberSection(const std::vector<int>& data)
1677 1677
    ///      : _it(data.begin()), _end(data.end()) {}
1678 1678
    ///    std::string operator()() {
1679 1679
    ///      int rem_in_line = 4;
1680 1680
    ///      std::ostringstream ls;
1681 1681
    ///      while (rem_in_line > 0 && _it != _end) {
1682 1682
    ///        ls << *(_it++) << ' ';
1683 1683
    ///        --rem_in_line;
1684 1684
    ///      }
1685 1685
    ///      return ls.str();
1686 1686
    ///    }
1687 1687
    ///  };
1688 1688
    ///
1689 1689
    ///  // ...
1690 1690
    ///
1691 1691
    ///  writer.sectionLines("numbers", NumberSection(vec));
1692 1692
    ///\endcode
1693 1693
    template <typename Functor>
1694 1694
    SectionWriter& sectionLines(const std::string& type, Functor functor) {
1695 1695
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1696 1696
      _sections.push_back(std::make_pair(type,
1697 1697
        new _writer_bits::LineSection<Functor>(functor)));
1698 1698
      return *this;
1699 1699
    }
1700 1700

	
1701 1701

	
1702 1702
    /// \brief Add a section writer with stream oriented writing
1703 1703
    ///
1704 1704
    /// The first parameter is the type of the section, the second is
1705 1705
    /// a functor, which takes a \c std::ostream& parameter. The
1706 1706
    /// functor writes the section to the output stream.
1707 1707
    /// \warning The last line must be closed with end-line character.
1708 1708
    template <typename Functor>
1709 1709
    SectionWriter& sectionStream(const std::string& type, Functor functor) {
1710 1710
      LEMON_ASSERT(!type.empty(), "Type is empty.");
1711 1711
      _sections.push_back(std::make_pair(type,
1712 1712
         new _writer_bits::StreamSection<Functor>(functor)));
1713 1713
      return *this;
1714 1714
    }
1715 1715

	
1716 1716
    /// @}
1717 1717

	
1718 1718
  public:
1719 1719

	
1720 1720

	
1721
    /// \name Execution of the writer
1721
    /// \name Execution of the Writer
1722 1722
    /// @{
1723 1723

	
1724 1724
    /// \brief Start the batch processing
1725 1725
    ///
1726 1726
    /// This function starts the batch processing.
1727 1727
    void run() {
1728 1728

	
1729 1729
      LEMON_ASSERT(_os != 0, "This writer is assigned to an other writer");
1730 1730

	
1731 1731
      for (Sections::iterator it = _sections.begin();
1732 1732
           it != _sections.end(); ++it) {
1733 1733
        (*_os) << '@' << it->first << std::endl;
1734 1734
        it->second->process(*_os);
1735 1735
      }
1736 1736
    }
1737 1737

	
1738 1738
    /// \brief Give back the stream of the writer
1739 1739
    ///
1740 1740
    /// Returns the stream of the writer
1741 1741
    std::ostream& ostream() {
1742 1742
      return *_os;
1743 1743
    }
1744 1744

	
1745 1745
    /// @}
1746 1746

	
1747 1747
  };
1748 1748

	
1749 1749
  /// \brief Return a \ref SectionWriter class
1750 1750
  ///
1751 1751
  /// This function just returns a \ref SectionWriter class.
1752 1752
  /// \relates SectionWriter
1753 1753
  inline SectionWriter sectionWriter(std::ostream& os) {
1754 1754
    SectionWriter tmp(os);
1755 1755
    return tmp;
1756 1756
  }
1757 1757

	
1758 1758
  /// \brief Return a \ref SectionWriter class
1759 1759
  ///
1760 1760
  /// This function just returns a \ref SectionWriter class.
1761 1761
  /// \relates SectionWriter
1762 1762
  inline SectionWriter sectionWriter(const std::string& fn) {
1763 1763
    SectionWriter tmp(fn);
1764 1764
    return tmp;
1765 1765
  }
1766 1766

	
1767 1767
  /// \brief Return a \ref SectionWriter class
1768 1768
  ///
1769 1769
  /// This function just returns a \ref SectionWriter class.
1770 1770
  /// \relates SectionWriter
1771 1771
  inline SectionWriter sectionWriter(const char* fn) {
1772 1772
    SectionWriter tmp(fn);
1773 1773
    return tmp;
1774 1774
  }
1775 1775
}
1776 1776

	
1777 1777
#endif

Changeset was too big and was cut off... Show full diff

0 comments (0 inline)