gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Move to private copy constrcutors
0 2 0
default
2 files changed with 201 insertions and 148 deletions:
↑ Collapse diff ↑
Ignore white space 192 line context
... ...
@@ -293,365 +293,380 @@
293 293
      if (!is.get(c)) 
294 294
	return is;
295 295

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

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

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

	
331 331
      Functor _functor;
332 332

	
333 333
    public:
334 334
      
335 335
      LineSection(const Functor& functor) : _functor(functor) {}
336 336
      virtual ~LineSection() {}
337 337

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

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

	
363 363
      Functor _functor;
364 364

	
365 365
    public:
366 366
      
367 367
      StreamSection(const Functor& functor) : _functor(functor) {}
368 368
      virtual ~StreamSection() {} 
369 369

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

	
389
  template <typename Digraph>
390
  class DigraphReader;
391

	
392
  template <typename Digraph>
393
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph);
394

	
395
  template <typename Digraph>
396
  DigraphReader<Digraph> digraphReader(const std::string& fn, Digraph& digraph);
397

	
398
  template <typename Digraph>
399
  DigraphReader<Digraph> digraphReader(const char *fn, Digraph& digraph);
400

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

	
442 454
    typedef _Digraph Digraph;
443 455
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
444 456
    
445 457
  private:
446 458

	
447 459

	
448 460
    std::istream* _is;
449 461
    bool local_is;
450 462

	
451 463
    Digraph& _digraph;
452 464

	
453 465
    std::string _nodes_caption;
454 466
    std::string _arcs_caption;
455 467
    std::string _attributes_caption;
456 468

	
457 469
    typedef std::map<std::string, Node> NodeIndex;
458 470
    NodeIndex _node_index;
459 471
    typedef std::map<std::string, Arc> ArcIndex;
460 472
    ArcIndex _arc_index;
461 473
    
462 474
    typedef std::vector<std::pair<std::string, 
463 475
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
464 476
    NodeMaps _node_maps; 
465 477

	
466 478
    typedef std::vector<std::pair<std::string,
467 479
      _reader_bits::MapStorageBase<Arc>*> >ArcMaps;
468 480
    ArcMaps _arc_maps;
469 481

	
470 482
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
471 483
      Attributes;
472 484
    Attributes _attributes;
473 485

	
474 486
    bool _use_nodes;
475 487
    bool _use_arcs;
476 488

	
477 489
    bool _skip_nodes;
478 490
    bool _skip_arcs;
479 491

	
480 492
    int line_num;
481 493
    std::istringstream line;
482 494

	
483 495
  public:
484 496

	
485 497
    /// \brief Constructor
486 498
    ///
487 499
    /// Construct a directed graph reader, which reads from the given
488 500
    /// input stream.
489 501
    DigraphReader(std::istream& is, Digraph& digraph) 
490 502
      : _is(&is), local_is(false), _digraph(digraph),
491 503
	_use_nodes(false), _use_arcs(false),
492 504
	_skip_nodes(false), _skip_arcs(false) {}
493 505

	
494 506
    /// \brief Constructor
495 507
    ///
496 508
    /// Construct a directed graph reader, which reads from the given
497 509
    /// file.
498 510
    DigraphReader(const std::string& fn, Digraph& digraph) 
499 511
      : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph),
500 512
    	_use_nodes(false), _use_arcs(false),
501 513
	_skip_nodes(false), _skip_arcs(false) {}
502 514
    
503 515
    /// \brief Constructor
504 516
    ///
505 517
    /// Construct a directed graph reader, which reads from the given
506 518
    /// file.
507 519
    DigraphReader(const char* fn, Digraph& digraph) 
508 520
      : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph),
509 521
    	_use_nodes(false), _use_arcs(false),
510 522
	_skip_nodes(false), _skip_arcs(false) {}
511 523

	
512
    /// \brief Copy constructor
513
    ///
514
    /// The copy constructor transfers all data from the other reader,
515
    /// therefore the copied reader will not be usable more. 
516
    DigraphReader(DigraphReader& other) 
517
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
518
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
519
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
520

	
521
      other._is = 0;
522
      other.local_is = false;
523
      
524
      _node_index.swap(other._node_index);
525
      _arc_index.swap(other._arc_index);
526

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

	
531
      _nodes_caption = other._nodes_caption;
532
      _arcs_caption = other._arcs_caption;
533
      _attributes_caption = other._attributes_caption;
534

	
535
    }
536

	
537 524
    /// \brief Destructor
538 525
    ~DigraphReader() {
539 526
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
540 527
	   it != _node_maps.end(); ++it) {
541 528
	delete it->second;
542 529
      }
543 530

	
544 531
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
545 532
	   it != _arc_maps.end(); ++it) {
546 533
	delete it->second;
547 534
      }
548 535

	
549 536
      for (typename Attributes::iterator it = _attributes.begin(); 
550 537
	   it != _attributes.end(); ++it) {
551 538
	delete it->second;
552 539
      }
553 540

	
554 541
      if (local_is) {
555 542
	delete _is;
556 543
      }
557 544

	
558 545
    }
559 546

	
560 547
  private:
561
    
548

	
549
    friend DigraphReader<Digraph> digraphReader<>(std::istream& is, 
550
						  Digraph& digraph);    
551
    friend DigraphReader<Digraph> digraphReader<>(const std::string& fn, 
552
						  Digraph& digraph);   
553
    friend DigraphReader<Digraph> digraphReader<>(const char *fn, 
554
						  Digraph& digraph);    
555

	
556
    DigraphReader(DigraphReader& other) 
557
      : _is(other._is), local_is(other.local_is), _digraph(other._digraph),
558
	_use_nodes(other._use_nodes), _use_arcs(other._use_arcs),
559
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
560

	
561
      other._is = 0;
562
      other.local_is = false;
563
      
564
      _node_index.swap(other._node_index);
565
      _arc_index.swap(other._arc_index);
566

	
567
      _node_maps.swap(other._node_maps);
568
      _arc_maps.swap(other._arc_maps);
569
      _attributes.swap(other._attributes);
570

	
571
      _nodes_caption = other._nodes_caption;
572
      _arcs_caption = other._arcs_caption;
573
      _attributes_caption = other._attributes_caption;
574

	
575
    }
576

	
562 577
    DigraphReader& operator=(const DigraphReader&);
563 578

	
564 579
  public:
565 580

	
566 581
    /// \name Reading rules
567 582
    /// @{
568 583
    
569 584
    /// \brief Node map reading rule
570 585
    ///
571 586
    /// Add a node map reading rule to the reader.
572 587
    template <typename Map>
573 588
    DigraphReader& nodeMap(const std::string& caption, Map& map) {
574 589
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
575 590
      _reader_bits::MapStorageBase<Node>* storage = 
576 591
	new _reader_bits::MapStorage<Node, Map>(map);
577 592
      _node_maps.push_back(std::make_pair(caption, storage));
578 593
      return *this;
579 594
    }
580 595

	
581 596
    /// \brief Node map reading rule
582 597
    ///
583 598
    /// Add a node map reading rule with specialized converter to the
584 599
    /// reader.
585 600
    template <typename Map, typename Converter>
586 601
    DigraphReader& nodeMap(const std::string& caption, Map& map, 
587 602
			   const Converter& converter = Converter()) {
588 603
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
589 604
      _reader_bits::MapStorageBase<Node>* storage = 
590 605
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
591 606
      _node_maps.push_back(std::make_pair(caption, storage));
592 607
      return *this;
593 608
    }
594 609

	
595 610
    /// \brief Arc map reading rule
596 611
    ///
597 612
    /// Add an arc map reading rule to the reader.
598 613
    template <typename Map>
599 614
    DigraphReader& arcMap(const std::string& caption, Map& map) {
600 615
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
601 616
      _reader_bits::MapStorageBase<Arc>* storage = 
602 617
	new _reader_bits::MapStorage<Arc, Map>(map);
603 618
      _arc_maps.push_back(std::make_pair(caption, storage));
604 619
      return *this;
605 620
    }
606 621

	
607 622
    /// \brief Arc map reading rule
608 623
    ///
609 624
    /// Add an arc map reading rule with specialized converter to the
610 625
    /// reader.
611 626
    template <typename Map, typename Converter>
612 627
    DigraphReader& arcMap(const std::string& caption, Map& map, 
613 628
			  const Converter& converter = Converter()) {
614 629
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
615 630
      _reader_bits::MapStorageBase<Arc>* storage = 
616 631
	new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter);
617 632
      _arc_maps.push_back(std::make_pair(caption, storage));
618 633
      return *this;
619 634
    }
620 635

	
621 636
    /// \brief Attribute reading rule
622 637
    ///
623 638
    /// Add an attribute reading rule to the reader.
624 639
    template <typename Value>
625 640
    DigraphReader& attribute(const std::string& caption, Value& value) {
626 641
      _reader_bits::ValueStorageBase* storage = 
627 642
	new _reader_bits::ValueStorage<Value>(value);
628 643
      _attributes.insert(std::make_pair(caption, storage));
629 644
      return *this;
630 645
    }
631 646

	
632 647
    /// \brief Attribute reading rule
633 648
    ///
634 649
    /// Add an attribute reading rule with specialized converter to the
635 650
    /// reader.
636 651
    template <typename Value, typename Converter>
637 652
    DigraphReader& attribute(const std::string& caption, Value& value, 
638 653
			     const Converter& converter = Converter()) {
639 654
      _reader_bits::ValueStorageBase* storage = 
640 655
	new _reader_bits::ValueStorage<Value, Converter>(value, converter);
641 656
      _attributes.insert(std::make_pair(caption, storage));
642 657
      return *this;
643 658
    }
644 659

	
645 660
    /// \brief Node reading rule
646 661
    ///
647 662
    /// Add a node reading rule to reader.
648 663
    DigraphReader& node(const std::string& caption, Node& node) {
649 664
      typedef _reader_bits::MapLookUpConverter<Node> Converter;
650 665
      Converter converter(_node_index);
651 666
      _reader_bits::ValueStorageBase* storage = 
652 667
	new _reader_bits::ValueStorage<Node, Converter>(node, converter);
653 668
      _attributes.insert(std::make_pair(caption, storage));
654 669
      return *this;
655 670
    }
656 671

	
657 672
    /// \brief Arc reading rule
... ...
@@ -1089,320 +1104,332 @@
1089 1104
    /// @{
1090 1105

	
1091 1106
    /// \brief Start the batch processing
1092 1107
    ///
1093 1108
    /// This function starts the batch processing
1094 1109
    void run() {
1095 1110
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1096 1111
      if (!*_is) {
1097 1112
	throw DataFormatError("Cannot find file");
1098 1113
      }
1099 1114
      
1100 1115
      bool nodes_done = _skip_nodes;
1101 1116
      bool arcs_done = _skip_arcs;
1102 1117
      bool attributes_done = false;
1103 1118

	
1104 1119
      line_num = 0;      
1105 1120
      readLine();
1106 1121
      skipSection();
1107 1122

	
1108 1123
      while (readSuccess()) {
1109 1124
	try {
1110 1125
	  char c;
1111 1126
	  std::string section, caption;
1112 1127
	  line >> c;
1113 1128
	  _reader_bits::readToken(line, section);
1114 1129
	  _reader_bits::readToken(line, caption);
1115 1130

	
1116 1131
	  if (line >> c) 
1117 1132
	    throw DataFormatError("Extra character on the end of line");
1118 1133

	
1119 1134
	  if (section == "nodes" && !nodes_done) {
1120 1135
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1121 1136
	      readNodes();
1122 1137
	      nodes_done = true;
1123 1138
	    }
1124 1139
	  } else if ((section == "arcs" || section == "edges") && 
1125 1140
		     !arcs_done) {
1126 1141
	    if (_arcs_caption.empty() || _arcs_caption == caption) {
1127 1142
	      readArcs();
1128 1143
	      arcs_done = true;
1129 1144
	    }
1130 1145
	  } else if (section == "attributes" && !attributes_done) {
1131 1146
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1132 1147
	      readAttributes();
1133 1148
	      attributes_done = true;
1134 1149
	    }
1135 1150
	  } else {
1136 1151
	    readLine();
1137 1152
	    skipSection();
1138 1153
	  }
1139 1154
	} catch (DataFormatError& error) {
1140 1155
	  error.line(line_num);
1141 1156
	  throw;
1142 1157
	}	
1143 1158
      }
1144 1159

	
1145 1160
      if (!nodes_done) {
1146 1161
	throw DataFormatError("Section @nodes not found");
1147 1162
      }
1148 1163

	
1149 1164
      if (!arcs_done) {
1150 1165
	throw DataFormatError("Section @arcs not found");
1151 1166
      }
1152 1167

	
1153 1168
      if (!attributes_done && !_attributes.empty()) {
1154 1169
	throw DataFormatError("Section @attributes not found");
1155 1170
      }
1156 1171

	
1157 1172
    }
1158 1173

	
1159 1174
    /// @}
1160 1175
    
1161 1176
  };
1162 1177

	
1163 1178
  /// \relates DigraphReader
1164 1179
  template <typename Digraph>
1165 1180
  DigraphReader<Digraph> digraphReader(std::istream& is, Digraph& digraph) {
1166 1181
    DigraphReader<Digraph> tmp(is, digraph);
1167 1182
    return tmp;
1168 1183
  }
1169 1184

	
1170 1185
  /// \relates DigraphReader
1171 1186
  template <typename Digraph>
1172 1187
  DigraphReader<Digraph> digraphReader(const std::string& fn, 
1173 1188
				       Digraph& digraph) {
1174 1189
    DigraphReader<Digraph> tmp(fn, digraph);
1175 1190
    return tmp;
1176 1191
  }
1177 1192

	
1178 1193
  /// \relates DigraphReader
1179 1194
  template <typename Digraph>
1180 1195
  DigraphReader<Digraph> digraphReader(const char* fn, Digraph& digraph) {
1181 1196
    DigraphReader<Digraph> tmp(fn, digraph);
1182 1197
    return tmp;
1183 1198
  }
1184 1199

	
1200
  template <typename Graph>
1201
  class GraphReader;
1202

	
1203
  template <typename Graph>
1204
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph);    
1205

	
1206
  template <typename Graph>
1207
  GraphReader<Graph> graphReader(const std::string& fn, Graph& graph);   
1208

	
1209
  template <typename Graph>
1210
  GraphReader<Graph> graphReader(const char *fn, Graph& graph);    
1211

	
1185 1212
  /// \ingroup lemon_io
1186 1213
  ///  
1187 1214
  /// \brief LGF reader for undirected graphs
1188 1215
  ///
1189 1216
  /// This utility reads an \ref lgf-format "LGF" file.
1190 1217
  template <typename _Graph>
1191 1218
  class GraphReader {
1192 1219
  public:
1193 1220

	
1194 1221
    typedef _Graph Graph;
1195 1222
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
1196 1223
    
1197 1224
  private:
1198 1225

	
1199 1226
    std::istream* _is;
1200 1227
    bool local_is;
1201 1228

	
1202 1229
    Graph& _graph;
1203 1230

	
1204 1231
    std::string _nodes_caption;
1205 1232
    std::string _edges_caption;
1206 1233
    std::string _attributes_caption;
1207 1234

	
1208 1235
    typedef std::map<std::string, Node> NodeIndex;
1209 1236
    NodeIndex _node_index;
1210 1237
    typedef std::map<std::string, Edge> EdgeIndex;
1211 1238
    EdgeIndex _edge_index;
1212 1239
    
1213 1240
    typedef std::vector<std::pair<std::string, 
1214 1241
      _reader_bits::MapStorageBase<Node>*> > NodeMaps;    
1215 1242
    NodeMaps _node_maps; 
1216 1243

	
1217 1244
    typedef std::vector<std::pair<std::string,
1218 1245
      _reader_bits::MapStorageBase<Edge>*> > EdgeMaps;
1219 1246
    EdgeMaps _edge_maps;
1220 1247

	
1221 1248
    typedef std::multimap<std::string, _reader_bits::ValueStorageBase*> 
1222 1249
      Attributes;
1223 1250
    Attributes _attributes;
1224 1251

	
1225 1252
    bool _use_nodes;
1226 1253
    bool _use_edges;
1227 1254

	
1228 1255
    bool _skip_nodes;
1229 1256
    bool _skip_edges;
1230 1257

	
1231 1258
    int line_num;
1232 1259
    std::istringstream line;
1233 1260

	
1234 1261
  public:
1235 1262

	
1236 1263
    /// \brief Constructor
1237 1264
    ///
1238 1265
    /// Construct a undirected graph reader, which reads from the given
1239 1266
    /// input stream.
1240 1267
    GraphReader(std::istream& is, Graph& graph) 
1241 1268
      : _is(&is), local_is(false), _graph(graph),
1242 1269
	_use_nodes(false), _use_edges(false),
1243 1270
	_skip_nodes(false), _skip_edges(false) {}
1244 1271

	
1245 1272
    /// \brief Constructor
1246 1273
    ///
1247 1274
    /// Construct a undirected graph reader, which reads from the given
1248 1275
    /// file.
1249 1276
    GraphReader(const std::string& fn, Graph& graph) 
1250 1277
      : _is(new std::ifstream(fn.c_str())), local_is(true), _graph(graph),
1251 1278
    	_use_nodes(false), _use_edges(false),
1252 1279
	_skip_nodes(false), _skip_edges(false) {}
1253 1280
    
1254 1281
    /// \brief Constructor
1255 1282
    ///
1256 1283
    /// Construct a undirected graph reader, which reads from the given
1257 1284
    /// file.
1258 1285
    GraphReader(const char* fn, Graph& graph) 
1259 1286
      : _is(new std::ifstream(fn)), local_is(true), _graph(graph),
1260 1287
    	_use_nodes(false), _use_edges(false),
1261 1288
	_skip_nodes(false), _skip_edges(false) {}
1262 1289

	
1263
    /// \brief Copy constructor
1264
    ///
1265
    /// The copy constructor transfers all data from the other reader,
1266
    /// therefore the copied reader will not be usable more. 
1267
    GraphReader(GraphReader& other) 
1268
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1269
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1270
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1271

	
1272
      other._is = 0;
1273
      other.local_is = false;
1274
      
1275
      _node_index.swap(other._node_index);
1276
      _edge_index.swap(other._edge_index);
1277

	
1278
      _node_maps.swap(other._node_maps);
1279
      _edge_maps.swap(other._edge_maps);
1280
      _attributes.swap(other._attributes);
1281

	
1282
      _nodes_caption = other._nodes_caption;
1283
      _edges_caption = other._edges_caption;
1284
      _attributes_caption = other._attributes_caption;
1285

	
1286
    }
1287

	
1288 1290
    /// \brief Destructor
1289 1291
    ~GraphReader() {
1290 1292
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
1291 1293
	   it != _node_maps.end(); ++it) {
1292 1294
	delete it->second;
1293 1295
      }
1294 1296

	
1295 1297
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
1296 1298
	   it != _edge_maps.end(); ++it) {
1297 1299
	delete it->second;
1298 1300
      }
1299 1301

	
1300 1302
      for (typename Attributes::iterator it = _attributes.begin(); 
1301 1303
	   it != _attributes.end(); ++it) {
1302 1304
	delete it->second;
1303 1305
      }
1304 1306

	
1305 1307
      if (local_is) {
1306 1308
	delete _is;
1307 1309
      }
1308 1310

	
1309 1311
    }
1310 1312

	
1311 1313
  private:
1312
    
1314
    friend GraphReader<Graph> graphReader<>(std::istream& is, Graph& graph);    
1315
    friend GraphReader<Graph> graphReader<>(const std::string& fn, 
1316
					    Graph& graph);   
1317
    friend GraphReader<Graph> graphReader<>(const char *fn, Graph& graph);    
1318

	
1319
    GraphReader(GraphReader& other) 
1320
      : _is(other._is), local_is(other.local_is), _graph(other._graph),
1321
	_use_nodes(other._use_nodes), _use_edges(other._use_edges),
1322
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1323

	
1324
      other._is = 0;
1325
      other.local_is = false;
1326
      
1327
      _node_index.swap(other._node_index);
1328
      _edge_index.swap(other._edge_index);
1329

	
1330
      _node_maps.swap(other._node_maps);
1331
      _edge_maps.swap(other._edge_maps);
1332
      _attributes.swap(other._attributes);
1333

	
1334
      _nodes_caption = other._nodes_caption;
1335
      _edges_caption = other._edges_caption;
1336
      _attributes_caption = other._attributes_caption;
1337

	
1338
    }
1339

	
1313 1340
    GraphReader& operator=(const GraphReader&);
1314 1341

	
1315 1342
  public:
1316 1343

	
1317 1344
    /// \name Reading rules
1318 1345
    /// @{
1319 1346
    
1320 1347
    /// \brief Node map reading rule
1321 1348
    ///
1322 1349
    /// Add a node map reading rule to the reader.
1323 1350
    template <typename Map>
1324 1351
    GraphReader& nodeMap(const std::string& caption, Map& map) {
1325 1352
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1326 1353
      _reader_bits::MapStorageBase<Node>* storage = 
1327 1354
	new _reader_bits::MapStorage<Node, Map>(map);
1328 1355
      _node_maps.push_back(std::make_pair(caption, storage));
1329 1356
      return *this;
1330 1357
    }
1331 1358

	
1332 1359
    /// \brief Node map reading rule
1333 1360
    ///
1334 1361
    /// Add a node map reading rule with specialized converter to the
1335 1362
    /// reader.
1336 1363
    template <typename Map, typename Converter>
1337 1364
    GraphReader& nodeMap(const std::string& caption, Map& map, 
1338 1365
			   const Converter& converter = Converter()) {
1339 1366
      checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>();
1340 1367
      _reader_bits::MapStorageBase<Node>* storage = 
1341 1368
	new _reader_bits::MapStorage<Node, Map, Converter>(map, converter);
1342 1369
      _node_maps.push_back(std::make_pair(caption, storage));
1343 1370
      return *this;
1344 1371
    }
1345 1372

	
1346 1373
    /// \brief Edge map reading rule
1347 1374
    ///
1348 1375
    /// Add an edge map reading rule to the reader.
1349 1376
    template <typename Map>
1350 1377
    GraphReader& edgeMap(const std::string& caption, Map& map) {
1351 1378
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1352 1379
      _reader_bits::MapStorageBase<Edge>* storage = 
1353 1380
	new _reader_bits::MapStorage<Edge, Map>(map);
1354 1381
      _edge_maps.push_back(std::make_pair(caption, storage));
1355 1382
      return *this;
1356 1383
    }
1357 1384

	
1358 1385
    /// \brief Edge map reading rule
1359 1386
    ///
1360 1387
    /// Add an edge map reading rule with specialized converter to the
1361 1388
    /// reader.
1362 1389
    template <typename Map, typename Converter>
1363 1390
    GraphReader& edgeMap(const std::string& caption, Map& map, 
1364 1391
			  const Converter& converter = Converter()) {
1365 1392
      checkConcept<concepts::WriteMap<Edge, typename Map::Value>, Map>();
1366 1393
      _reader_bits::MapStorageBase<Edge>* storage = 
1367 1394
	new _reader_bits::MapStorage<Edge, Map, Converter>(map, converter);
1368 1395
      _edge_maps.push_back(std::make_pair(caption, storage));
1369 1396
      return *this;
1370 1397
    }
1371 1398

	
1372 1399
    /// \brief Arc map reading rule
1373 1400
    ///
1374 1401
    /// Add an arc map reading rule to the reader.
1375 1402
    template <typename Map>
1376 1403
    GraphReader& arcMap(const std::string& caption, Map& map) {
1377 1404
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1378 1405
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1379 1406
	new _reader_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1380 1407
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1381 1408
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1382 1409
	new _reader_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1383 1410
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1384 1411
      return *this;
1385 1412
    }
1386 1413

	
1387 1414
    /// \brief Arc map reading rule
1388 1415
    ///
1389 1416
    /// Add an arc map reading rule with specialized converter to the
1390 1417
    /// reader.
1391 1418
    template <typename Map, typename Converter>
1392 1419
    GraphReader& arcMap(const std::string& caption, Map& map, 
1393 1420
			  const Converter& converter = Converter()) {
1394 1421
      checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>();
1395 1422
      _reader_bits::MapStorageBase<Edge>* forward_storage = 
1396 1423
	new _reader_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1397 1424
	(_graph, map, converter);
1398 1425
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1399 1426
      _reader_bits::MapStorageBase<Edge>* backward_storage = 
1400 1427
	new _reader_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1401 1428
	(_graph, map, converter);
1402 1429
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1403 1430
      return *this;
1404 1431
    }
1405 1432

	
1406 1433
    /// \brief Attribute reading rule
1407 1434
    ///
1408 1435
    /// Add an attribute reading rule to the reader.
... ...
@@ -1884,261 +1911,267 @@
1884 1911

	
1885 1912
    /// \name Execution of the reader    
1886 1913
    /// @{
1887 1914

	
1888 1915
    /// \brief Start the batch processing
1889 1916
    ///
1890 1917
    /// This function starts the batch processing
1891 1918
    void run() {
1892 1919
      
1893 1920
      LEMON_ASSERT(_is != 0, "This reader assigned to an other reader");
1894 1921
      
1895 1922
      bool nodes_done = _skip_nodes;
1896 1923
      bool edges_done = _skip_edges;
1897 1924
      bool attributes_done = false;
1898 1925

	
1899 1926
      line_num = 0;      
1900 1927
      readLine();
1901 1928
      skipSection();
1902 1929

	
1903 1930
      while (readSuccess()) {
1904 1931
	try {
1905 1932
	  char c;
1906 1933
	  std::string section, caption;
1907 1934
	  line >> c;
1908 1935
	  _reader_bits::readToken(line, section);
1909 1936
	  _reader_bits::readToken(line, caption);
1910 1937

	
1911 1938
	  if (line >> c) 
1912 1939
	    throw DataFormatError("Extra character on the end of line");
1913 1940

	
1914 1941
	  if (section == "nodes" && !nodes_done) {
1915 1942
	    if (_nodes_caption.empty() || _nodes_caption == caption) {
1916 1943
	      readNodes();
1917 1944
	      nodes_done = true;
1918 1945
	    }
1919 1946
	  } else if ((section == "edges" || section == "arcs") && 
1920 1947
		     !edges_done) {
1921 1948
	    if (_edges_caption.empty() || _edges_caption == caption) {
1922 1949
	      readEdges();
1923 1950
	      edges_done = true;
1924 1951
	    }
1925 1952
	  } else if (section == "attributes" && !attributes_done) {
1926 1953
	    if (_attributes_caption.empty() || _attributes_caption == caption) {
1927 1954
	      readAttributes();
1928 1955
	      attributes_done = true;
1929 1956
	    }
1930 1957
	  } else {
1931 1958
	    readLine();
1932 1959
	    skipSection();
1933 1960
	  }
1934 1961
	} catch (DataFormatError& error) {
1935 1962
	  error.line(line_num);
1936 1963
	  throw;
1937 1964
	}	
1938 1965
      }
1939 1966

	
1940 1967
      if (!nodes_done) {
1941 1968
	throw DataFormatError("Section @nodes not found");
1942 1969
      }
1943 1970

	
1944 1971
      if (!edges_done) {
1945 1972
	throw DataFormatError("Section @edges not found");
1946 1973
      }
1947 1974

	
1948 1975
      if (!attributes_done && !_attributes.empty()) {
1949 1976
	throw DataFormatError("Section @attributes not found");
1950 1977
      }
1951 1978

	
1952 1979
    }
1953 1980

	
1954 1981
    /// @}
1955 1982
    
1956 1983
  };
1957 1984

	
1958 1985
  /// \relates GraphReader
1959 1986
  template <typename Graph>
1960 1987
  GraphReader<Graph> graphReader(std::istream& is, Graph& graph) {
1961 1988
    GraphReader<Graph> tmp(is, graph);
1962 1989
    return tmp;
1963 1990
  }
1964 1991

	
1965 1992
  /// \relates GraphReader
1966 1993
  template <typename Graph>
1967 1994
  GraphReader<Graph> graphReader(const std::string& fn, 
1968 1995
				       Graph& graph) {
1969 1996
    GraphReader<Graph> tmp(fn, graph);
1970 1997
    return tmp;
1971 1998
  }
1972 1999

	
1973 2000
  /// \relates GraphReader
1974 2001
  template <typename Graph>
1975 2002
  GraphReader<Graph> graphReader(const char* fn, Graph& graph) {
1976 2003
    GraphReader<Graph> tmp(fn, graph);
1977 2004
    return tmp;
1978 2005
  }
1979 2006

	
2007
  class SectionReader;
2008

	
2009
  SectionReader sectionReader(std::istream& is);
2010
  SectionReader sectionReader(const std::string& fn);
2011
  SectionReader sectionReader(const char* fn);
2012
  
1980 2013
  /// \brief Section reader class
1981 2014
  ///
1982 2015
  /// In the \e LGF file extra sections can be placed, which contain
1983 2016
  /// any data in arbitrary format. Such sections can be read with
1984 2017
  /// this class. A reading rule can be added with two different
1985 2018
  /// functions, with the \c sectionLines() function a functor can
1986 2019
  /// process the section line-by-line. While with the \c
1987 2020
  /// sectionStream() member the section can be read from an input
1988 2021
  /// stream.
1989 2022
  class SectionReader {
1990 2023
  private:
1991 2024
    
1992 2025
    std::istream* _is;
1993 2026
    bool local_is;
1994 2027

	
1995 2028
    typedef std::map<std::string, _reader_bits::Section*> Sections;
1996 2029
    Sections _sections;
1997 2030

	
1998 2031
    int line_num;
1999 2032
    std::istringstream line;
2000 2033

	
2001 2034
  public:
2002 2035

	
2003 2036
    /// \brief Constructor
2004 2037
    ///
2005 2038
    /// Construct a section reader, which reads from the given input
2006 2039
    /// stream.
2007 2040
    SectionReader(std::istream& is) 
2008 2041
      : _is(&is), local_is(false) {}
2009 2042

	
2010 2043
    /// \brief Constructor
2011 2044
    ///
2012 2045
    /// Construct a section reader, which reads from the given file.
2013 2046
    SectionReader(const std::string& fn) 
2014 2047
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2015 2048
    
2016 2049
    /// \brief Constructor
2017 2050
    ///
2018 2051
    /// Construct a section reader, which reads from the given file.
2019 2052
    SectionReader(const char* fn) 
2020 2053
      : _is(new std::ifstream(fn)), local_is(true) {}
2021 2054

	
2022
    /// \brief Copy constructor
2023
    ///
2024
    /// The copy constructor transfers all data from the other reader,
2025
    /// therefore the copied reader will not be usable more. 
2026
    SectionReader(SectionReader& other) 
2027
      : _is(other._is), local_is(other.local_is) {
2028

	
2029
      other._is = 0;
2030
      other.local_is = false;
2031
      
2032
      _sections.swap(other._sections);
2033
    }
2034

	
2035 2055
    /// \brief Destructor
2036 2056
    ~SectionReader() {
2037 2057
      for (Sections::iterator it = _sections.begin(); 
2038 2058
	   it != _sections.end(); ++it) {
2039 2059
	delete it->second;
2040 2060
      }
2041 2061

	
2042 2062
      if (local_is) {
2043 2063
	delete _is;
2044 2064
      }
2045 2065

	
2046 2066
    }
2047 2067

	
2048 2068
  private:
2069

	
2070
    friend SectionReader sectionReader(std::istream& is);
2071
    friend SectionReader sectionReader(const std::string& fn);
2072
    friend SectionReader sectionReader(const char* fn);
2073

	
2074
    SectionReader(SectionReader& other) 
2075
      : _is(other._is), local_is(other.local_is) {
2076

	
2077
      other._is = 0;
2078
      other.local_is = false;
2079
      
2080
      _sections.swap(other._sections);
2081
    }
2049 2082
    
2050 2083
    SectionReader& operator=(const SectionReader&);
2051 2084

	
2052 2085
  public:
2053 2086

	
2054 2087
    /// \name Section readers
2055 2088
    /// @{
2056 2089

	
2057 2090
    /// \brief Add a section processor with line oriented reading
2058 2091
    ///
2059 2092
    /// The first parameter is the type descriptor of the section, the
2060 2093
    /// second is a functor, which takes just one \c std::string
2061 2094
    /// parameter. At the reading process, each line of the section
2062 2095
    /// will be given to the functor object. However, the empty lines
2063 2096
    /// and the comment lines are filtered out, and the leading
2064 2097
    /// whitespaces are trimmed from each processed string.
2065 2098
    ///
2066 2099
    /// For example let's see a section, which contain several
2067 2100
    /// integers, which should be inserted into a vector.
2068 2101
    ///\code
2069 2102
    ///  @numbers
2070 2103
    ///  12 45 23
2071 2104
    ///  4
2072 2105
    ///  23 6
2073 2106
    ///\endcode
2074 2107
    ///
2075 2108
    /// The functor is implemented as an struct:
2076 2109
    ///\code
2077 2110
    ///  struct NumberSection {
2078 2111
    ///    std::vector<int>& _data;
2079 2112
    ///    NumberSection(std::vector<int>& data) : _data(data) {}
2080 2113
    ///    void operator()(const std::string& line) {
2081 2114
    ///      std::istringstream ls(line);
2082 2115
    ///      int value;
2083 2116
    ///      while (ls >> value) _data.push_back(value);
2084 2117
    ///    }
2085 2118
    ///  };
2086 2119
    ///
2087 2120
    ///  // ...
2088 2121
    ///
2089 2122
    ///  reader.sectionLines("numbers", NumberSection(vec));  
2090 2123
    ///\endcode
2091 2124
    template <typename Functor>
2092 2125
    SectionReader& sectionLines(const std::string& type, Functor functor) {
2093 2126
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
2094 2127
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
2095 2128
		   "Multiple reading of section.");
2096 2129
      _sections.insert(std::make_pair(type, 
2097 2130
        new _reader_bits::LineSection<Functor>(functor)));
2098 2131
      return *this;
2099 2132
    }
2100 2133

	
2101 2134

	
2102 2135
    /// \brief Add a section processor with stream oriented reading
2103 2136
    ///
2104 2137
    /// The first parameter is the type of the section, the second is
2105 2138
    /// a functor, which takes an \c std::istream& and an int&
2106 2139
    /// parameter, the latter regard to the line number of stream. The
2107 2140
    /// functor can read the input while the section go on, and the
2108 2141
    /// line number should be modified accordingly.
2109 2142
    template <typename Functor>
2110 2143
    SectionReader& sectionStream(const std::string& type, Functor functor) {
2111 2144
      LEMON_ASSERT(!type.empty(), "Type is not empty.");
2112 2145
      LEMON_ASSERT(_sections.find(type) == _sections.end(), 
2113 2146
		   "Multiple reading of section.");
2114 2147
      _sections.insert(std::make_pair(type, 
2115 2148
	 new _reader_bits::StreamSection<Functor>(functor)));
2116 2149
      return *this;
2117 2150
    }    
2118 2151
    
2119 2152
    /// @}
2120 2153

	
2121 2154
  private:
2122 2155

	
2123 2156
    bool readLine() {
2124 2157
      std::string str;
2125 2158
      while(++line_num, std::getline(*_is, str)) {
2126 2159
	line.clear(); line.str(str);
2127 2160
	char c;
2128 2161
	if (line >> std::ws >> c && c != '#') {
2129 2162
	  line.putback(c);
2130 2163
	  return true;
2131 2164
	}
2132 2165
      }
2133 2166
      return false;
2134 2167
    }
2135 2168

	
2136 2169
    bool readSuccess() {
2137 2170
      return static_cast<bool>(*_is);
2138 2171
    }
2139 2172
    
2140 2173
    void skipSection() {
2141 2174
      char c;
2142 2175
      while (readSuccess() && line >> c && c != '@') {
2143 2176
	readLine();
2144 2177
      }
... ...
@@ -2202,220 +2235,205 @@
2202 2235
      }
2203 2236
    }
2204 2237

	
2205 2238
    /// @}
2206 2239
        
2207 2240
  };
2208 2241

	
2209 2242
  /// \relates SectionReader
2210 2243
  inline SectionReader sectionReader(std::istream& is) {
2211 2244
    SectionReader tmp(is);
2212 2245
    return tmp;
2213 2246
  }
2214 2247

	
2215 2248
  /// \relates SectionReader
2216 2249
  inline SectionReader sectionReader(const std::string& fn) {
2217 2250
    SectionReader tmp(fn);
2218 2251
    return tmp;
2219 2252
  }
2220 2253

	
2221 2254
  /// \relates SectionReader
2222 2255
  inline SectionReader sectionReader(const char* fn) {
2223 2256
    SectionReader tmp(fn);
2224 2257
    return tmp;
2225 2258
  }
2226 2259

	
2227 2260
  /// \ingroup lemon_io
2228 2261
  ///
2229 2262
  /// \brief Reader for the contents of the \ref lgf-format "LGF" file 
2230 2263
  ///
2231 2264
  /// This class can be used to read the sections, the map names and
2232 2265
  /// the attributes from a file. Usually, the Lemon programs know
2233 2266
  /// that, which type of graph, which maps and which attributes
2234 2267
  /// should be read from a file, but in general tools (like glemon)
2235 2268
  /// the contents of an LGF file should be guessed somehow. This class
2236 2269
  /// reads the graph and stores the appropriate information for
2237 2270
  /// reading the graph.
2238 2271
  ///
2239 2272
  ///\code LgfContents contents("graph.lgf"); 
2240 2273
  /// contents.run();
2241 2274
  ///
2242 2275
  /// // does it contain any node section and arc section
2243 2276
  /// if (contents.nodeSectionNum() == 0 || contents.arcSectionNum()) {
2244 2277
  ///   std::cerr << "Failure, cannot find graph" << std::endl;
2245 2278
  ///   return -1;
2246 2279
  /// }
2247 2280
  /// std::cout << "The name of the default node section : " 
2248 2281
  ///           << contents.nodeSection(0) << std::endl;
2249 2282
  /// std::cout << "The number of the arc maps : " 
2250 2283
  ///           << contents.arcMaps(0).size() << std::endl;
2251 2284
  /// std::cout << "The name of second arc map : " 
2252 2285
  ///           << contents.arcMaps(0)[1] << std::endl;
2253 2286
  ///\endcode
2254 2287
  class LgfContents {    
2255 2288
  private:
2256 2289

	
2257 2290
    std::istream* _is;
2258 2291
    bool local_is;
2259 2292

	
2260 2293
    std::vector<std::string> _node_sections;
2261 2294
    std::vector<std::string> _edge_sections;
2262 2295
    std::vector<std::string> _attribute_sections;
2263 2296
    std::vector<std::string> _extra_sections;
2264 2297

	
2265 2298
    std::vector<bool> _arc_sections;
2266 2299

	
2267 2300
    std::vector<std::vector<std::string> > _node_maps;
2268 2301
    std::vector<std::vector<std::string> > _edge_maps;
2269 2302

	
2270 2303
    std::vector<std::vector<std::string> > _attributes;
2271 2304

	
2272 2305

	
2273 2306
    int line_num;
2274 2307
    std::istringstream line;
2275 2308
    
2276 2309
  public:
2277 2310

	
2278 2311
    /// \brief Constructor
2279 2312
    ///
2280 2313
    /// Construct an \e LGF contents reader, which reads from the given
2281 2314
    /// input stream.
2282 2315
    LgfContents(std::istream& is) 
2283 2316
      : _is(&is), local_is(false) {}
2284 2317

	
2285 2318
    /// \brief Constructor
2286 2319
    ///
2287 2320
    /// Construct an \e LGF contents reader, which reads from the given
2288 2321
    /// file.
2289 2322
    LgfContents(const std::string& fn) 
2290 2323
      : _is(new std::ifstream(fn.c_str())), local_is(true) {}
2291 2324

	
2292 2325
    /// \brief Constructor
2293 2326
    ///
2294 2327
    /// Construct an \e LGF contents reader, which reads from the given
2295 2328
    /// file.
2296 2329
    LgfContents(const char* fn)
2297 2330
      : _is(new std::ifstream(fn)), local_is(true) {}
2298

	
2299
    /// \brief Copy constructor
2300
    ///
2301
    /// The copy constructor transfers all data from the other reader,
2302
    /// therefore the copied reader will not be usable more. 
2303
    LgfContents(LgfContents& other)
2304
      : _is(other._is), local_is(other.local_is) {
2305
      
2306
      other._is = 0;
2307
      other.local_is = false;
2308
      
2309
      _node_sections.swap(other._node_sections);
2310
      _edge_sections.swap(other._edge_sections);
2311
      _attribute_sections.swap(other._attribute_sections);
2312
      _extra_sections.swap(other._extra_sections);
2313

	
2314
      _arc_sections.swap(other._arc_sections);
2315

	
2316
      _node_maps.swap(other._node_maps);
2317
      _edge_maps.swap(other._edge_maps);
2318
      _attributes.swap(other._attributes);
2319
    }
2320 2331
    
2321 2332
    /// \brief Destructor
2322 2333
    ~LgfContents() {
2323 2334
      if (local_is) delete _is;
2324 2335
    }
2325 2336

	
2337
  private:
2338
    
2339
    LgfContents(const LgfContents&);
2340
    LgfContents& operator=(const LgfContents&);
2341

	
2342
  public:
2343

	
2326 2344

	
2327 2345
    /// \name Node sections
2328 2346
    /// @{
2329 2347

	
2330 2348
    /// \brief Gives back the number of node sections in the file.
2331 2349
    ///
2332 2350
    /// Gives back the number of node sections in the file.
2333 2351
    int nodeSectionNum() const {
2334 2352
      return _node_sections.size();
2335 2353
    }
2336 2354

	
2337 2355
    /// \brief Returns the section name at the given position. 
2338 2356
    ///
2339 2357
    /// Returns the section name at the given position. 
2340 2358
    const std::string& nodeSection(int i) const {
2341 2359
      return _node_sections[i];
2342 2360
    }
2343 2361

	
2344 2362
    /// \brief Gives back the node maps for the given section.
2345 2363
    ///
2346 2364
    /// Gives back the node maps for the given section.
2347 2365
    const std::vector<std::string>& nodeMapNames(int i) const {
2348 2366
      return _node_maps[i];
2349 2367
    }
2350 2368

	
2351 2369
    /// @}
2352 2370

	
2353 2371
    /// \name Arc/Edge sections 
2354 2372
    /// @{
2355 2373

	
2356 2374
    /// \brief Gives back the number of arc/edge sections in the file.
2357 2375
    ///
2358 2376
    /// Gives back the number of arc/edge sections in the file.
2359 2377
    /// \note It is synonym of \c edgeSectionNum().
2360 2378
    int arcSectionNum() const {
2361 2379
      return _edge_sections.size();
2362 2380
    }
2363 2381

	
2364 2382
    /// \brief Returns the section name at the given position. 
2365 2383
    ///
2366 2384
    /// Returns the section name at the given position. 
2367 2385
    /// \note It is synonym of \c edgeSection().
2368 2386
    const std::string& arcSection(int i) const {
2369 2387
      return _edge_sections[i];
2370 2388
    }
2371 2389

	
2372 2390
    /// \brief Gives back the arc/edge maps for the given section.
2373 2391
    ///
2374 2392
    /// Gives back the arc/edge maps for the given section.
2375 2393
    /// \note It is synonym of \c edgeMapNames().
2376 2394
    const std::vector<std::string>& arcMapNames(int i) const {
2377 2395
      return _edge_maps[i];
2378 2396
    }
2379 2397

	
2380 2398
    /// @}
2381 2399

	
2382 2400
    /// \name Synonyms
2383 2401
    /// @{
2384 2402

	
2385 2403
    /// \brief Gives back the number of arc/edge sections in the file.
2386 2404
    ///
2387 2405
    /// Gives back the number of arc/edge sections in the file.
2388 2406
    /// \note It is synonym of \c arcSectionNum().
2389 2407
    int edgeSectionNum() const {
2390 2408
      return _edge_sections.size();
2391 2409
    }
2392 2410

	
2393 2411
    /// \brief Returns the section name at the given position. 
2394 2412
    ///
2395 2413
    /// Returns the section name at the given position. 
2396 2414
    /// \note It is synonym of \c arcSection().
2397 2415
    const std::string& edgeSection(int i) const {
2398 2416
      return _edge_sections[i];
2399 2417
    }
2400 2418

	
2401 2419
    /// \brief Gives back the edge maps for the given section.
2402 2420
    ///
2403 2421
    /// Gives back the edge maps for the given section.
2404 2422
    /// \note It is synonym of \c arcMapNames().
2405 2423
    const std::vector<std::string>& edgeMapNames(int i) const {
2406 2424
      return _edge_maps[i];
2407 2425
    }
2408 2426

	
2409 2427
    /// @}
2410 2428

	
2411 2429
    /// \name Attribute sections   
2412 2430
    /// @{
2413 2431

	
2414 2432
    /// \brief Gives back the number of attribute sections in the file.
2415 2433
    ///
2416 2434
    /// Gives back the number of attribute sections in the file.
2417 2435
    int attributeSectionNum() const {
2418 2436
      return _attribute_sections.size();
2419 2437
    }
2420 2438

	
2421 2439
    /// \brief Returns the section name at the given position. 
Ignore white space 6 line context
... ...
@@ -211,348 +211,366 @@
211 211
      const std::map<typename Graph::Edge, std::string>& _map;
212 212
      
213 213
      GraphArcLookUpConverter(const Graph& graph, 
214 214
			      const std::map<typename Graph::Edge, 
215 215
			                     std::string>& map) 
216 216
	: _graph(graph), _map(map) {}
217 217
      
218 218
      std::string operator()(const typename Graph::Arc& val) {
219 219
	typename std::map<typename Graph::Edge, std::string>
220 220
	  ::const_iterator it = _map.find(val);
221 221
	if (it == _map.end()) {
222 222
	  throw DataFormatError("Item not found");
223 223
	}
224 224
	return (_graph.direction(val) ? '+' : '-') + it->second;
225 225
      }
226 226
    };
227 227

	
228 228
    bool isWhiteSpace(char c) {
229 229
      return c == ' ' || c == '\t' || c == '\v' || 
230 230
        c == '\n' || c == '\r' || c == '\f'; 
231 231
    }
232 232

	
233 233
    bool isEscaped(char c) {
234 234
      return c == '\\' || c == '\"' || c == '\'' || 
235 235
	c == '\a' || c == '\b';
236 236
    }
237 237

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

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

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

	
306 306
  }
307

	
308
  template <typename Digraph>
309
  class DigraphWriter;
310

	
311
  template <typename Digraph>
312
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, 
313
				       const Digraph& digraph);
314

	
315
  template <typename Digraph>
316
  DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
317
				       const Digraph& digraph);
318

	
319
  template <typename Digraph>
320
  DigraphWriter<Digraph> digraphWriter(const char *fn, 
321
				       const Digraph& digraph);
307 322
  
308 323
  /// \ingroup lemon_io
309 324
  ///  
310 325
  /// \brief LGF writer for directed graphs
311 326
  ///
312 327
  /// This utility writes an \ref lgf-format "LGF" file.
313 328
  ///
314 329
  /// The writing method does a batch processing. The user creates a
315 330
  /// writer object, then various writing rules can be added to the
316 331
  /// writer, and eventually the writing is executed with the \c run()
317 332
  /// member function. A map writing rule can be added to the writer
318 333
  /// with the \c nodeMap() or \c arcMap() members. An optional
319 334
  /// converter parameter can also be added as a standard functor
320 335
  /// converting from the value type of the map to std::string. If it
321 336
  /// is set, it will determine how the map's value type is written to
322 337
  /// the output stream. If the functor is not set, then a default
323 338
  /// conversion will be used. The \c attribute(), \c node() and \c
324 339
  /// arc() functions are used to add attribute writing rules.
325 340
  ///
326 341
  ///\code
327 342
  ///     DigraphWriter<Digraph>(std::cout, digraph).
328 343
  ///       nodeMap("coordinates", coord_map).
329 344
  ///       nodeMap("size", size).
330 345
  ///       nodeMap("title", title).
331 346
  ///       arcMap("capacity", cap_map).
332 347
  ///       node("source", src).
333 348
  ///       node("target", trg).
334 349
  ///       attribute("caption", caption).
335 350
  ///       run();
336 351
  ///\endcode
337 352
  ///
338 353
  ///
339 354
  /// By default, the writer does not write additional captions to the
340 355
  /// sections, but they can be give as an optional parameter of
341 356
  /// the \c nodes(), \c arcs() or \c
342 357
  /// attributes() functions.
343 358
  ///
344 359
  /// The \c skipNodes() and \c skipArcs() functions forbid the
345 360
  /// writing of the sections. If two arc sections should be written
346 361
  /// to the output, it can be done in two passes, the first pass
347 362
  /// writes the node section and the first arc section, then the
348 363
  /// second pass skips the node section and writes just the arc
349 364
  /// section to the stream. The output stream can be retrieved with
350 365
  /// the \c ostream() function, hence the second pass can append its
351 366
  /// output to the output of the first pass.
352 367
  template <typename _Digraph>
353 368
  class DigraphWriter {
354 369
  public:
355 370

	
356 371
    typedef _Digraph Digraph;
357 372
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
358 373
    
359 374
  private:
360 375

	
361 376

	
362 377
    std::ostream* _os;
363 378
    bool local_os;
364 379

	
365
    Digraph& _digraph;
380
    const Digraph& _digraph;
366 381

	
367 382
    std::string _nodes_caption;
368 383
    std::string _arcs_caption;
369 384
    std::string _attributes_caption;
370 385
    
371 386
    typedef std::map<Node, std::string> NodeIndex;
372 387
    NodeIndex _node_index;
373 388
    typedef std::map<Arc, std::string> ArcIndex;
374 389
    ArcIndex _arc_index;
375 390

	
376 391
    typedef std::vector<std::pair<std::string, 
377 392
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
378 393
    NodeMaps _node_maps; 
379 394

	
380 395
    typedef std::vector<std::pair<std::string, 
381 396
      _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
382 397
    ArcMaps _arc_maps;
383 398

	
384 399
    typedef std::vector<std::pair<std::string, 
385 400
      _writer_bits::ValueStorageBase*> > Attributes;
386 401
    Attributes _attributes;
387 402

	
388 403
    bool _skip_nodes;
389 404
    bool _skip_arcs;
390 405

	
391 406
  public:
392 407

	
393 408
    /// \brief Constructor
394 409
    ///
395 410
    /// Construct a directed graph writer, which writes to the given
396 411
    /// output stream.
397
    DigraphWriter(std::ostream& is, Digraph& digraph) 
412
    DigraphWriter(std::ostream& is, const Digraph& digraph) 
398 413
      : _os(&is), local_os(false), _digraph(digraph),
399 414
	_skip_nodes(false), _skip_arcs(false) {}
400 415

	
401 416
    /// \brief Constructor
402 417
    ///
403 418
    /// Construct a directed graph writer, which writes to the given
404 419
    /// output file.
405
    DigraphWriter(const std::string& fn, Digraph& digraph) 
420
    DigraphWriter(const std::string& fn, const Digraph& digraph) 
406 421
      : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
407 422
	_skip_nodes(false), _skip_arcs(false) {}
408 423

	
409 424
    /// \brief Constructor
410 425
    ///
411 426
    /// Construct a directed graph writer, which writes to the given
412 427
    /// output file.
413
    DigraphWriter(const char* fn, Digraph& digraph) 
428
    DigraphWriter(const char* fn, const Digraph& digraph) 
414 429
      : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
415 430
	_skip_nodes(false), _skip_arcs(false) {}
416 431

	
417
    /// \brief Copy constructor
418
    ///
419
    /// The copy constructor transfers all data from the other writer,
420
    /// therefore the copied writer will not be usable more. 
421
    DigraphWriter(DigraphWriter& other) 
422
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
423
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
424

	
425
      other._os = 0;
426
      other.local_os = false;
427

	
428
      _node_index.swap(other._node_index);
429
      _arc_index.swap(other._arc_index);
430

	
431
      _node_maps.swap(other._node_maps);
432
      _arc_maps.swap(other._arc_maps);
433
      _attributes.swap(other._attributes);
434

	
435
      _nodes_caption = other._nodes_caption;
436
      _arcs_caption = other._arcs_caption;
437
      _attributes_caption = other._attributes_caption;
438
    }
439

	
440 432
    /// \brief Destructor
441 433
    ~DigraphWriter() {
442 434
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
443 435
	   it != _node_maps.end(); ++it) {
444 436
	delete it->second;
445 437
      }
446 438

	
447 439
      for (typename ArcMaps::iterator it = _arc_maps.begin(); 
448 440
	   it != _arc_maps.end(); ++it) {
449 441
	delete it->second;
450 442
      }
451 443

	
452 444
      for (typename Attributes::iterator it = _attributes.begin(); 
453 445
	   it != _attributes.end(); ++it) {
454 446
	delete it->second;
455 447
      }
456 448

	
457 449
      if (local_os) {
458 450
	delete _os;
459 451
      }
460 452
    }
461 453

	
462 454
  private:
455

	
456
    friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os, 
457
						  const Digraph& digraph);
458
    friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn, 
459
						  const Digraph& digraph);   
460
    friend DigraphWriter<Digraph> digraphWriter<>(const char *fn, 
461
						  const Digraph& digraph);
462

	
463
    DigraphWriter(DigraphWriter& other) 
464
      : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
465
	_skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
466

	
467
      other._os = 0;
468
      other.local_os = false;
469

	
470
      _node_index.swap(other._node_index);
471
      _arc_index.swap(other._arc_index);
472

	
473
      _node_maps.swap(other._node_maps);
474
      _arc_maps.swap(other._arc_maps);
475
      _attributes.swap(other._attributes);
476

	
477
      _nodes_caption = other._nodes_caption;
478
      _arcs_caption = other._arcs_caption;
479
      _attributes_caption = other._attributes_caption;
480
    }
463 481
    
464 482
    DigraphWriter& operator=(const DigraphWriter&);
465 483

	
466 484
  public:
467 485

	
468 486
    /// \name Writing rules
469 487
    /// @{
470 488
    
471 489
    /// \brief Node map reading rule
472 490
    ///
473 491
    /// Add a node map reading rule to the writer.
474 492
    template <typename Map>
475 493
    DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
476 494
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
477 495
      _writer_bits::MapStorageBase<Node>* storage = 
478 496
	new _writer_bits::MapStorage<Node, Map>(map);
479 497
      _node_maps.push_back(std::make_pair(caption, storage));
480 498
      return *this;
481 499
    }
482 500

	
483 501
    /// \brief Node map writing rule
484 502
    ///
485 503
    /// Add a node map writing rule with specialized converter to the
486 504
    /// writer.
487 505
    template <typename Map, typename Converter>
488 506
    DigraphWriter& nodeMap(const std::string& caption, const Map& map, 
489 507
			   const Converter& converter = Converter()) {
490 508
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
491 509
      _writer_bits::MapStorageBase<Node>* storage = 
492 510
	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
493 511
      _node_maps.push_back(std::make_pair(caption, storage));
494 512
      return *this;
495 513
    }
496 514

	
497 515
    /// \brief Arc map writing rule
498 516
    ///
499 517
    /// Add an arc map writing rule to the writer.
500 518
    template <typename Map>
501 519
    DigraphWriter& arcMap(const std::string& caption, const Map& map) {
502 520
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
503 521
      _writer_bits::MapStorageBase<Arc>* storage = 
504 522
	new _writer_bits::MapStorage<Arc, Map>(map);
505 523
      _arc_maps.push_back(std::make_pair(caption, storage));
506 524
      return *this;
507 525
    }
508 526

	
509 527
    /// \brief Arc map writing rule
510 528
    ///
511 529
    /// Add an arc map writing rule with specialized converter to the
512 530
    /// writer.
513 531
    template <typename Map, typename Converter>
514 532
    DigraphWriter& arcMap(const std::string& caption, const Map& map, 
515 533
			  const Converter& converter = Converter()) {
516 534
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
517 535
      _writer_bits::MapStorageBase<Arc>* storage = 
518 536
	new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
519 537
      _arc_maps.push_back(std::make_pair(caption, storage));
520 538
      return *this;
521 539
    }
522 540

	
523 541
    /// \brief Attribute writing rule
524 542
    ///
525 543
    /// Add an attribute writing rule to the writer.
526 544
    template <typename Value>
527 545
    DigraphWriter& attribute(const std::string& caption, const Value& value) {
528 546
      _writer_bits::ValueStorageBase* storage = 
529 547
	new _writer_bits::ValueStorage<Value>(value);
530 548
      _attributes.push_back(std::make_pair(caption, storage));
531 549
      return *this;
532 550
    }
533 551

	
534 552
    /// \brief Attribute writing rule
535 553
    ///
536 554
    /// Add an attribute writing rule with specialized converter to the
537 555
    /// writer.
538 556
    template <typename Value, typename Converter>
539 557
    DigraphWriter& attribute(const std::string& caption, const Value& value, 
540 558
			     const Converter& converter = Converter()) {
541 559
      _writer_bits::ValueStorageBase* storage = 
542 560
	new _writer_bits::ValueStorage<Value, Converter>(value, converter);
543 561
      _attributes.push_back(std::make_pair(caption, storage));
544 562
      return *this;
545 563
    }
546 564

	
547 565
    /// \brief Node writing rule
548 566
    ///
549 567
    /// Add a node writing rule to the writer.
550 568
    DigraphWriter& node(const std::string& caption, const Node& node) {
551 569
      typedef _writer_bits::MapLookUpConverter<Node> Converter;
552 570
      Converter converter(_node_index);
553 571
      _writer_bits::ValueStorageBase* storage = 
554 572
	new _writer_bits::ValueStorage<Node, Converter>(node, converter);
555 573
      _attributes.push_back(std::make_pair(caption, storage));
556 574
      return *this;
557 575
    }
558 576

	
... ...
@@ -751,329 +769,346 @@
751 769
	_writer_bits::writeToken(*_os, _node_index.
752 770
				 find(_digraph.target(a))->second);
753 771
	*_os << '\t';
754 772
	if (label == 0) {
755 773
	  std::ostringstream os;
756 774
	  os << _digraph.id(a);
757 775
	  _writer_bits::writeToken(*_os, os.str());
758 776
	  *_os << '\t';
759 777
	  _arc_index.insert(std::make_pair(a, os.str()));
760 778
	}
761 779
	for (typename ArcMaps::iterator it = _arc_maps.begin();
762 780
	     it != _arc_maps.end(); ++it) {
763 781
	  std::string value = it->second->get(a);
764 782
	  _writer_bits::writeToken(*_os, value);
765 783
	  if (it->first == "label") {
766 784
	    _arc_index.insert(std::make_pair(a, value));
767 785
	  }
768 786
	  *_os << '\t';
769 787
	}
770 788
	*_os << std::endl;
771 789
      }
772 790
    }
773 791

	
774 792
    void createArcIndex() {
775 793
      _writer_bits::MapStorageBase<Arc>* label = 0;
776 794
      for (typename ArcMaps::iterator it = _arc_maps.begin();
777 795
	   it != _arc_maps.end(); ++it) {
778 796
        if (it->first == "label") {
779 797
	  label = it->second;
780 798
	  break;
781 799
	}
782 800
      }
783 801

	
784 802
      if (label == 0) {
785 803
	for (ArcIt a(_digraph); a != INVALID; ++a) {
786 804
	  std::ostringstream os;
787 805
	  os << _digraph.id(a);
788 806
	  _arc_index.insert(std::make_pair(a, os.str()));	  
789 807
	}	
790 808
      } else {
791 809
	for (ArcIt a(_digraph); a != INVALID; ++a) {
792 810
	  std::string value = label->get(a);	  
793 811
	  _arc_index.insert(std::make_pair(a, value));
794 812
	}
795 813
      }
796 814
    }
797 815

	
798 816
    void writeAttributes() {
799 817
      if (_attributes.empty()) return;
800 818
      *_os << "@attributes";
801 819
      if (!_attributes_caption.empty()) {
802 820
	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
803 821
      }
804 822
      *_os << std::endl;
805 823
      for (typename Attributes::iterator it = _attributes.begin();
806 824
	   it != _attributes.end(); ++it) {
807 825
	_writer_bits::writeToken(*_os, it->first) << ' ';
808 826
	_writer_bits::writeToken(*_os, it->second->get());
809 827
	*_os << std::endl;
810 828
      }
811 829
    }
812 830
    
813 831
  public:
814 832
    
815 833
    /// \name Execution of the writer    
816 834
    /// @{
817 835

	
818 836
    /// \brief Start the batch processing
819 837
    ///
820 838
    /// This function starts the batch processing
821 839
    void run() {
822 840
      if (!_skip_nodes) {
823 841
	writeNodes();
824 842
      } else {
825 843
	createNodeIndex();
826 844
      }
827 845
      if (!_skip_arcs) {      
828 846
	writeArcs();
829 847
      } else {
830 848
	createArcIndex();
831 849
      }
832 850
      writeAttributes();
833 851
    }
834 852

	
835 853
    /// \brief Gives back the stream of the writer
836 854
    ///
837 855
    /// Gives back the stream of the writer
838 856
    std::ostream& ostream() {
839 857
      return *_os;
840 858
    }
841 859

	
842 860
    /// @}
843 861
  };
844 862

	
845 863
  /// \relates DigraphWriter
846 864
  template <typename Digraph>
847
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, Digraph& digraph) {
865
  DigraphWriter<Digraph> digraphWriter(std::ostream& os, 
866
				       const Digraph& digraph) {
848 867
    DigraphWriter<Digraph> tmp(os, digraph);
849 868
    return tmp;
850 869
  }
851 870

	
852 871
  /// \relates DigraphWriter
853 872
  template <typename Digraph>
854 873
  DigraphWriter<Digraph> digraphWriter(const std::string& fn, 
855
				       Digraph& digraph) {
874
				       const Digraph& digraph) {
856 875
    DigraphWriter<Digraph> tmp(fn, digraph);
857 876
    return tmp;
858 877
  }
859 878

	
860 879
  /// \relates DigraphWriter
861 880
  template <typename Digraph>
862
  DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
881
  DigraphWriter<Digraph> digraphWriter(const char* fn, 
882
				       const Digraph& digraph) {
863 883
    DigraphWriter<Digraph> tmp(fn, digraph);
864 884
    return tmp;
865 885
  }
866 886

	
887
  template <typename Graph>
888
  class GraphWriter;
889

	
890
  template <typename Graph>
891
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);    
892

	
893
  template <typename Graph>
894
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);   
895

	
896
  template <typename Graph>
897
  GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);    
898

	
867 899
  /// \ingroup lemon_io
868 900
  ///  
869 901
  /// \brief LGF writer for directed graphs
870 902
  ///
871 903
  /// This utility writes an \ref lgf-format "LGF" file.
872 904
  template <typename _Graph>
873 905
  class GraphWriter {
874 906
  public:
875 907

	
876 908
    typedef _Graph Graph;
877 909
    TEMPLATE_GRAPH_TYPEDEFS(Graph);
878 910
    
879 911
  private:
880 912

	
881 913

	
882 914
    std::ostream* _os;
883 915
    bool local_os;
884 916

	
885 917
    Graph& _graph;
886 918

	
887 919
    std::string _nodes_caption;
888 920
    std::string _edges_caption;
889 921
    std::string _attributes_caption;
890 922
    
891 923
    typedef std::map<Node, std::string> NodeIndex;
892 924
    NodeIndex _node_index;
893 925
    typedef std::map<Edge, std::string> EdgeIndex;
894 926
    EdgeIndex _edge_index;
895 927

	
896 928
    typedef std::vector<std::pair<std::string, 
897 929
      _writer_bits::MapStorageBase<Node>* > > NodeMaps;    
898 930
    NodeMaps _node_maps; 
899 931

	
900 932
    typedef std::vector<std::pair<std::string, 
901 933
      _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
902 934
    EdgeMaps _edge_maps;
903 935

	
904 936
    typedef std::vector<std::pair<std::string, 
905 937
      _writer_bits::ValueStorageBase*> > Attributes;
906 938
    Attributes _attributes;
907 939

	
908 940
    bool _skip_nodes;
909 941
    bool _skip_edges;
910 942

	
911 943
  public:
912 944

	
913 945
    /// \brief Constructor
914 946
    ///
915 947
    /// Construct a directed graph writer, which writes to the given
916 948
    /// output stream.
917
    GraphWriter(std::ostream& is, Graph& graph) 
949
    GraphWriter(std::ostream& is, const Graph& graph) 
918 950
      : _os(&is), local_os(false), _graph(graph),
919 951
	_skip_nodes(false), _skip_edges(false) {}
920 952

	
921 953
    /// \brief Constructor
922 954
    ///
923 955
    /// Construct a directed graph writer, which writes to the given
924 956
    /// output file.
925
    GraphWriter(const std::string& fn, Graph& graph) 
957
    GraphWriter(const std::string& fn, const Graph& graph) 
926 958
      : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
927 959
	_skip_nodes(false), _skip_edges(false) {}
928 960

	
929 961
    /// \brief Constructor
930 962
    ///
931 963
    /// Construct a directed graph writer, which writes to the given
932 964
    /// output file.
933
    GraphWriter(const char* fn, Graph& graph) 
965
    GraphWriter(const char* fn, const Graph& graph) 
934 966
      : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
935 967
	_skip_nodes(false), _skip_edges(false) {}
936 968

	
937
    /// \brief Copy constructor
938
    ///
939
    /// The copy constructor transfers all data from the other writer,
940
    /// therefore the copied writer will not be usable more. 
941
    GraphWriter(GraphWriter& other) 
942
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
943
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
944

	
945
      other._os = 0;
946
      other.local_os = false;
947

	
948
      _node_index.swap(other._node_index);
949
      _edge_index.swap(other._edge_index);
950

	
951
      _node_maps.swap(other._node_maps);
952
      _edge_maps.swap(other._edge_maps);
953
      _attributes.swap(other._attributes);
954

	
955
      _nodes_caption = other._nodes_caption;
956
      _edges_caption = other._edges_caption;
957
      _attributes_caption = other._attributes_caption;
958
    }
959

	
960 969
    /// \brief Destructor
961 970
    ~GraphWriter() {
962 971
      for (typename NodeMaps::iterator it = _node_maps.begin(); 
963 972
	   it != _node_maps.end(); ++it) {
964 973
	delete it->second;
965 974
      }
966 975

	
967 976
      for (typename EdgeMaps::iterator it = _edge_maps.begin(); 
968 977
	   it != _edge_maps.end(); ++it) {
969 978
	delete it->second;
970 979
      }
971 980

	
972 981
      for (typename Attributes::iterator it = _attributes.begin(); 
973 982
	   it != _attributes.end(); ++it) {
974 983
	delete it->second;
975 984
      }
976 985

	
977 986
      if (local_os) {
978 987
	delete _os;
979 988
      }
980 989
    }
990
    
991
  private:
981 992

	
982
  private:
983
    
993
    friend GraphWriter<Graph> graphWriter<>(std::ostream& os, 
994
					    const Graph& graph);    
995
    friend GraphWriter<Graph> graphWriter<>(const std::string& fn, 
996
					    const Graph& graph);   
997
    friend GraphWriter<Graph> graphWriter<>(const char *fn, 
998
					    const Graph& graph);    
999

	
1000
    GraphWriter(GraphWriter& other) 
1001
      : _os(other._os), local_os(other.local_os), _graph(other._graph),
1002
	_skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1003

	
1004
      other._os = 0;
1005
      other.local_os = false;
1006

	
1007
      _node_index.swap(other._node_index);
1008
      _edge_index.swap(other._edge_index);
1009

	
1010
      _node_maps.swap(other._node_maps);
1011
      _edge_maps.swap(other._edge_maps);
1012
      _attributes.swap(other._attributes);
1013

	
1014
      _nodes_caption = other._nodes_caption;
1015
      _edges_caption = other._edges_caption;
1016
      _attributes_caption = other._attributes_caption;
1017
    }
1018

	
984 1019
    GraphWriter& operator=(const GraphWriter&);
985 1020

	
986 1021
  public:
987 1022

	
988 1023
    /// \name Writing rules
989 1024
    /// @{
990 1025
    
991 1026
    /// \brief Node map reading rule
992 1027
    ///
993 1028
    /// Add a node map reading rule to the writer.
994 1029
    template <typename Map>
995 1030
    GraphWriter& nodeMap(const std::string& caption, const Map& map) {
996 1031
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
997 1032
      _writer_bits::MapStorageBase<Node>* storage = 
998 1033
	new _writer_bits::MapStorage<Node, Map>(map);
999 1034
      _node_maps.push_back(std::make_pair(caption, storage));
1000 1035
      return *this;
1001 1036
    }
1002 1037

	
1003 1038
    /// \brief Node map writing rule
1004 1039
    ///
1005 1040
    /// Add a node map writing rule with specialized converter to the
1006 1041
    /// writer.
1007 1042
    template <typename Map, typename Converter>
1008 1043
    GraphWriter& nodeMap(const std::string& caption, const Map& map, 
1009 1044
			   const Converter& converter = Converter()) {
1010 1045
      checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1011 1046
      _writer_bits::MapStorageBase<Node>* storage = 
1012 1047
	new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1013 1048
      _node_maps.push_back(std::make_pair(caption, storage));
1014 1049
      return *this;
1015 1050
    }
1016 1051

	
1017 1052
    /// \brief Edge map writing rule
1018 1053
    ///
1019 1054
    /// Add an edge map writing rule to the writer.
1020 1055
    template <typename Map>
1021 1056
    GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1022 1057
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1023 1058
      _writer_bits::MapStorageBase<Edge>* storage = 
1024 1059
	new _writer_bits::MapStorage<Edge, Map>(map);
1025 1060
      _edge_maps.push_back(std::make_pair(caption, storage));
1026 1061
      return *this;
1027 1062
    }
1028 1063

	
1029 1064
    /// \brief Edge map writing rule
1030 1065
    ///
1031 1066
    /// Add an edge map writing rule with specialized converter to the
1032 1067
    /// writer.
1033 1068
    template <typename Map, typename Converter>
1034 1069
    GraphWriter& edgeMap(const std::string& caption, const Map& map, 
1035 1070
			  const Converter& converter = Converter()) {
1036 1071
      checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1037 1072
      _writer_bits::MapStorageBase<Edge>* storage = 
1038 1073
	new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1039 1074
      _edge_maps.push_back(std::make_pair(caption, storage));
1040 1075
      return *this;
1041 1076
    }
1042 1077

	
1043 1078
    /// \brief Arc map writing rule
1044 1079
    ///
1045 1080
    /// Add an arc map writing rule to the writer.
1046 1081
    template <typename Map>
1047 1082
    GraphWriter& arcMap(const std::string& caption, const Map& map) {
1048 1083
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1049 1084
      _writer_bits::MapStorageBase<Edge>* forward_storage = 
1050 1085
	new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1051 1086
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1052 1087
      _writer_bits::MapStorageBase<Edge>* backward_storage = 
1053 1088
	new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1054 1089
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1055 1090
      return *this;
1056 1091
    }
1057 1092

	
1058 1093
    /// \brief Arc map writing rule
1059 1094
    ///
1060 1095
    /// Add an arc map writing rule with specialized converter to the
1061 1096
    /// writer.
1062 1097
    template <typename Map, typename Converter>
1063 1098
    GraphWriter& arcMap(const std::string& caption, const Map& map, 
1064 1099
			  const Converter& converter = Converter()) {
1065 1100
      checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1066 1101
      _writer_bits::MapStorageBase<Edge>* forward_storage = 
1067 1102
	new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1068 1103
	(_graph, map, converter);
1069 1104
      _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1070 1105
      _writer_bits::MapStorageBase<Edge>* backward_storage = 
1071 1106
	new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1072 1107
	(_graph, map, converter);
1073 1108
      _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1074 1109
      return *this;
1075 1110
    }
1076 1111

	
1077 1112
    /// \brief Attribute writing rule
1078 1113
    ///
1079 1114
    /// Add an attribute writing rule to the writer.
... ...
@@ -1317,117 +1352,117 @@
1317 1352
	_writer_bits::writeToken(*_os, _node_index.
1318 1353
				 find(_graph.v(e))->second);
1319 1354
	*_os << '\t';
1320 1355
	if (label == 0) {
1321 1356
	  std::ostringstream os;
1322 1357
	  os << _graph.id(e);
1323 1358
	  _writer_bits::writeToken(*_os, os.str());
1324 1359
	  *_os << '\t';
1325 1360
	  _edge_index.insert(std::make_pair(e, os.str()));
1326 1361
	}
1327 1362
	for (typename EdgeMaps::iterator it = _edge_maps.begin();
1328 1363
	     it != _edge_maps.end(); ++it) {
1329 1364
	  std::string value = it->second->get(e);
1330 1365
	  _writer_bits::writeToken(*_os, value);
1331 1366
	  if (it->first == "label") {
1332 1367
	    _edge_index.insert(std::make_pair(e, value));
1333 1368
	  }
1334 1369
	  *_os << '\t';
1335 1370
	}
1336 1371
	*_os << std::endl;
1337 1372
      }
1338 1373
    }
1339 1374

	
1340 1375
    void createEdgeIndex() {
1341 1376
      _writer_bits::MapStorageBase<Edge>* label = 0;
1342 1377
      for (typename EdgeMaps::iterator it = _edge_maps.begin();
1343 1378
	   it != _edge_maps.end(); ++it) {
1344 1379
        if (it->first == "label") {
1345 1380
	  label = it->second;
1346 1381
	  break;
1347 1382
	}
1348 1383
      }
1349 1384

	
1350 1385
      if (label == 0) {
1351 1386
	for (EdgeIt e(_graph); e != INVALID; ++e) {
1352 1387
	  std::ostringstream os;
1353 1388
	  os << _graph.id(e);
1354 1389
	  _edge_index.insert(std::make_pair(e, os.str()));	  
1355 1390
	}	
1356 1391
      } else {
1357 1392
	for (EdgeIt e(_graph); e != INVALID; ++e) {
1358 1393
	  std::string value = label->get(e);	  
1359 1394
	  _edge_index.insert(std::make_pair(e, value));
1360 1395
	}
1361 1396
      }
1362 1397
    }
1363 1398

	
1364 1399
    void writeAttributes() {
1365 1400
      if (_attributes.empty()) return;
1366 1401
      *_os << "@attributes";
1367 1402
      if (!_attributes_caption.empty()) {
1368 1403
	_writer_bits::writeToken(*_os << ' ', _attributes_caption);
1369 1404
      }
1370 1405
      *_os << std::endl;
1371 1406
      for (typename Attributes::iterator it = _attributes.begin();
1372 1407
	   it != _attributes.end(); ++it) {
1373 1408
	_writer_bits::writeToken(*_os, it->first) << ' ';
1374 1409
	_writer_bits::writeToken(*_os, it->second->get());
1375 1410
	*_os << std::endl;
1376 1411
      }
1377 1412
    }
1378 1413
    
1379 1414
  public:
1380 1415
    
1381 1416
    /// \name Execution of the writer    
1382 1417
    /// @{
1383 1418

	
1384 1419
    /// \brief Start the batch processing
1385 1420
    ///
1386 1421
    /// This function starts the batch processing
1387 1422
    void run() {
1388 1423
      if (!_skip_nodes) {
1389 1424
	writeNodes();
1390 1425
      } else {
1391 1426
	createNodeIndex();
1392 1427
      }
1393 1428
      if (!_skip_edges) {      
1394 1429
	writeEdges();
1395 1430
      } else {
1396 1431
	createEdgeIndex();
1397 1432
      }
1398 1433
      writeAttributes();
1399 1434
    }
1400 1435

	
1401 1436
    /// \brief Gives back the stream of the writer
1402 1437
    ///
1403 1438
    /// Gives back the stream of the writer
1404 1439
    std::ostream& ostream() {
1405 1440
      return *_os;
1406 1441
    }
1407 1442

	
1408 1443
    /// @}
1409 1444
  };
1410 1445

	
1411 1446
  /// \relates GraphWriter
1412 1447
  template <typename Graph>
1413
  GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) {
1448
  GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1414 1449
    GraphWriter<Graph> tmp(os, graph);
1415 1450
    return tmp;
1416 1451
  }
1417 1452

	
1418 1453
  /// \relates GraphWriter
1419 1454
  template <typename Graph>
1420
  GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) {
1455
  GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1421 1456
    GraphWriter<Graph> tmp(fn, graph);
1422 1457
    return tmp;
1423 1458
  }
1424 1459

	
1425 1460
  /// \relates GraphWriter
1426 1461
  template <typename Graph>
1427
  GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) {
1462
  GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1428 1463
    GraphWriter<Graph> tmp(fn, graph);
1429 1464
    return tmp;
1430 1465
  }
1431 1466
}
1432 1467

	
1433 1468
#endif
0 comments (0 inline)