gravatar
alpar (Alpar Juttner)
alpar@cs.elte.hu
Merge
0 4 0
merge default
0 files changed with 203 insertions and 153 deletions:
↑ Collapse diff ↑
Show white space 96 line context
... ...
@@ -345,127 +345,103 @@
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 394
  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
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.
... ...
@@ -539,102 +515,103 @@
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,
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, 
590 567
                                                  const std::string& fn);
591
    friend DigraphReader<Digraph> digraphReader<>(Digraph& digraph,
592
                                                  const char *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()) {
... ...
@@ -1165,128 +1142,137 @@
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 1223

	
1216
  /// \brief Return a \ref GraphReader class
1217
  ///
1218
  /// This function just returns a \ref GraphReader class.
1219
  /// \relates GraphReader
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

	
... ...
@@ -1323,100 +1309,102 @@
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()) {
... ...
@@ -1995,96 +1983,126 @@
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);
Show white space 96 line context
... ...
@@ -305,128 +305,107 @@
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:
... ...
@@ -481,101 +460,104 @@
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,
508
    template <typename DGR>
509
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, 
530 510
                                                  std::ostream& os);
531
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
511
    template <typename DGR>
512
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
532 513
                                                  const std::string& fn);
533
    friend DigraphWriter<Digraph> digraphWriter<>(const Digraph& digraph,
514
    template <typename DGR>
515
    friend DigraphWriter<DGR> digraphWriter(const DGR& digraph,
534 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>();
... ...
@@ -888,129 +870,139 @@
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

	
... ...
@@ -1036,101 +1028,104 @@
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,
1076
    template <typename GR>
1077
    friend GraphWriter<GR> graphWriter(const GR& graph,
1085 1078
                                            std::ostream& os);
1086
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1079
    template <typename GR>
1080
    friend GraphWriter<GR> graphWriter(const GR& graph,
1087 1081
                                            const std::string& fn);
1088
    friend GraphWriter<Graph> graphWriter<>(const Graph& graph,
1082
    template <typename GR>
1083
    friend GraphWriter<GR> graphWriter(const GR& graph,
1089 1084
                                            const char *fn);
1090 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>();
... ...
@@ -1489,96 +1484,127 @@
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

	
Show white space 96 line context
... ...
@@ -884,133 +884,149 @@
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> {
945
      static void copy(Target& target, const Source& source) {
946
        target.clear();
947
        for (typename Source::RevArcIt it(source); it != INVALID; ++it) {
948
          target.addFront(it);
949
        }
950
      }
951
    };
952

	
953
    template <typename Target, typename Source>
954
    struct PathCopySelector<Target, Source, true, false> {
943
    struct PathCopySelectorForward<Target, Source, true> {
955 944
      static void copy(Target& target, const Source& source) {
956 945
        target.clear();
957 946
        target.build(source);
958 947
      }
959 948
    };
960 949

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

	
961 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
Show white space 96 line context
... ...
@@ -299,176 +299,166 @@
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
    };
0 comments (0 inline)