gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 4 0
merge default
0 files changed with 211 insertions and 161 deletions:
↑ Collapse diff ↑
Ignore white space 384 line context
... ...
@@ -201,584 +201,561 @@
201 201
        c == '\n' || c == '\r' || c == '\f';
202 202
    }
203 203

	
204 204
    inline bool isOct(char c) {
205 205
      return '0' <= c && c <='7';
206 206
    }
207 207

	
208 208
    inline int valueOct(char c) {
209 209
      LEMON_ASSERT(isOct(c), "The character is not octal.");
210 210
      return c - '0';
211 211
    }
212 212

	
213 213
    inline bool isHex(char c) {
214 214
      return ('0' <= c && c <= '9') ||
215 215
        ('a' <= c && c <= 'z') ||
216 216
        ('A' <= c && c <= 'Z');
217 217
    }
218 218

	
219 219
    inline int valueHex(char c) {
220 220
      LEMON_ASSERT(isHex(c), "The character is not hexadecimal.");
221 221
      if ('0' <= c && c <= '9') return c - '0';
222 222
      if ('a' <= c && c <= 'z') return c - 'a' + 10;
223 223
      return c - 'A' + 10;
224 224
    }
225 225

	
226 226
    inline bool isIdentifierFirstChar(char c) {
227 227
      return ('a' <= c && c <= 'z') ||
228 228
        ('A' <= c && c <= 'Z') || c == '_';
229 229
    }
230 230

	
231 231
    inline bool isIdentifierChar(char c) {
232 232
      return isIdentifierFirstChar(c) ||
233 233
        ('0' <= c && c <= '9');
234 234
    }
235 235

	
236 236
    inline char readEscape(std::istream& is) {
237 237
      char c;
238 238
      if (!is.get(c))
239 239
        throw FormatError("Escape format error");
240 240

	
241 241
      switch (c) {
242 242
      case '\\':
243 243
        return '\\';
244 244
      case '\"':
245 245
        return '\"';
246 246
      case '\'':
247 247
        return '\'';
248 248
      case '\?':
249 249
        return '\?';
250 250
      case 'a':
251 251
        return '\a';
252 252
      case 'b':
253 253
        return '\b';
254 254
      case 'f':
255 255
        return '\f';
256 256
      case 'n':
257 257
        return '\n';
258 258
      case 'r':
259 259
        return '\r';
260 260
      case 't':
261 261
        return '\t';
262 262
      case 'v':
263 263
        return '\v';
264 264
      case 'x':
265 265
        {
266 266
          int code;
267 267
          if (!is.get(c) || !isHex(c))
268 268
            throw FormatError("Escape format error");
269 269
          else if (code = valueHex(c), !is.get(c) || !isHex(c)) is.putback(c);
270 270
          else code = code * 16 + valueHex(c);
271 271
          return code;
272 272
        }
273 273
      default:
274 274
        {
275 275
          int code;
276 276
          if (!isOct(c))
277 277
            throw FormatError("Escape format error");
278 278
          else if (code = valueOct(c), !is.get(c) || !isOct(c))
279 279
            is.putback(c);
280 280
          else if (code = code * 8 + valueOct(c), !is.get(c) || !isOct(c))
281 281
            is.putback(c);
282 282
          else code = code * 8 + valueOct(c);
283 283
          return code;
284 284
        }
285 285
      }
286 286
    }
287 287

	
288 288
    inline std::istream& readToken(std::istream& is, std::string& str) {
289 289
      std::ostringstream os;
290 290

	
291 291
      char c;
292 292
      is >> std::ws;
293 293

	
294 294
      if (!is.get(c))
295 295
        return is;
296 296

	
297 297
      if (c == '\"') {
298 298
        while (is.get(c) && c != '\"') {
299 299
          if (c == '\\')
300 300
            c = readEscape(is);
301 301
          os << c;
302 302
        }
303 303
        if (!is)
304 304
          throw FormatError("Quoted format error");
305 305
      } else {
306 306
        is.putback(c);
307 307
        while (is.get(c) && !isWhiteSpace(c)) {
308 308
          if (c == '\\')
309 309
            c = readEscape(is);
310 310
          os << c;
311 311
        }
312 312
        if (!is) {
313 313
          is.clear();
314 314
        } else {
315 315
          is.putback(c);
316 316
        }
317 317
      }
318 318
      str = os.str();
319 319
      return is;
320 320
    }
321 321

	
322 322
    class Section {
323 323
    public:
324 324
      virtual ~Section() {}
325 325
      virtual void process(std::istream& is, int& line_num) = 0;
326 326
    };
327 327

	
328 328
    template <typename Functor>
329 329
    class LineSection : public Section {
330 330
    private:
331 331

	
332 332
      Functor _functor;
333 333

	
334 334
    public:
335 335

	
336 336
      LineSection(const Functor& functor) : _functor(functor) {}
337 337
      virtual ~LineSection() {}
338 338

	
339 339
      virtual void process(std::istream& is, int& line_num) {
340 340
        char c;
341 341
        std::string line;
342 342
        while (is.get(c) && c != '@') {
343 343
          if (c == '\n') {
344 344
            ++line_num;
345 345
          } else if (c == '#') {
346 346
            getline(is, line);
347 347
            ++line_num;
348 348
          } else if (!isWhiteSpace(c)) {
349 349
            is.putback(c);
350 350
            getline(is, line);
351 351
            _functor(line);
352 352
            ++line_num;
353 353
          }
354 354
        }
355 355
        if (is) is.putback(c);
356 356
        else if (is.eof()) is.clear();
357 357
      }
358 358
    };
359 359

	
360 360
    template <typename Functor>
361 361
    class StreamSection : public Section {
362 362
    private:
363 363

	
364 364
      Functor _functor;
365 365

	
366 366
    public:
367 367

	
368 368
      StreamSection(const Functor& functor) : _functor(functor) {}
369 369
      virtual ~StreamSection() {}
370 370

	
371 371
      virtual void process(std::istream& is, int& line_num) {
372 372
        _functor(is, line_num);
373 373
        char c;
374 374
        std::string line;
375 375
        while (is.get(c) && c != '@') {
376 376
          if (c == '\n') {
377 377
            ++line_num;
378 378
          } else if (!isWhiteSpace(c)) {
379 379
            getline(is, line);
380 380
            ++line_num;
381 381
          }
382 382
        }
383 383
        if (is) is.putback(c);
384 384
        else if (is.eof()) is.clear();
385 385
      }
386 386
    };
387 387

	
388 388
  }
389 389

	
390 390
  template <typename Digraph>
391 391
  class DigraphReader;
392 392

	
393
  /// \brief Return a \ref DigraphReader class
394
  ///
395
  /// This function just returns a \ref DigraphReader class.
396
  /// \relates DigraphReader
397 393
  template <typename Digraph>
398
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
399
                                       std::istream& is = std::cin) {
400
    DigraphReader<Digraph> tmp(digraph, is);
401
    return tmp;
402
  }
403

	
404
  /// \brief Return a \ref DigraphReader class
405
  ///
406
  /// This function just returns a \ref DigraphReader class.
407
  /// \relates DigraphReader
394
  DigraphReader<Digraph> digraphReader(Digraph& digraph, 
395
                                       std::istream& is = std::cin);
408 396
  template <typename Digraph>
409
  DigraphReader<Digraph> digraphReader(Digraph& digraph,
410
                                       const std::string& fn) {
411
    DigraphReader<Digraph> tmp(digraph, fn);
412
    return tmp;
413
  }
414

	
415
  /// \brief Return a \ref DigraphReader class
416
  ///
417
  /// This function just returns a \ref DigraphReader class.
418
  /// \relates DigraphReader
397
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const std::string& fn);
419 398
  template <typename Digraph>
420
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char* fn) {
421
    DigraphReader<Digraph> tmp(digraph, fn);
422
    return tmp;
423
  }
399
  DigraphReader<Digraph> digraphReader(Digraph& digraph, const char *fn);
424 400

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

	
479 455
    typedef _Digraph Digraph;
480 456
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
481 457

	
482 458
  private:
483 459

	
484 460

	
485 461
    std::istream* _is;
486 462
    bool local_is;
487 463
    std::string _filename;
488 464

	
489 465
    Digraph& _digraph;
490 466

	
491 467
    std::string _nodes_caption;
492 468
    std::string _arcs_caption;
493 469
    std::string _attributes_caption;
494 470

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

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

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

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

	
512 488
    bool _use_nodes;
513 489
    bool _use_arcs;
514 490

	
515 491
    bool _skip_nodes;
516 492
    bool _skip_arcs;
517 493

	
518 494
    int line_num;
519 495
    std::istringstream line;
520 496

	
521 497
  public:
522 498

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

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

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

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

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

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

	
579 555
      if (local_is) {
580 556
        delete _is;
581 557
      }
582 558

	
583 559
    }
584 560

	
585 561
  private:
586 562

	
587
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
588
                                                  std::istream& is);
589
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
590
                                                  const std::string& fn);
591
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
592
                                                  const char *fn);
563
    template <typename DGR>
564
    friend DigraphReader<DGR> digraphReader(DGR& digraph, std::istream& is);
565
    template <typename DGR>
566
    friend DigraphReader<DGR> digraphReader(DGR& digraph, 
567
                                            const std::string& fn);
568
    template <typename DGR>
569
    friend DigraphReader<DGR> digraphReader(DGR& digraph, const char *fn);
593 570

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

	
599 576
      other._is = 0;
600 577
      other.local_is = false;
601 578

	
602 579
      _node_index.swap(other._node_index);
603 580
      _arc_index.swap(other._arc_index);
604 581

	
605 582
      _node_maps.swap(other._node_maps);
606 583
      _arc_maps.swap(other._arc_maps);
607 584
      _attributes.swap(other._attributes);
608 585

	
609 586
      _nodes_caption = other._nodes_caption;
610 587
      _arcs_caption = other._arcs_caption;
611 588
      _attributes_caption = other._attributes_caption;
612 589

	
613 590
    }
614 591

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

	
617 594
  public:
618 595

	
619 596
    /// \name Reading rules
620 597
    /// @{
621 598

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

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

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

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

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

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

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

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

	
722 699
    /// @}
723 700

	
724 701
    /// \name Select section by name
725 702
    /// @{
726 703

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

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

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

	
751 728
    /// @}
752 729

	
753 730
    /// \name Using previously constructed node or arc set
754 731
    /// @{
755 732

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

	
772 749
    /// \brief Use previously constructed node set
773 750
    ///
774 751
    /// Use previously constructed node set, and specify the node
775 752
    /// label map and a functor which converts the label map values to
776 753
    /// \c std::string.
777 754
    template <typename Map, typename Converter>
778 755
    DigraphReader& useNodes(const Map& map,
779 756
                            const Converter& converter = Converter()) {
780 757
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
781 758
      LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member");
782 759
      _use_nodes = true;
783 760
      for (NodeIt n(_digraph); n != INVALID; ++n) {
784 761
        _node_index.insert(std::make_pair(converter(map[n]), n));
... ...
@@ -1021,546 +998,557 @@
1021 998
        line.putback(c);
1022 999

	
1023 1000
        std::string source_token;
1024 1001
        std::string target_token;
1025 1002

	
1026 1003
        if (!_reader_bits::readToken(line, source_token))
1027 1004
          throw FormatError("Source not found");
1028 1005

	
1029 1006
        if (!_reader_bits::readToken(line, target_token))
1030 1007
          throw FormatError("Target not found");
1031 1008

	
1032 1009
        std::vector<std::string> tokens(map_num);
1033 1010
        for (int i = 0; i < map_num; ++i) {
1034 1011
          if (!_reader_bits::readToken(line, tokens[i])) {
1035 1012
            std::ostringstream msg;
1036 1013
            msg << "Column not found (" << i + 1 << ")";
1037 1014
            throw FormatError(msg.str());
1038 1015
          }
1039 1016
        }
1040 1017
        if (line >> std::ws >> c)
1041 1018
          throw FormatError("Extra character at the end of line");
1042 1019

	
1043 1020
        Arc a;
1044 1021
        if (!_use_arcs) {
1045 1022

	
1046 1023
          typename NodeIndex::iterator it;
1047 1024

	
1048 1025
          it = _node_index.find(source_token);
1049 1026
          if (it == _node_index.end()) {
1050 1027
            std::ostringstream msg;
1051 1028
            msg << "Item not found: " << source_token;
1052 1029
            throw FormatError(msg.str());
1053 1030
          }
1054 1031
          Node source = it->second;
1055 1032

	
1056 1033
          it = _node_index.find(target_token);
1057 1034
          if (it == _node_index.end()) {
1058 1035
            std::ostringstream msg;
1059 1036
            msg << "Item not found: " << target_token;
1060 1037
            throw FormatError(msg.str());
1061 1038
          }
1062 1039
          Node target = it->second;
1063 1040

	
1064 1041
          a = _digraph.addArc(source, target);
1065 1042
          if (label_index != -1)
1066 1043
            _arc_index.insert(std::make_pair(tokens[label_index], a));
1067 1044
        } else {
1068 1045
          if (label_index == -1)
1069 1046
            throw FormatError("Label map not found");
1070 1047
          typename std::map<std::string, Arc>::iterator it =
1071 1048
            _arc_index.find(tokens[label_index]);
1072 1049
          if (it == _arc_index.end()) {
1073 1050
            std::ostringstream msg;
1074 1051
            msg << "Arc with label not found: " << tokens[label_index];
1075 1052
            throw FormatError(msg.str());
1076 1053
          }
1077 1054
          a = it->second;
1078 1055
        }
1079 1056

	
1080 1057
        for (int i = 0; i < static_cast<int>(_arc_maps.size()); ++i) {
1081 1058
          _arc_maps[i].second->set(a, tokens[map_index[i]]);
1082 1059
        }
1083 1060

	
1084 1061
      }
1085 1062
      if (readSuccess()) {
1086 1063
        line.putback(c);
1087 1064
      }
1088 1065
    }
1089 1066

	
1090 1067
    void readAttributes() {
1091 1068

	
1092 1069
      std::set<std::string> read_attr;
1093 1070

	
1094 1071
      char c;
1095 1072
      while (readLine() && line >> c && c != '@') {
1096 1073
        line.putback(c);
1097 1074

	
1098 1075
        std::string attr, token;
1099 1076
        if (!_reader_bits::readToken(line, attr))
1100 1077
          throw FormatError("Attribute name not found");
1101 1078
        if (!_reader_bits::readToken(line, token))
1102 1079
          throw FormatError("Attribute value not found");
1103 1080
        if (line >> c)
1104 1081
          throw FormatError("Extra character at the end of line");
1105 1082

	
1106 1083
        {
1107 1084
          std::set<std::string>::iterator it = read_attr.find(attr);
1108 1085
          if (it != read_attr.end()) {
1109 1086
            std::ostringstream msg;
1110 1087
            msg << "Multiple occurence of attribute: " << attr;
1111 1088
            throw FormatError(msg.str());
1112 1089
          }
1113 1090
          read_attr.insert(attr);
1114 1091
        }
1115 1092

	
1116 1093
        {
1117 1094
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1118 1095
          while (it != _attributes.end() && it->first == attr) {
1119 1096
            it->second->set(token);
1120 1097
            ++it;
1121 1098
          }
1122 1099
        }
1123 1100

	
1124 1101
      }
1125 1102
      if (readSuccess()) {
1126 1103
        line.putback(c);
1127 1104
      }
1128 1105
      for (typename Attributes::iterator it = _attributes.begin();
1129 1106
           it != _attributes.end(); ++it) {
1130 1107
        if (read_attr.find(it->first) == read_attr.end()) {
1131 1108
          std::ostringstream msg;
1132 1109
          msg << "Attribute not found: " << it->first;
1133 1110
          throw FormatError(msg.str());
1134 1111
        }
1135 1112
      }
1136 1113
    }
1137 1114

	
1138 1115
  public:
1139 1116

	
1140 1117
    /// \name Execution of the reader
1141 1118
    /// @{
1142 1119

	
1143 1120
    /// \brief Start the batch processing
1144 1121
    ///
1145 1122
    /// This function starts the batch processing
1146 1123
    void run() {
1147 1124
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1148 1125

	
1149 1126
      bool nodes_done = _skip_nodes;
1150 1127
      bool arcs_done = _skip_arcs;
1151 1128
      bool attributes_done = false;
1152 1129

	
1153 1130
      line_num = 0;
1154 1131
      readLine();
1155 1132
      skipSection();
1156 1133

	
1157 1134
      while (readSuccess()) {
1158 1135
        try {
1159 1136
          char c;
1160 1137
          std::string section, caption;
1161 1138
          line >> c;
1162 1139
          _reader_bits::readToken(line, section);
1163 1140
          _reader_bits::readToken(line, caption);
1164 1141

	
1165 1142
          if (line >> c)
1166 1143
            throw FormatError("Extra character at the end of line");
1167 1144

	
1168 1145
          if (section == "nodes" && !nodes_done) {
1169 1146
            if (_nodes_caption.empty() || _nodes_caption == caption) {
1170 1147
              readNodes();
1171 1148
              nodes_done = true;
1172 1149
            }
1173 1150
          } else if ((section == "arcs" || section == "edges") &&
1174 1151
                     !arcs_done) {
1175 1152
            if (_arcs_caption.empty() || _arcs_caption == caption) {
1176 1153
              readArcs();
1177 1154
              arcs_done = true;
1178 1155
            }
1179 1156
          } else if (section == "attributes" && !attributes_done) {
1180 1157
            if (_attributes_caption.empty() || _attributes_caption == caption) {
1181 1158
              readAttributes();
1182 1159
              attributes_done = true;
1183 1160
            }
1184 1161
          } else {
1185 1162
            readLine();
1186 1163
            skipSection();
1187 1164
          }
1188 1165
        } catch (FormatError& error) {
1189 1166
          error.line(line_num);
1190 1167
          error.file(_filename);
1191 1168
          throw;
1192 1169
        }
1193 1170
      }
1194 1171

	
1195 1172
      if (!nodes_done) {
1196 1173
        throw FormatError("Section @nodes not found");
1197 1174
      }
1198 1175

	
1199 1176
      if (!arcs_done) {
1200 1177
        throw FormatError("Section @arcs not found");
1201 1178
      }
1202 1179

	
1203 1180
      if (!attributes_done && !_attributes.empty()) {
1204 1181
        throw FormatError("Section @attributes not found");
1205 1182
      }
1206 1183

	
1207 1184
    }
1208 1185

	
1209 1186
    /// @}
1210 1187

	
1211 1188
  };
1212 1189

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

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

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

	
1213 1221
  template <typename Graph>
1214 1222
  class GraphReader;
1215

	
1216
  /// \brief Return a \ref GraphReader class
1217
  ///
1218
  /// This function just returns a \ref GraphReader class.
1219
  /// \relates GraphReader
1223
 
1220 1224
  template <typename Graph>
1221
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is = std::cin) {
1222
    GraphReader<Graph> tmp(graph, is);
1223
    return tmp;
1224
  }
1225

	
1226
  /// \brief Return a \ref GraphReader class
1227
  ///
1228
  /// This function just returns a \ref GraphReader class.
1229
  /// \relates GraphReader
1225
  GraphReader<Graph> graphReader(Graph& graph, 
1226
                                 std::istream& is = std::cin);
1230 1227
  template <typename Graph>
1231
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn) {
1232
    GraphReader<Graph> tmp(graph, fn);
1233
    return tmp;
1234
  }
1235

	
1236
  /// \brief Return a \ref GraphReader class
1237
  ///
1238
  /// This function just returns a \ref GraphReader class.
1239
  /// \relates GraphReader
1228
  GraphReader<Graph> graphReader(Graph& graph, const std::string& fn);
1240 1229
  template <typename Graph>
1241
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
1242
    GraphReader<Graph> tmp(graph, fn);
1243
    return tmp;
1244
  }
1230
  GraphReader<Graph> graphReader(Graph& graph, const char *fn);
1245 1231

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

	
1265 1251
    typedef _Graph Graph;
1266 1252
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1267 1253

	
1268 1254
  private:
1269 1255

	
1270 1256
    std::istream* _is;
1271 1257
    bool local_is;
1272 1258
    std::string _filename;
1273 1259

	
1274 1260
    Graph& _graph;
1275 1261

	
1276 1262
    std::string _nodes_caption;
1277 1263
    std::string _edges_caption;
1278 1264
    std::string _attributes_caption;
1279 1265

	
1280 1266
    typedef std::map<std::string, Node> NodeIndex;
1281 1267
    NodeIndex _node_index;
1282 1268
    typedef std::map<std::string, Edge> EdgeIndex;
1283 1269
    EdgeIndex _edge_index;
1284 1270

	
1285 1271
    typedef std::vector<std::pair<std::string,
1286 1272
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;
1287 1273
    NodeMaps _node_maps;
1288 1274

	
1289 1275
    typedef std::vector<std::pair<std::string,
1290 1276
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1291 1277
    EdgeMaps _edge_maps;
1292 1278

	
1293 1279
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*>
1294 1280
      Attributes;
1295 1281
    Attributes _attributes;
1296 1282

	
1297 1283
    bool _use_nodes;
1298 1284
    bool _use_edges;
1299 1285

	
1300 1286
    bool _skip_nodes;
1301 1287
    bool _skip_edges;
1302 1288

	
1303 1289
    int line_num;
1304 1290
    std::istringstream line;
1305 1291

	
1306 1292
  public:
1307 1293

	
1308 1294
    /// \brief Constructor
1309 1295
    ///
1310 1296
    /// Construct an undirected graph reader, which reads from the given
1311 1297
    /// input stream.
1312 1298
    GraphReader(Graph& graph, std::istream& is = std::cin)
1313 1299
      : _is(&is), local_is(false), _graph(graph),
1314 1300
        _use_nodes(false), _use_edges(false),
1315 1301
        _skip_nodes(false), _skip_edges(false) {}
1316 1302

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

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

	
1347 1333
    /// \brief Destructor
1348 1334
    ~GraphReader() {
1349 1335
      for (typename NodeMaps::iterator it = _node_maps.begin();
1350 1336
           it != _node_maps.end(); ++it) {
1351 1337
        delete it->second;
1352 1338
      }
1353 1339

	
1354 1340
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1355 1341
           it != _edge_maps.end(); ++it) {
1356 1342
        delete it->second;
1357 1343
      }
1358 1344

	
1359 1345
      for (typename Attributes::iterator it = _attributes.begin();
1360 1346
           it != _attributes.end(); ++it) {
1361 1347
        delete it->second;
1362 1348
      }
1363 1349

	
1364 1350
      if (local_is) {
1365 1351
        delete _is;
1366 1352
      }
1367 1353

	
1368 1354
    }
1369 1355

	
1370 1356
  private:
1371
    friend GraphReader<Graph> graphReader<>(Graph& graph, std::istream& is);
1372
    friend GraphReader<Graph> graphReader<>(Graph& graph,
1373
                                            const std::string& fn);
1374
    friend GraphReader<Graph> graphReader<>(Graph& graph, const char *fn);
1357
    template <typename GR>
1358
    friend GraphReader<GR> graphReader(GR& graph, std::istream& is);
1359
    template <typename GR>
1360
    friend GraphReader<GR> graphReader(GR& graph, const std::string& fn); 
1361
    template <typename GR>
1362
    friend GraphReader<GR> graphReader(GR& graph, const char *fn);
1375 1363

	
1376 1364
    GraphReader(GraphReader& other)
1377 1365
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1378 1366
        _use_nodes(other._use_nodes), _use_edges(other._use_edges),
1379 1367
        _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1380 1368

	
1381 1369
      other._is = 0;
1382 1370
      other.local_is = false;
1383 1371

	
1384 1372
      _node_index.swap(other._node_index);
1385 1373
      _edge_index.swap(other._edge_index);
1386 1374

	
1387 1375
      _node_maps.swap(other._node_maps);
1388 1376
      _edge_maps.swap(other._edge_maps);
1389 1377
      _attributes.swap(other._attributes);
1390 1378

	
1391 1379
      _nodes_caption = other._nodes_caption;
1392 1380
      _edges_caption = other._edges_caption;
1393 1381
      _attributes_caption = other._attributes_caption;
1394 1382

	
1395 1383
    }
1396 1384

	
1397 1385
    GraphReader& operator=(const GraphReader&);
1398 1386

	
1399 1387
  public:
1400 1388

	
1401 1389
    /// \name Reading rules
1402 1390
    /// @{
1403 1391

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

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

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

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

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

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

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

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

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

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

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

	
1550 1538
    /// @}
1551 1539

	
1552 1540
    /// \name Select section by name
1553 1541
    /// @{
1554 1542

	
1555 1543
    /// \brief Set \c \@nodes section to be read
1556 1544
    ///
1557 1545
    /// Set \c \@nodes section to be read.
1558 1546
    GraphReader& nodes(const std::string& caption) {
1559 1547
      _nodes_caption = caption;
1560 1548
      return *this;
1561 1549
    }
1562 1550

	
1563 1551
    /// \brief Set \c \@edges section to be read
1564 1552
    ///
1565 1553
    /// Set \c \@edges section to be read.
1566 1554
    GraphReader& edges(const std::string& caption) {
... ...
@@ -1851,384 +1839,414 @@
1851 1839

	
1852 1840
        std::string source_token;
1853 1841
        std::string target_token;
1854 1842

	
1855 1843
        if (!_reader_bits::readToken(line, source_token))
1856 1844
          throw FormatError("Node u not found");
1857 1845

	
1858 1846
        if (!_reader_bits::readToken(line, target_token))
1859 1847
          throw FormatError("Node v not found");
1860 1848

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

	
1872 1860
        Edge e;
1873 1861
        if (!_use_edges) {
1874 1862

	
1875 1863
          typename NodeIndex::iterator it;
1876 1864

	
1877 1865
          it = _node_index.find(source_token);
1878 1866
          if (it == _node_index.end()) {
1879 1867
            std::ostringstream msg;
1880 1868
            msg << "Item not found: " << source_token;
1881 1869
            throw FormatError(msg.str());
1882 1870
          }
1883 1871
          Node source = it->second;
1884 1872

	
1885 1873
          it = _node_index.find(target_token);
1886 1874
          if (it == _node_index.end()) {
1887 1875
            std::ostringstream msg;
1888 1876
            msg << "Item not found: " << target_token;
1889 1877
            throw FormatError(msg.str());
1890 1878
          }
1891 1879
          Node target = it->second;
1892 1880

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

	
1909 1897
        for (int i = 0; i < static_cast<int>(_edge_maps.size()); ++i) {
1910 1898
          _edge_maps[i].second->set(e, tokens[map_index[i]]);
1911 1899
        }
1912 1900

	
1913 1901
      }
1914 1902
      if (readSuccess()) {
1915 1903
        line.putback(c);
1916 1904
      }
1917 1905
    }
1918 1906

	
1919 1907
    void readAttributes() {
1920 1908

	
1921 1909
      std::set<std::string> read_attr;
1922 1910

	
1923 1911
      char c;
1924 1912
      while (readLine() && line >> c && c != '@') {
1925 1913
        line.putback(c);
1926 1914

	
1927 1915
        std::string attr, token;
1928 1916
        if (!_reader_bits::readToken(line, attr))
1929 1917
          throw FormatError("Attribute name not found");
1930 1918
        if (!_reader_bits::readToken(line, token))
1931 1919
          throw FormatError("Attribute value not found");
1932 1920
        if (line >> c)
1933 1921
          throw FormatError("Extra character at the end of line");
1934 1922

	
1935 1923
        {
1936 1924
          std::set<std::string>::iterator it = read_attr.find(attr);
1937 1925
          if (it != read_attr.end()) {
1938 1926
            std::ostringstream msg;
1939 1927
            msg << "Multiple occurence of attribute: " << attr;
1940 1928
            throw FormatError(msg.str());
1941 1929
          }
1942 1930
          read_attr.insert(attr);
1943 1931
        }
1944 1932

	
1945 1933
        {
1946 1934
          typename Attributes::iterator it = _attributes.lower_bound(attr);
1947 1935
          while (it != _attributes.end() && it->first == attr) {
1948 1936
            it->second->set(token);
1949 1937
            ++it;
1950 1938
          }
1951 1939
        }
1952 1940

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

	
1967 1955
  public:
1968 1956

	
1969 1957
    /// \name Execution of the reader
1970 1958
    /// @{
1971 1959

	
1972 1960
    /// \brief Start the batch processing
1973 1961
    ///
1974 1962
    /// This function starts the batch processing
1975 1963
    void run() {
1976 1964

	
1977 1965
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1978 1966

	
1979 1967
      bool nodes_done = _skip_nodes;
1980 1968
      bool edges_done = _skip_edges;
1981 1969
      bool attributes_done = false;
1982 1970

	
1983 1971
      line_num = 0;
1984 1972
      readLine();
1985 1973
      skipSection();
1986 1974

	
1987 1975
      while (readSuccess()) {
1988 1976
        try {
1989 1977
          char c;
1990 1978
          std::string section, caption;
1991 1979
          line >> c;
1992 1980
          _reader_bits::readToken(line, section);
1993 1981
          _reader_bits::readToken(line, caption);
1994 1982

	
1995 1983
          if (line >> c)
1996 1984
            throw FormatError("Extra character at the end of line");
1997 1985

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

	
2025 2013
      if (!nodes_done) {
2026 2014
        throw FormatError("Section @nodes not found");
2027 2015
      }
2028 2016

	
2029 2017
      if (!edges_done) {
2030 2018
        throw FormatError("Section @edges not found");
2031 2019
      }
2032 2020

	
2033 2021
      if (!attributes_done && !_attributes.empty()) {
2034 2022
        throw FormatError("Section @attributes not found");
2035 2023
      }
2036 2024

	
2037 2025
    }
2038 2026

	
2039 2027
    /// @}
2040 2028

	
2041 2029
  };
2042 2030

	
2031
  /// \brief Return a \ref GraphReader class
2032
  ///
2033
  /// This function just returns a \ref GraphReader class.
2034
  /// \relates GraphReader
2035
  template <typename Graph>
2036
  GraphReader<Graph> graphReader(Graph& graph, std::istream& is) {
2037
    GraphReader<Graph> tmp(graph, is);
2038
    return tmp;
2039
  }
2040

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

	
2051
  /// \brief Return a \ref GraphReader class
2052
  ///
2053
  /// This function just returns a \ref GraphReader class.
2054
  /// \relates GraphReader
2055
  template <typename Graph>
2056
  GraphReader<Graph> graphReader(Graph& graph, const char* fn) {
2057
    GraphReader<Graph> tmp(graph, fn);
2058
    return tmp;
2059
  }
2060

	
2043 2061
  class SectionReader;
2044 2062

	
2045 2063
  SectionReader sectionReader(std::istream& is);
2046 2064
  SectionReader sectionReader(const std::string& fn);
2047 2065
  SectionReader sectionReader(const char* fn);
2048 2066

	
2049 2067
  /// \ingroup lemon_io
2050 2068
  ///
2051 2069
  /// \brief Section reader class
2052 2070
  ///
2053 2071
  /// In the \ref lgf-format "LGF" file extra sections can be placed,
2054 2072
  /// which contain any data in arbitrary format. Such sections can be
2055 2073
  /// read with this class. A reading rule can be added to the class
2056 2074
  /// with two different functions. With the \c sectionLines() function a
2057 2075
  /// functor can process the section line-by-line, while with the \c
2058 2076
  /// sectionStream() member the section can be read from an input
2059 2077
  /// stream.
2060 2078
  class SectionReader {
2061 2079
  private:
2062 2080

	
2063 2081
    std::istream* _is;
2064 2082
    bool local_is;
2065 2083
    std::string _filename;
2066 2084

	
2067 2085
    typedef std::map<std::string, _reader_bits::Section*> Sections;
2068 2086
    Sections _sections;
2069 2087

	
2070 2088
    int line_num;
2071 2089
    std::istringstream line;
2072 2090

	
2073 2091
  public:
2074 2092

	
2075 2093
    /// \brief Constructor
2076 2094
    ///
2077 2095
    /// Construct a section reader, which reads from the given input
2078 2096
    /// stream.
2079 2097
    SectionReader(std::istream& is)
2080 2098
      : _is(&is), local_is(false) {}
2081 2099

	
2082 2100
    /// \brief Constructor
2083 2101
    ///
2084 2102
    /// Construct a section reader, which reads from the given file.
2085 2103
    SectionReader(const std::string& fn)
2086 2104
      : _is(new std::ifstream(fn.c_str())), local_is(true),
2087 2105
        _filename(fn) {
2088 2106
      if (!(*_is)) {
2089 2107
        delete _is;
2090 2108
        throw IoError("Cannot open file", fn);
2091 2109
      }
2092 2110
    }
2093 2111

	
2094 2112
    /// \brief Constructor
2095 2113
    ///
2096 2114
    /// Construct a section reader, which reads from the given file.
2097 2115
    SectionReader(const char* fn)
2098 2116
      : _is(new std::ifstream(fn)), local_is(true),
2099 2117
        _filename(fn) {
2100 2118
      if (!(*_is)) {
2101 2119
        delete _is;
2102 2120
        throw IoError("Cannot open file", fn);
2103 2121
      }
2104 2122
    }
2105 2123

	
2106 2124
    /// \brief Destructor
2107 2125
    ~SectionReader() {
2108 2126
      for (Sections::iterator it = _sections.begin();
2109 2127
           it != _sections.end(); ++it) {
2110 2128
        delete it->second;
2111 2129
      }
2112 2130

	
2113 2131
      if (local_is) {
2114 2132
        delete _is;
2115 2133
      }
2116 2134

	
2117 2135
    }
2118 2136

	
2119 2137
  private:
2120 2138

	
2121 2139
    friend SectionReader sectionReader(std::istream& is);
2122 2140
    friend SectionReader sectionReader(const std::string& fn);
2123 2141
    friend SectionReader sectionReader(const char* fn);
2124 2142

	
2125 2143
    SectionReader(SectionReader& other)
2126 2144
      : _is(other._is), local_is(other.local_is) {
2127 2145

	
2128 2146
      other._is = 0;
2129 2147
      other.local_is = false;
2130 2148

	
2131 2149
      _sections.swap(other._sections);
2132 2150
    }
2133 2151

	
2134 2152
    SectionReader& operator=(const SectionReader&);
2135 2153

	
2136 2154
  public:
2137 2155

	
2138 2156
    /// \name Section readers
2139 2157
    /// @{
2140 2158

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

	
2185 2203

	
2186 2204
    /// \brief Add a section processor with stream oriented reading
2187 2205
    ///
2188 2206
    /// The first parameter is the type of the section, the second is
2189 2207
    /// a functor, which takes an \c std::istream& and an \c int&
2190 2208
    /// parameter, the latter regard to the line number of stream. The
2191 2209
    /// functor can read the input while the section go on, and the
2192 2210
    /// line number should be modified accordingly.
2193 2211
    template <typename Functor>
2194 2212
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2195 2213
      LEMON_ASSERT(!type.empty(), "Type is empty.");
2196 2214
      LEMON_ASSERT(_sections.find(type) == _sections.end(),
2197 2215
                   "Multiple reading of section.");
2198 2216
      _sections.insert(std::make_pair(type,
2199 2217
         new _reader_bits::StreamSection<Functor>(functor)));
2200 2218
      return *this;
2201 2219
    }
2202 2220

	
2203 2221
    /// @}
2204 2222

	
2205 2223
  private:
2206 2224

	
2207 2225
    bool readLine() {
2208 2226
      std::string str;
2209 2227
      while(++line_num, std::getline(*_is, str)) {
2210 2228
        line.clear(); line.str(str);
2211 2229
        char c;
2212 2230
        if (line >> std::ws >> c && c != '#') {
2213 2231
          line.putback(c);
2214 2232
          return true;
2215 2233
        }
2216 2234
      }
2217 2235
      return false;
2218 2236
    }
2219 2237

	
2220 2238
    bool readSuccess() {
2221 2239
      return static_cast<bool>(*_is);
2222 2240
    }
2223 2241

	
2224 2242
    void skipSection() {
2225 2243
      char c;
2226 2244
      while (readSuccess() && line >> c && c != '@') {
2227 2245
        readLine();
2228 2246
      }
2229 2247
      line.putback(c);
2230 2248
    }
2231 2249

	
2232 2250
  public:
2233 2251

	
2234 2252

	
Ignore white space 384 line context
... ...
@@ -161,566 +161,548 @@
161 161
      virtual void sort(std::vector<Item>& items) {
162 162
        GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
163 163
        std::sort(items.begin(), items.end(), less);
164 164
      }
165 165
    };
166 166

	
167 167
    class ValueStorageBase {
168 168
    public:
169 169
      ValueStorageBase() {}
170 170
      virtual ~ValueStorageBase() {}
171 171

	
172 172
      virtual std::string get() = 0;
173 173
    };
174 174

	
175 175
    template <typename _Value, typename _Converter = DefaultConverter<_Value> >
176 176
    class ValueStorage : public ValueStorageBase {
177 177
    public:
178 178
      typedef _Value Value;
179 179
      typedef _Converter Converter;
180 180

	
181 181
    private:
182 182
      const Value& _value;
183 183
      Converter _converter;
184 184

	
185 185
    public:
186 186
      ValueStorage(const Value& value, const Converter& converter = Converter())
187 187
        : _value(value), _converter(converter) {}
188 188

	
189 189
      virtual std::string get() {
190 190
        return _converter(_value);
191 191
      }
192 192
    };
193 193

	
194 194
    template <typename Value>
195 195
    struct MapLookUpConverter {
196 196
      const std::map<Value, std::string>& _map;
197 197

	
198 198
      MapLookUpConverter(const std::map<Value, std::string>& map)
199 199
        : _map(map) {}
200 200

	
201 201
      std::string operator()(const Value& str) {
202 202
        typename std::map<Value, std::string>::const_iterator it =
203 203
          _map.find(str);
204 204
        if (it == _map.end()) {
205 205
          throw FormatError("Item not found");
206 206
        }
207 207
        return it->second;
208 208
      }
209 209
    };
210 210

	
211 211
    template <typename Graph>
212 212
    struct GraphArcLookUpConverter {
213 213
      const Graph& _graph;
214 214
      const std::map<typename Graph::Edge, std::string>& _map;
215 215

	
216 216
      GraphArcLookUpConverter(const Graph& graph,
217 217
                              const std::map<typename Graph::Edge,
218 218
                                             std::string>& map)
219 219
        : _graph(graph), _map(map) {}
220 220

	
221 221
      std::string operator()(const typename Graph::Arc& val) {
222 222
        typename std::map<typename Graph::Edge, std::string>
223 223
          ::const_iterator it = _map.find(val);
224 224
        if (it == _map.end()) {
225 225
          throw FormatError("Item not found");
226 226
        }
227 227
        return (_graph.direction(val) ? '+' : '-') + it->second;
228 228
      }
229 229
    };
230 230

	
231 231
    inline bool isWhiteSpace(char c) {
232 232
      return c == ' ' || c == '\t' || c == '\v' ||
233 233
        c == '\n' || c == '\r' || c == '\f';
234 234
    }
235 235

	
236 236
    inline bool isEscaped(char c) {
237 237
      return c == '\\' || c == '\"' || c == '\'' ||
238 238
        c == '\a' || c == '\b';
239 239
    }
240 240

	
241 241
    inline static void writeEscape(std::ostream& os, char c) {
242 242
      switch (c) {
243 243
      case '\\':
244 244
        os << "\\\\";
245 245
        return;
246 246
      case '\"':
247 247
        os << "\\\"";
248 248
        return;
249 249
      case '\a':
250 250
        os << "\\a";
251 251
        return;
252 252
      case '\b':
253 253
        os << "\\b";
254 254
        return;
255 255
      case '\f':
256 256
        os << "\\f";
257 257
        return;
258 258
      case '\r':
259 259
        os << "\\r";
260 260
        return;
261 261
      case '\n':
262 262
        os << "\\n";
263 263
        return;
264 264
      case '\t':
265 265
        os << "\\t";
266 266
        return;
267 267
      case '\v':
268 268
        os << "\\v";
269 269
        return;
270 270
      default:
271 271
        if (c < 0x20) {
272 272
          std::ios::fmtflags flags = os.flags();
273 273
          os << '\\' << std::oct << static_cast<int>(c);
274 274
          os.flags(flags);
275 275
        } else {
276 276
          os << c;
277 277
        }
278 278
        return;
279 279
      }
280 280
    }
281 281

	
282 282
    inline bool requireEscape(const std::string& str) {
283 283
      if (str.empty() || str[0] == '@') return true;
284 284
      std::istringstream is(str);
285 285
      char c;
286 286
      while (is.get(c)) {
287 287
        if (isWhiteSpace(c) || isEscaped(c)) {
288 288
          return true;
289 289
        }
290 290
      }
291 291
      return false;
292 292
    }
293 293

	
294 294
    inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
295 295

	
296 296
      if (requireEscape(str)) {
297 297
        os << '\"';
298 298
        for (std::string::const_iterator it = str.begin();
299 299
             it != str.end(); ++it) {
300 300
          writeEscape(os, *it);
301 301
        }
302 302
        os << '\"';
303 303
      } else {
304 304
        os << str;
305 305
      }
306 306
      return os;
307 307
    }
308 308

	
309 309
    class Section {
310 310
    public:
311 311
      virtual ~Section() {}
312 312
      virtual void process(std::ostream& os) = 0;
313 313
    };
314 314

	
315 315
    template <typename Functor>
316 316
    class LineSection : public Section {
317 317
    private:
318 318

	
319 319
      Functor _functor;
320 320

	
321 321
    public:
322 322

	
323 323
      LineSection(const Functor& functor) : _functor(functor) {}
324 324
      virtual ~LineSection() {}
325 325

	
326 326
      virtual void process(std::ostream& os) {
327 327
        std::string line;
328 328
        while (!(line = _functor()).empty()) os << line << std::endl;
329 329
      }
330 330
    };
331 331

	
332 332
    template <typename Functor>
333 333
    class StreamSection : public Section {
334 334
    private:
335 335

	
336 336
      Functor _functor;
337 337

	
338 338
    public:
339 339

	
340 340
      StreamSection(const Functor& functor) : _functor(functor) {}
341 341
      virtual ~StreamSection() {}
342 342

	
343 343
      virtual void process(std::ostream& os) {
344 344
        _functor(os);
345 345
      }
346 346
    };
347 347

	
348 348
  }
349 349

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

	
353
  /// \brief Return a \ref DigraphWriter class
354
  ///
355
  /// This function just returns a \ref DigraphWriter class.
356
  /// \relates DigraphWriter
357 353
  template <typename Digraph>
358 354
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
359
                                       std::ostream& os = std::cout) {
360
    DigraphWriter<Digraph> tmp(digraph, os);
361
    return tmp;
362
  }
363

	
364
  /// \brief Return a \ref DigraphWriter class
365
  ///
366
  /// This function just returns a \ref DigraphWriter class.
367
  /// \relates DigraphWriter
355
                                       std::ostream& os = std::cout);
368 356
  template <typename Digraph>
369 357
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
370
                                       const std::string& fn) {
371
    DigraphWriter<Digraph> tmp(digraph, fn);
372
    return tmp;
373
  }
358
                                       const std::string& fn);
374 359

	
375
  /// \brief Return a \ref DigraphWriter class
376
  ///
377
  /// This function just returns a \ref DigraphWriter class.
378
  /// \relates DigraphWriter
379 360
  template <typename Digraph>
380 361
  DigraphWriter<Digraph> digraphWriter(const Digraph& digraph,
381
                                       const char* fn) {
382
    DigraphWriter<Digraph> tmp(digraph, fn);
383
    return tmp;
384
  }
362
                                       const char* fn);
363

	
385 364

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

	
434 413
    typedef _Digraph Digraph;
435 414
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
436 415

	
437 416
  private:
438 417

	
439 418

	
440 419
    std::ostream* _os;
441 420
    bool local_os;
442 421

	
443 422
    const Digraph& _digraph;
444 423

	
445 424
    std::string _nodes_caption;
446 425
    std::string _arcs_caption;
447 426
    std::string _attributes_caption;
448 427

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

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

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

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

	
466 445
    bool _skip_nodes;
467 446
    bool _skip_arcs;
468 447

	
469 448
  public:
470 449

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

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

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

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

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

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

	
522 501
      if (local_os) {
523 502
        delete _os;
524 503
      }
525 504
    }
526 505

	
527 506
  private:
528 507

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

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

	
540 522
      other._os = 0;
541 523
      other.local_os = false;
542 524

	
543 525
      _node_index.swap(other._node_index);
544 526
      _arc_index.swap(other._arc_index);
545 527

	
546 528
      _node_maps.swap(other._node_maps);
547 529
      _arc_maps.swap(other._arc_maps);
548 530
      _attributes.swap(other._attributes);
549 531

	
550 532
      _nodes_caption = other._nodes_caption;
551 533
      _arcs_caption = other._arcs_caption;
552 534
      _attributes_caption = other._attributes_caption;
553 535
    }
554 536

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

	
557 539
  public:
558 540

	
559 541
    /// \name Writing rules
560 542
    /// @{
561 543

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

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

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

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

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

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

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

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

	
662 644
    /// \name Section captions
663 645
    /// @{
664 646

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

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

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

	
689 671
    /// \name Skipping section
690 672
    /// @{
691 673

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

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

	
710 692
    /// @}
711 693

	
712 694
  private:
713 695

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

	
724 706
      *_os << "@nodes";
725 707
      if (!_nodes_caption.empty()) {
726 708
        _writer_bits::writeToken(*_os << ' ', _nodes_caption);
... ...
@@ -744,539 +726,552 @@
744 726
      if (label == 0) {
745 727
        IdMap<Digraph, Node> id_map(_digraph);
746 728
        _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
747 729
        std::sort(nodes.begin(), nodes.end(), id_less);
748 730
      } else {
749 731
        label->sort(nodes);
750 732
      }
751 733

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

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

	
784 766
      if (label == 0) {
785 767
        for (NodeIt n(_digraph); n != INVALID; ++n) {
786 768
          std::ostringstream os;
787 769
          os << _digraph.id(n);
788 770
          _node_index.insert(std::make_pair(n, os.str()));
789 771
        }
790 772
      } else {
791 773
        for (NodeIt n(_digraph); n != INVALID; ++n) {
792 774
          std::string value = label->get(n);
793 775
          _node_index.insert(std::make_pair(n, value));
794 776
        }
795 777
      }
796 778
    }
797 779

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

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

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

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

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

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

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

	
875 857
      if (label == 0) {
876 858
        for (ArcIt a(_digraph); a != INVALID; ++a) {
877 859
          std::ostringstream os;
878 860
          os << _digraph.id(a);
879 861
          _arc_index.insert(std::make_pair(a, os.str()));
880 862
        }
881 863
      } else {
882 864
        for (ArcIt a(_digraph); a != INVALID; ++a) {
883 865
          std::string value = label->get(a);
884 866
          _arc_index.insert(std::make_pair(a, value));
885 867
        }
886 868
      }
887 869
    }
888 870

	
889 871
    void writeAttributes() {
890 872
      if (_attributes.empty()) return;
891 873
      *_os << "@attributes";
892 874
      if (!_attributes_caption.empty()) {
893 875
        _writer_bits::writeToken(*_os << ' ', _attributes_caption);
894 876
      }
895 877
      *_os << std::endl;
896 878
      for (typename Attributes::iterator it = _attributes.begin();
897 879
           it != _attributes.end(); ++it) {
898 880
        _writer_bits::writeToken(*_os, it->first) << ' ';
899 881
        _writer_bits::writeToken(*_os, it->second->get());
900 882
        *_os << std::endl;
901 883
      }
902 884
    }
903 885

	
904 886
  public:
905 887

	
906 888
    /// \name Execution of the writer
907 889
    /// @{
908 890

	
909 891
    /// \brief Start the batch processing
910 892
    ///
911 893
    /// This function starts the batch processing.
912 894
    void run() {
913 895
      if (!_skip_nodes) {
914 896
        writeNodes();
915 897
      } else {
916 898
        createNodeIndex();
917 899
      }
918 900
      if (!_skip_arcs) {
919 901
        writeArcs();
920 902
      } else {
921 903
        createArcIndex();
922 904
      }
923 905
      writeAttributes();
924 906
    }
925 907

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

	
933 915
    /// @}
934 916
  };
935 917

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

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

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

	
936 951
  template <typename Graph>
937 952
  class GraphWriter;
938 953

	
939
  /// \brief Return a \ref GraphWriter class
940
  ///
941
  /// This function just returns a \ref GraphWriter class.
942
  /// \relates GraphWriter
943 954
  template <typename Graph>
944 955
  GraphWriter<Graph> graphWriter(const Graph& graph,
945
                                 std::ostream& os = std::cout) {
946
    GraphWriter<Graph> tmp(graph, os);
947
    return tmp;
948
  }
949

	
950
  /// \brief Return a \ref GraphWriter class
951
  ///
952
  /// This function just returns a \ref GraphWriter class.
953
  /// \relates GraphWriter
956
                                 std::ostream& os = std::cout);
954 957
  template <typename Graph>
955
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn) {
956
    GraphWriter<Graph> tmp(graph, fn);
957
    return tmp;
958
  }
959

	
960
  /// \brief Return a \ref GraphWriter class
961
  ///
962
  /// This function just returns a \ref GraphWriter class.
963
  /// \relates GraphWriter
958
  GraphWriter<Graph> graphWriter(const Graph& graph, const std::string& fn);
964 959
  template <typename Graph>
965
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn) {
966
    GraphWriter<Graph> tmp(graph, fn);
967
    return tmp;
968
  }
960
  GraphWriter<Graph> graphWriter(const Graph& graph, const char* fn);
969 961

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

	
989 981
    typedef _Graph Graph;
990 982
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
991 983

	
992 984
  private:
993 985

	
994 986

	
995 987
    std::ostream* _os;
996 988
    bool local_os;
997 989

	
998 990
    const Graph& _graph;
999 991

	
1000 992
    std::string _nodes_caption;
1001 993
    std::string _edges_caption;
1002 994
    std::string _attributes_caption;
1003 995

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

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

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

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

	
1021 1013
    bool _skip_nodes;
1022 1014
    bool _skip_edges;
1023 1015

	
1024 1016
  public:
1025 1017

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

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

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

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

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

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

	
1077 1069
      if (local_os) {
1078 1070
        delete _os;
1079 1071
      }
1080 1072
    }
1081 1073

	
1082 1074
  private:
1083 1075

	
1084
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1085
                                            std::ostream& os);
1086
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1087
                                            const std::string& fn);
1088
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1089
                                            const char *fn);
1090

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

	
1095 1090
      other._os = 0;
1096 1091
      other.local_os = false;
1097 1092

	
1098 1093
      _node_index.swap(other._node_index);
1099 1094
      _edge_index.swap(other._edge_index);
1100 1095

	
1101 1096
      _node_maps.swap(other._node_maps);
1102 1097
      _edge_maps.swap(other._edge_maps);
1103 1098
      _attributes.swap(other._attributes);
1104 1099

	
1105 1100
      _nodes_caption = other._nodes_caption;
1106 1101
      _edges_caption = other._edges_caption;
1107 1102
      _attributes_caption = other._attributes_caption;
1108 1103
    }
1109 1104

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

	
1112 1107
  public:
1113 1108

	
1114 1109
    /// \name Writing rules
1115 1110
    /// @{
1116 1111

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

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

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

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

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

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

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

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

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

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

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

	
1263 1258
    /// \name Section captions
1264 1259
    /// @{
1265 1260

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

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

	
1282 1277
    /// \brief Add an additional caption to the \c \@attributes section
... ...
@@ -1345,384 +1340,415 @@
1345 1340
      if (label == 0) {
1346 1341
        IdMap<Graph, Node> id_map(_graph);
1347 1342
        _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1348 1343
        std::sort(nodes.begin(), nodes.end(), id_less);
1349 1344
      } else {
1350 1345
        label->sort(nodes);
1351 1346
      }
1352 1347

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

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

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

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

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

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

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

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

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

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

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

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

	
1505 1500
  public:
1506 1501

	
1507 1502
    /// \name Execution of the writer
1508 1503
    /// @{
1509 1504

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

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

	
1534 1529
    /// @}
1535 1530
  };
1536 1531

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

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

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

	
1537 1563
  class SectionWriter;
1538 1564

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

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

	
1557 1583
    std::ostream* _os;
1558 1584
    bool local_os;
1559 1585

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

	
1563 1589
    Sections _sections;
1564 1590

	
1565 1591
  public:
1566 1592

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

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

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

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

	
1603 1629
      if (local_os) {
1604 1630
        delete _os;
1605 1631
      }
1606 1632

	
1607 1633
    }
1608 1634

	
1609 1635
  private:
1610 1636

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

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

	
1618 1644
      other._os = 0;
1619 1645
      other.local_os = false;
1620 1646

	
1621 1647
      _sections.swap(other._sections);
1622 1648
    }
1623 1649

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

	
1626 1652
  public:
1627 1653

	
1628 1654
    /// \name Section writers
1629 1655
    /// @{
1630 1656

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

	
1675 1701

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

	
1690 1716
    /// @}
1691 1717

	
1692 1718
  public:
1693 1719

	
1694 1720

	
1695 1721
    /// \name Execution of the writer
1696 1722
    /// @{
1697 1723

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

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

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

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

	
1719 1745
    /// @}
1720 1746

	
1721 1747
  };
1722 1748

	
1723 1749
  /// \brief Return a \ref SectionWriter class
1724 1750
  ///
1725 1751
  /// This function just returns a \ref SectionWriter class.
1726 1752
  /// \relates SectionWriter
1727 1753
  inline SectionWriter sectionWriter(std::ostream& os) {
1728 1754
    SectionWriter tmp(os);
Ignore white space 384 line context
... ...
@@ -740,347 +740,363 @@
740 740
  /// a zero length path is undefined.
741 741
  ///
742 742
  /// This implementation is completly static, i.e. it can be copy constucted
743 743
  /// or copy assigned from another path, but otherwise it cannot be
744 744
  /// modified.
745 745
  ///
746 746
  /// Being the the most memory efficient path type in LEMON,
747 747
  /// it is intented to be
748 748
  /// used when you want to store a large number of paths.
749 749
  template <typename _Digraph>
750 750
  class StaticPath {
751 751
  public:
752 752

	
753 753
    typedef _Digraph Digraph;
754 754
    typedef typename Digraph::Arc Arc;
755 755

	
756 756
    /// \brief Default constructor
757 757
    ///
758 758
    /// Default constructor
759 759
    StaticPath() : len(0), arcs(0) {}
760 760

	
761 761
    /// \brief Template copy constructor
762 762
    ///
763 763
    /// This path can be initialized from any other path type.
764 764
    template <typename CPath>
765 765
    StaticPath(const CPath& cpath) : arcs(0) {
766 766
      copyPath(*this, cpath);
767 767
    }
768 768

	
769 769
    /// \brief Destructor of the path
770 770
    ///
771 771
    /// Destructor of the path
772 772
    ~StaticPath() {
773 773
      if (arcs) delete[] arcs;
774 774
    }
775 775

	
776 776
    /// \brief Template copy assignment
777 777
    ///
778 778
    /// This path can be made equal to any other path type. It simply
779 779
    /// makes a copy of the given path.
780 780
    template <typename CPath>
781 781
    StaticPath& operator=(const CPath& cpath) {
782 782
      copyPath(*this, cpath);
783 783
      return *this;
784 784
    }
785 785

	
786 786
    /// \brief Iterator class to iterate on the arcs of the paths
787 787
    ///
788 788
    /// This class is used to iterate on the arcs of the paths
789 789
    ///
790 790
    /// Of course it converts to Digraph::Arc
791 791
    class ArcIt {
792 792
      friend class StaticPath;
793 793
    public:
794 794
      /// Default constructor
795 795
      ArcIt() {}
796 796
      /// Invalid constructor
797 797
      ArcIt(Invalid) : path(0), idx(-1) {}
798 798
      /// Initializate the constructor to the first arc of path
799 799
      ArcIt(const StaticPath &_path)
800 800
        : path(&_path), idx(_path.empty() ? -1 : 0) {}
801 801

	
802 802
    private:
803 803

	
804 804
      /// Constructor with starting point
805 805
      ArcIt(const StaticPath &_path, int _idx)
806 806
        : idx(_idx), path(&_path) {}
807 807

	
808 808
    public:
809 809

	
810 810
      ///Conversion to Digraph::Arc
811 811
      operator const Arc&() const {
812 812
        return path->nth(idx);
813 813
      }
814 814

	
815 815
      /// Next arc
816 816
      ArcIt& operator++() {
817 817
        ++idx;
818 818
        if (idx >= path->length()) idx = -1;
819 819
        return *this;
820 820
      }
821 821

	
822 822
      /// Comparison operator
823 823
      bool operator==(const ArcIt& e) const { return idx==e.idx; }
824 824
      /// Comparison operator
825 825
      bool operator!=(const ArcIt& e) const { return idx!=e.idx; }
826 826
      /// Comparison operator
827 827
      bool operator<(const ArcIt& e) const { return idx<e.idx; }
828 828

	
829 829
    private:
830 830
      const StaticPath *path;
831 831
      int idx;
832 832
    };
833 833

	
834 834
    /// \brief The nth arc.
835 835
    ///
836 836
    /// \pre n is in the [0..length() - 1] range
837 837
    const Arc& nth(int n) const {
838 838
      return arcs[n];
839 839
    }
840 840

	
841 841
    /// \brief The arc iterator pointing to the nth arc.
842 842
    ArcIt nthIt(int n) const {
843 843
      return ArcIt(*this, n);
844 844
    }
845 845

	
846 846
    /// \brief The length of the path.
847 847
    int length() const { return len; }
848 848

	
849 849
    /// \brief Return true when the path is empty.
850 850
    int empty() const { return len == 0; }
851 851

	
852 852
    /// \brief Erase all arcs in the digraph.
853 853
    void clear() {
854 854
      len = 0;
855 855
      if (arcs) delete[] arcs;
856 856
      arcs = 0;
857 857
    }
858 858

	
859 859
    /// \brief The first arc of the path.
860 860
    const Arc& front() const {
861 861
      return arcs[0];
862 862
    }
863 863

	
864 864
    /// \brief The last arc of the path.
865 865
    const Arc& back() const {
866 866
      return arcs[len - 1];
867 867
    }
868 868

	
869 869

	
870 870
    typedef True BuildTag;
871 871

	
872 872
    template <typename CPath>
873 873
    void build(const CPath& path) {
874 874
      len = path.length();
875 875
      arcs = new Arc[len];
876 876
      int index = 0;
877 877
      for (typename CPath::ArcIt it(path); it != INVALID; ++it) {
878 878
        arcs[index] = it;
879 879
        ++index;
880 880
      }
881 881
    }
882 882

	
883 883
    template <typename CPath>
884 884
    void buildRev(const CPath& path) {
885 885
      len = path.length();
886 886
      arcs = new Arc[len];
887 887
      int index = len;
888 888
      for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
889 889
        --index;
890 890
        arcs[index] = it;
891 891
      }
892 892
    }
893 893

	
894 894
  private:
895 895
    int len;
896 896
    Arc* arcs;
897 897
  };
898 898

	
899 899
  ///////////////////////////////////////////////////////////////////////
900 900
  // Additional utilities
901 901
  ///////////////////////////////////////////////////////////////////////
902 902

	
903 903
  namespace _path_bits {
904 904

	
905 905
    template <typename Path, typename Enable = void>
906 906
    struct RevPathTagIndicator {
907 907
      static const bool value = false;
908 908
    };
909 909

	
910 910
    template <typename Path>
911 911
    struct RevPathTagIndicator<
912 912
      Path,
913 913
      typename enable_if<typename Path::RevPathTag, void>::type
914 914
      > {
915 915
      static const bool value = true;
916 916
    };
917 917

	
918 918
    template <typename Path, typename Enable = void>
919 919
    struct BuildTagIndicator {
920 920
      static const bool value = false;
921 921
    };
922 922

	
923 923
    template <typename Path>
924 924
    struct BuildTagIndicator<
925 925
      Path,
926 926
      typename enable_if<typename Path::BuildTag, void>::type
927 927
    > {
928 928
      static const bool value = true;
929 929
    };
930 930

	
931 931
    template <typename Target, typename Source,
932
              bool buildEnable = BuildTagIndicator<Target>::value,
933
              bool revEnable = RevPathTagIndicator<Source>::value>
934
    struct PathCopySelector {
932
              bool buildEnable = BuildTagIndicator<Target>::value>
933
    struct PathCopySelectorForward {
935 934
      static void copy(Target& target, const Source& source) {
936 935
        target.clear();
937 936
        for (typename Source::ArcIt it(source); it != INVALID; ++it) {
938 937
          target.addBack(it);
939 938
        }
940 939
      }
941 940
    };
942 941

	
943 942
    template <typename Target, typename Source>
944
    struct PathCopySelector<Target, Source, false, true> {
943
    struct PathCopySelectorForward<Target, Source, true> {
944
      static void copy(Target& target, const Source& source) {
945
        target.clear();
946
        target.build(source);
947
      }
948
    };
949

	
950
    template <typename Target, typename Source,
951
              bool buildEnable = BuildTagIndicator<Target>::value>
952
    struct PathCopySelectorBackward {
945 953
      static void copy(Target& target, const Source& source) {
946 954
        target.clear();
947 955
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
948 956
          target.addFront(it);
949 957
        }
950 958
      }
951 959
    };
952 960

	
953 961
    template <typename Target, typename Source>
954
    struct PathCopySelector<Target, Source, true, false> {
955
      static void copy(Target& target, const Source& source) {
956
        target.clear();
957
        target.build(source);
958
      }
959
    };
960

	
961
    template <typename Target, typename Source>
962
    struct PathCopySelector<Target, Source, true, true> {
962
    struct PathCopySelectorBackward<Target, Source, true> {
963 963
      static void copy(Target& target, const Source& source) {
964 964
        target.clear();
965 965
        target.buildRev(source);
966 966
      }
967 967
    };
968 968

	
969
    
970
    template <typename Target, typename Source,
971
              bool revEnable = RevPathTagIndicator<Source>::value>
972
    struct PathCopySelector {
973
      static void copy(Target& target, const Source& source) {
974
        PathCopySelectorForward<Target, Source>::copy(target, source);
975
      }      
976
    };
977

	
978
    template <typename Target, typename Source>
979
    struct PathCopySelector<Target, Source, true> {
980
      static void copy(Target& target, const Source& source) {
981
        PathCopySelectorBackward<Target, Source>::copy(target, source);
982
      }      
983
    };
984

	
969 985
  }
970 986

	
971 987

	
972 988
  /// \brief Make a copy of a path.
973 989
  ///
974 990
  ///  This function makes a copy of a path.
975 991
  template <typename Target, typename Source>
976 992
  void copyPath(Target& target, const Source& source) {
977 993
    checkConcept<concepts::PathDumper<typename Source::Digraph>, Source>();
978 994
    _path_bits::PathCopySelector<Target, Source>::copy(target, source);
979 995
  }
980 996

	
981 997
  /// \brief Check the consistency of a path.
982 998
  ///
983 999
  /// This function checks that the target of each arc is the same
984 1000
  /// as the source of the next one.
985 1001
  ///
986 1002
  template <typename Digraph, typename Path>
987 1003
  bool checkPath(const Digraph& digraph, const Path& path) {
988 1004
    typename Path::ArcIt it(path);
989 1005
    if (it == INVALID) return true;
990 1006
    typename Digraph::Node node = digraph.target(it);
991 1007
    ++it;
992 1008
    while (it != INVALID) {
993 1009
      if (digraph.source(it) != node) return false;
994 1010
      node = digraph.target(it);
995 1011
      ++it;
996 1012
    }
997 1013
    return true;
998 1014
  }
999 1015

	
1000 1016
  /// \brief The source of a path
1001 1017
  ///
1002 1018
  /// This function returns the source of the given path.
1003 1019
  template <typename Digraph, typename Path>
1004 1020
  typename Digraph::Node pathSource(const Digraph& digraph, const Path& path) {
1005 1021
    return digraph.source(path.front());
1006 1022
  }
1007 1023

	
1008 1024
  /// \brief The target of a path
1009 1025
  ///
1010 1026
  /// This function returns the target of the given path.
1011 1027
  template <typename Digraph, typename Path>
1012 1028
  typename Digraph::Node pathTarget(const Digraph& digraph, const Path& path) {
1013 1029
    return digraph.target(path.back());
1014 1030
  }
1015 1031

	
1016 1032
  /// \brief Class which helps to iterate through the nodes of a path
1017 1033
  ///
1018 1034
  /// In a sense, the path can be treated as a list of arcs. The
1019 1035
  /// lemon path type stores only this list. As a consequence, it
1020 1036
  /// cannot enumerate the nodes in the path and the zero length paths
1021 1037
  /// cannot have a source node.
1022 1038
  ///
1023 1039
  /// This class implements the node iterator of a path structure. To
1024 1040
  /// provide this feature, the underlying digraph should be passed to
1025 1041
  /// the constructor of the iterator.
1026 1042
  template <typename Path>
1027 1043
  class PathNodeIt {
1028 1044
  private:
1029 1045
    const typename Path::Digraph *_digraph;
1030 1046
    typename Path::ArcIt _it;
1031 1047
    typename Path::Digraph::Node _nd;
1032 1048

	
1033 1049
  public:
1034 1050

	
1035 1051
    typedef typename Path::Digraph Digraph;
1036 1052
    typedef typename Digraph::Node Node;
1037 1053

	
1038 1054
    /// Default constructor
1039 1055
    PathNodeIt() {}
1040 1056
    /// Invalid constructor
1041 1057
    PathNodeIt(Invalid)
1042 1058
      : _digraph(0), _it(INVALID), _nd(INVALID) {}
1043 1059
    /// Constructor
1044 1060
    PathNodeIt(const Digraph& digraph, const Path& path)
1045 1061
      : _digraph(&digraph), _it(path) {
1046 1062
      _nd = (_it != INVALID ? _digraph->source(_it) : INVALID);
1047 1063
    }
1048 1064
    /// Constructor
1049 1065
    PathNodeIt(const Digraph& digraph, const Path& path, const Node& src)
1050 1066
      : _digraph(&digraph), _it(path), _nd(src) {}
1051 1067

	
1052 1068
    ///Conversion to Digraph::Node
1053 1069
    operator Node() const {
1054 1070
      return _nd;
1055 1071
    }
1056 1072

	
1057 1073
    /// Next node
1058 1074
    PathNodeIt& operator++() {
1059 1075
      if (_it == INVALID) _nd = INVALID;
1060 1076
      else {
1061 1077
        _nd = _digraph->target(_it);
1062 1078
        ++_it;
1063 1079
      }
1064 1080
      return *this;
1065 1081
    }
1066 1082

	
1067 1083
    /// Comparison operator
1068 1084
    bool operator==(const PathNodeIt& n) const {
1069 1085
      return _it == n._it && _nd == n._nd;
1070 1086
    }
1071 1087
    /// Comparison operator
1072 1088
    bool operator!=(const PathNodeIt& n) const {
1073 1089
      return _it != n._it || _nd != n._nd;
1074 1090
    }
1075 1091
    /// Comparison operator
1076 1092
    bool operator<(const PathNodeIt& n) const {
1077 1093
      return (_it < n._it && _nd != INVALID);
1078 1094
    }
1079 1095

	
1080 1096
  };
1081 1097

	
1082 1098
  ///@}
1083 1099

	
1084 1100
} // namespace lemon
1085 1101

	
1086 1102
#endif // LEMON_PATH_H
Ignore white space 384 line context
... ...
@@ -155,464 +155,454 @@
155 155
      typedef _Word Word;
156 156

	
157 157
    private:
158 158

	
159 159
      static const int bits = RandomTraits<Word>::bits;
160 160

	
161 161
      static const int length = RandomTraits<Word>::length;
162 162
      static const int shift = RandomTraits<Word>::shift;
163 163

	
164 164
    public:
165 165

	
166 166
      void initState() {
167 167
        static const Word seedArray[4] = {
168 168
          0x12345u, 0x23456u, 0x34567u, 0x45678u
169 169
        };
170 170

	
171 171
        initState(seedArray, seedArray + 4);
172 172
      }
173 173

	
174 174
      void initState(Word seed) {
175 175

	
176 176
        static const Word mul = RandomTraits<Word>::mul;
177 177

	
178 178
        current = state;
179 179

	
180 180
        Word *curr = state + length - 1;
181 181
        curr[0] = seed; --curr;
182 182
        for (int i = 1; i < length; ++i) {
183 183
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
184 184
          --curr;
185 185
        }
186 186
      }
187 187

	
188 188
      template <typename Iterator>
189 189
      void initState(Iterator begin, Iterator end) {
190 190

	
191 191
        static const Word init = RandomTraits<Word>::arrayInit;
192 192
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
193 193
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
194 194

	
195 195

	
196 196
        Word *curr = state + length - 1; --curr;
197 197
        Iterator it = begin; int cnt = 0;
198 198
        int num;
199 199

	
200 200
        initState(init);
201 201

	
202 202
        num = length > end - begin ? length : end - begin;
203 203
        while (num--) {
204 204
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
205 205
            + *it + cnt;
206 206
          ++it; ++cnt;
207 207
          if (it == end) {
208 208
            it = begin; cnt = 0;
209 209
          }
210 210
          if (curr == state) {
211 211
            curr = state + length - 1; curr[0] = state[0];
212 212
          }
213 213
          --curr;
214 214
        }
215 215

	
216 216
        num = length - 1; cnt = length - (curr - state) - 1;
217 217
        while (num--) {
218 218
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
219 219
            - cnt;
220 220
          --curr; ++cnt;
221 221
          if (curr == state) {
222 222
            curr = state + length - 1; curr[0] = state[0]; --curr;
223 223
            cnt = 1;
224 224
          }
225 225
        }
226 226

	
227 227
        state[length - 1] = Word(1) << (bits - 1);
228 228
      }
229 229

	
230 230
      void copyState(const RandomCore& other) {
231 231
        std::copy(other.state, other.state + length, state);
232 232
        current = state + (other.current - other.state);
233 233
      }
234 234

	
235 235
      Word operator()() {
236 236
        if (current == state) fillState();
237 237
        --current;
238 238
        Word rnd = *current;
239 239
        return RandomTraits<Word>::tempering(rnd);
240 240
      }
241 241

	
242 242
    private:
243 243

	
244 244

	
245 245
      void fillState() {
246 246
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
247 247
        static const Word loMask = RandomTraits<Word>::loMask;
248 248
        static const Word hiMask = RandomTraits<Word>::hiMask;
249 249

	
250 250
        current = state + length;
251 251

	
252 252
        register Word *curr = state + length - 1;
253 253
        register long num;
254 254

	
255 255
        num = length - shift;
256 256
        while (num--) {
257 257
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
258 258
            curr[- shift] ^ mask[curr[-1] & 1ul];
259 259
          --curr;
260 260
        }
261 261
        num = shift - 1;
262 262
        while (num--) {
263 263
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
264 264
            curr[length - shift] ^ mask[curr[-1] & 1ul];
265 265
          --curr;
266 266
        }
267 267
        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
268 268
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
269 269

	
270 270
      }
271 271

	
272 272

	
273 273
      Word *current;
274 274
      Word state[length];
275 275

	
276 276
    };
277 277

	
278 278

	
279 279
    template <typename Result,
280 280
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
281 281
    struct Masker {
282 282
      static Result mask(const Result& result) {
283 283
        return Masker<Result, (shift + 1) / 2>::
284 284
          mask(static_cast<Result>(result | (result >> shift)));
285 285
      }
286 286
    };
287 287

	
288 288
    template <typename Result>
289 289
    struct Masker<Result, 1> {
290 290
      static Result mask(const Result& result) {
291 291
        return static_cast<Result>(result | (result >> 1));
292 292
      }
293 293
    };
294 294

	
295 295
    template <typename Result, typename Word,
296 296
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
297 297
              bool last = rest <= std::numeric_limits<Word>::digits>
298 298
    struct IntConversion {
299 299
      static const int bits = std::numeric_limits<Word>::digits;
300 300

	
301 301
      static Result convert(RandomCore<Word>& rnd) {
302 302
        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
303 303
      }
304 304

	
305 305
    };
306 306

	
307 307
    template <typename Result, typename Word, int rest, int shift>
308 308
    struct IntConversion<Result, Word, rest, shift, false> {
309 309
      static const int bits = std::numeric_limits<Word>::digits;
310 310

	
311 311
      static Result convert(RandomCore<Word>& rnd) {
312 312
        return (static_cast<Result>(rnd()) << shift) |
313 313
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
314 314
      }
315 315
    };
316 316

	
317 317

	
318 318
    template <typename Result, typename Word,
319 319
              bool one_word = (std::numeric_limits<Word>::digits <
320 320
                               std::numeric_limits<Result>::digits) >
321 321
    struct Mapping {
322 322
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
323 323
        Word max = Word(bound - 1);
324 324
        Result mask = Masker<Result>::mask(bound - 1);
325 325
        Result num;
326 326
        do {
327 327
          num = IntConversion<Result, Word>::convert(rnd) & mask;
328 328
        } while (num > max);
329 329
        return num;
330 330
      }
331 331
    };
332 332

	
333 333
    template <typename Result, typename Word>
334 334
    struct Mapping<Result, Word, false> {
335 335
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
336 336
        Word max = Word(bound - 1);
337 337
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
338 338
          ::mask(max);
339 339
        Word num;
340 340
        do {
341 341
          num = rnd() & mask;
342 342
        } while (num > max);
343 343
        return num;
344 344
      }
345 345
    };
346 346

	
347
    template <typename Result, int exp, bool pos = (exp >= 0)>
347
    template <typename Result, int exp>
348 348
    struct ShiftMultiplier {
349 349
      static const Result multiplier() {
350 350
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
351 351
        res *= res;
352
        if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
353
        return res;
354
      }
355
    };
356

	
357
    template <typename Result, int exp>
358
    struct ShiftMultiplier<Result, exp, false> {
359
      static const Result multiplier() {
360
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
361
        res *= res;
362 352
        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
363 353
        return res;
364 354
      }
365 355
    };
366 356

	
367 357
    template <typename Result>
368
    struct ShiftMultiplier<Result, 0, true> {
358
    struct ShiftMultiplier<Result, 0> {
369 359
      static const Result multiplier() {
370 360
        return static_cast<Result>(1.0);
371 361
      }
372 362
    };
373 363

	
374 364
    template <typename Result>
375
    struct ShiftMultiplier<Result, -20, true> {
365
    struct ShiftMultiplier<Result, 20> {
376 366
      static const Result multiplier() {
377 367
        return static_cast<Result>(1.0/1048576.0);
378 368
      }
379 369
    };
380 370

	
381 371
    template <typename Result>
382
    struct ShiftMultiplier<Result, -32, true> {
372
    struct ShiftMultiplier<Result, 32> {
383 373
      static const Result multiplier() {
384
        return static_cast<Result>(1.0/424967296.0);
374
        return static_cast<Result>(1.0/4294967296.0);
385 375
      }
386 376
    };
387 377

	
388 378
    template <typename Result>
389
    struct ShiftMultiplier<Result, -53, true> {
379
    struct ShiftMultiplier<Result, 53> {
390 380
      static const Result multiplier() {
391 381
        return static_cast<Result>(1.0/9007199254740992.0);
392 382
      }
393 383
    };
394 384

	
395 385
    template <typename Result>
396
    struct ShiftMultiplier<Result, -64, true> {
386
    struct ShiftMultiplier<Result, 64> {
397 387
      static const Result multiplier() {
398 388
        return static_cast<Result>(1.0/18446744073709551616.0);
399 389
      }
400 390
    };
401 391

	
402 392
    template <typename Result, int exp>
403 393
    struct Shifting {
404 394
      static Result shift(const Result& result) {
405 395
        return result * ShiftMultiplier<Result, exp>::multiplier();
406 396
      }
407 397
    };
408 398

	
409 399
    template <typename Result, typename Word,
410 400
              int rest = std::numeric_limits<Result>::digits, int shift = 0,
411 401
              bool last = rest <= std::numeric_limits<Word>::digits>
412 402
    struct RealConversion{
413 403
      static const int bits = std::numeric_limits<Word>::digits;
414 404

	
415 405
      static Result convert(RandomCore<Word>& rnd) {
416
        return Shifting<Result, - shift - rest>::
406
        return Shifting<Result, shift + rest>::
417 407
          shift(static_cast<Result>(rnd() >> (bits - rest)));
418 408
      }
419 409
    };
420 410

	
421 411
    template <typename Result, typename Word, int rest, int shift>
422 412
    struct RealConversion<Result, Word, rest, shift, false> {
423 413
      static const int bits = std::numeric_limits<Word>::digits;
424 414

	
425 415
      static Result convert(RandomCore<Word>& rnd) {
426
        return Shifting<Result, - shift - bits>::
416
        return Shifting<Result, shift + bits>::
427 417
          shift(static_cast<Result>(rnd())) +
428 418
          RealConversion<Result, Word, rest-bits, shift + bits>::
429 419
          convert(rnd);
430 420
      }
431 421
    };
432 422

	
433 423
    template <typename Result, typename Word>
434 424
    struct Initializer {
435 425

	
436 426
      template <typename Iterator>
437 427
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
438 428
        std::vector<Word> ws;
439 429
        for (Iterator it = begin; it != end; ++it) {
440 430
          ws.push_back(Word(*it));
441 431
        }
442 432
        rnd.initState(ws.begin(), ws.end());
443 433
      }
444 434

	
445 435
      static void init(RandomCore<Word>& rnd, Result seed) {
446 436
        rnd.initState(seed);
447 437
      }
448 438
    };
449 439

	
450 440
    template <typename Word>
451 441
    struct BoolConversion {
452 442
      static bool convert(RandomCore<Word>& rnd) {
453 443
        return (rnd() & 1) == 1;
454 444
      }
455 445
    };
456 446

	
457 447
    template <typename Word>
458 448
    struct BoolProducer {
459 449
      Word buffer;
460 450
      int num;
461 451

	
462 452
      BoolProducer() : num(0) {}
463 453

	
464 454
      bool convert(RandomCore<Word>& rnd) {
465 455
        if (num == 0) {
466 456
          buffer = rnd();
467 457
          num = RandomTraits<Word>::bits;
468 458
        }
469 459
        bool r = (buffer & 1);
470 460
        buffer >>= 1;
471 461
        --num;
472 462
        return r;
473 463
      }
474 464
    };
475 465

	
476 466
  }
477 467

	
478 468
  /// \ingroup misc
479 469
  ///
480 470
  /// \brief Mersenne Twister random number generator
481 471
  ///
482 472
  /// The Mersenne Twister is a twisted generalized feedback
483 473
  /// shift-register generator of Matsumoto and Nishimura. The period
484 474
  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
485 475
  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
486 476
  /// performance of this generator is comparable to the commonly used
487 477
  /// generators.
488 478
  ///
489 479
  /// This implementation is specialized for both 32-bit and 64-bit
490 480
  /// architectures. The generators differ sligthly in the
491 481
  /// initialization and generation phase so they produce two
492 482
  /// completly different sequences.
493 483
  ///
494 484
  /// The generator gives back random numbers of serveral types. To
495 485
  /// get a random number from a range of a floating point type you
496 486
  /// can use one form of the \c operator() or the \c real() member
497 487
  /// function. If you want to get random number from the {0, 1, ...,
498 488
  /// n-1} integer range use the \c operator[] or the \c integer()
499 489
  /// method. And to get random number from the whole range of an
500 490
  /// integer type you can use the argumentless \c integer() or \c
501 491
  /// uinteger() functions. After all you can get random bool with
502 492
  /// equal chance of true and false or given probability of true
503 493
  /// result with the \c boolean() member functions.
504 494
  ///
505 495
  ///\code
506 496
  /// // The commented code is identical to the other
507 497
  /// double a = rnd();                     // [0.0, 1.0)
508 498
  /// // double a = rnd.real();             // [0.0, 1.0)
509 499
  /// double b = rnd(100.0);                // [0.0, 100.0)
510 500
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
511 501
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
512 502
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
513 503
  /// int d = rnd[100000];                  // 0..99999
514 504
  /// // int d = rnd.integer(100000);       // 0..99999
515 505
  /// int e = rnd[6] + 1;                   // 1..6
516 506
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
517 507
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
518 508
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
519 509
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
520 510
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
521 511
  ///\endcode
522 512
  ///
523 513
  /// LEMON provides a global instance of the random number
524 514
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
525 515
  /// good programming convenience to use this global generator to get
526 516
  /// random numbers.
527 517
  class Random {
528 518
  private:
529 519

	
530 520
    // Architecture word
531 521
    typedef unsigned long Word;
532 522

	
533 523
    _random_bits::RandomCore<Word> core;
534 524
    _random_bits::BoolProducer<Word> bool_producer;
535 525

	
536 526

	
537 527
  public:
538 528

	
539 529
    ///\name Initialization
540 530
    ///
541 531
    /// @{
542 532

	
543 533
    ///\name Initialization
544 534
    ///
545 535
    /// @{
546 536

	
547 537
    /// \brief Default constructor
548 538
    ///
549 539
    /// Constructor with constant seeding.
550 540
    Random() { core.initState(); }
551 541

	
552 542
    /// \brief Constructor with seed
553 543
    ///
554 544
    /// Constructor with seed. The current number type will be converted
555 545
    /// to the architecture word type.
556 546
    template <typename Number>
557 547
    Random(Number seed) {
558 548
      _random_bits::Initializer<Number, Word>::init(core, seed);
559 549
    }
560 550

	
561 551
    /// \brief Constructor with array seeding
562 552
    ///
563 553
    /// Constructor with array seeding. The given range should contain
564 554
    /// any number type and the numbers will be converted to the
565 555
    /// architecture word type.
566 556
    template <typename Iterator>
567 557
    Random(Iterator begin, Iterator end) {
568 558
      typedef typename std::iterator_traits<Iterator>::value_type Number;
569 559
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
570 560
    }
571 561

	
572 562
    /// \brief Copy constructor
573 563
    ///
574 564
    /// Copy constructor. The generated sequence will be identical to
575 565
    /// the other sequence. It can be used to save the current state
576 566
    /// of the generator and later use it to generate the same
577 567
    /// sequence.
578 568
    Random(const Random& other) {
579 569
      core.copyState(other.core);
580 570
    }
581 571

	
582 572
    /// \brief Assign operator
583 573
    ///
584 574
    /// Assign operator. The generated sequence will be identical to
585 575
    /// the other sequence. It can be used to save the current state
586 576
    /// of the generator and later use it to generate the same
587 577
    /// sequence.
588 578
    Random& operator=(const Random& other) {
589 579
      if (&other != this) {
590 580
        core.copyState(other.core);
591 581
      }
592 582
      return *this;
593 583
    }
594 584

	
595 585
    /// \brief Seeding random sequence
596 586
    ///
597 587
    /// Seeding the random sequence. The current number type will be
598 588
    /// converted to the architecture word type.
599 589
    template <typename Number>
600 590
    void seed(Number seed) {
601 591
      _random_bits::Initializer<Number, Word>::init(core, seed);
602 592
    }
603 593

	
604 594
    /// \brief Seeding random sequence
605 595
    ///
606 596
    /// Seeding the random sequence. The given range should contain
607 597
    /// any number type and the numbers will be converted to the
608 598
    /// architecture word type.
609 599
    template <typename Iterator>
610 600
    void seed(Iterator begin, Iterator end) {
611 601
      typedef typename std::iterator_traits<Iterator>::value_type Number;
612 602
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
613 603
    }
614 604

	
615 605
    /// \brief Seeding from file or from process id and time
616 606
    ///
617 607
    /// By default, this function calls the \c seedFromFile() member
618 608
    /// function with the <tt>/dev/urandom</tt> file. If it does not success,
0 comments (0 inline)