0
4
0
... | ... |
@@ -377,63 +377,39 @@ |
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 |
|
|
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, |
... | ... |
@@ -571,38 +547,39 @@ |
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 |
|
|
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 |
|
... | ... |
@@ -1197,64 +1174,73 @@ |
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 |
|
|
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 |
|
|
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 '-'. |
... | ... |
@@ -1355,36 +1341,38 @@ |
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 |
|
... | ... |
@@ -2027,32 +2015,62 @@ |
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 |
... | ... |
@@ -337,64 +337,43 @@ |
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 |
|
|
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 |
... | ... |
@@ -513,37 +492,40 @@ |
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 |
|
|
508 |
template <typename DGR> |
|
509 |
friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, |
|
530 | 510 |
std::ostream& os); |
531 |
|
|
511 |
template <typename DGR> |
|
512 |
friend DigraphWriter<DGR> digraphWriter(const DGR& digraph, |
|
532 | 513 |
const std::string& fn); |
533 |
|
|
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 |
|
... | ... |
@@ -920,65 +902,75 @@ |
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 |
|
|
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 |
|
|
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. |
... | ... |
@@ -1068,37 +1060,40 @@ |
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 |
|
|
1076 |
template <typename GR> |
|
1077 |
friend GraphWriter<GR> graphWriter(const GR& graph, |
|
1085 | 1078 |
std::ostream& os); |
1086 |
|
|
1079 |
template <typename GR> |
|
1080 |
friend GraphWriter<GR> graphWriter(const GR& graph, |
|
1087 | 1081 |
const std::string& fn); |
1088 |
|
|
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 |
|
... | ... |
@@ -1521,32 +1516,63 @@ |
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 |
... | ... |
@@ -916,69 +916,85 @@ |
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 |
|
|
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 |
|
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 |
|
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. |
... | ... |
@@ -331,112 +331,102 @@ |
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 |
|
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 |
|
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, |
|
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, |
|
372 |
struct ShiftMultiplier<Result, 32> { |
|
383 | 373 |
static const Result multiplier() { |
384 |
return static_cast<Result>(1.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, |
|
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, |
|
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, |
|
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, |
|
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()); |
0 comments (0 inline)