266 } |
266 } |
267 } |
267 } |
268 str = os.str(); |
268 str = os.str(); |
269 return is; |
269 return is; |
270 } |
270 } |
271 |
|
272 std::istream& readIdentifier(std::istream& is, std::string& str) { |
|
273 std::ostringstream os; |
|
274 |
|
275 char c; |
|
276 is >> std::ws; |
|
277 |
|
278 if (!is.get(c)) |
|
279 return is; |
|
280 |
|
281 if (!isIdentifierFirstChar(c)) |
|
282 throw DataFormatError("Wrong char in identifier"); |
|
283 |
|
284 os << c; |
|
285 |
|
286 while (is.get(c) && !isWhiteSpace(c)) { |
|
287 if (!isIdentifierChar(c)) |
|
288 throw DataFormatError("Wrong char in identifier"); |
|
289 os << c; |
|
290 } |
|
291 if (!is) is.clear(); |
|
292 |
|
293 str = os.str(); |
|
294 return is; |
|
295 } |
|
296 |
271 |
297 } |
272 } |
298 |
273 |
299 /// \e |
274 /// \ingroup lemon_io |
|
275 /// |
|
276 /// \brief LGF reader for directed graphs |
|
277 /// |
|
278 /// This utility reads an \ref lgf-format "LGF" file. |
|
279 /// |
|
280 /// The reading method does a batch processing. The user creates a |
|
281 /// reader object, then various reading rules can be added to the |
|
282 /// reader, and eventually the reading is executed with the \c run() |
|
283 /// member function. A map reading rule can be added to the reader |
|
284 /// with the \c nodeMap() or \c arcMap() members. An optional |
|
285 /// converter parameter can also be added as a standard functor converting from |
|
286 /// std::string to the value type of the map. If it is set, it will |
|
287 /// determine how the tokens in the file should be is converted to the map's |
|
288 /// value type. If the functor is not set, then a default conversion |
|
289 /// will be used. One map can be read into multiple map objects at the |
|
290 /// same time. The \c attribute(), \c node() and \c arc() functions |
|
291 /// are used to add attribute reading rules. |
|
292 /// |
|
293 ///\code |
|
294 /// DigraphReader<Digraph>(std::cin, digraph). |
|
295 /// nodeMap("coordinates", coord_map). |
|
296 /// arcMap("capacity", cap_map). |
|
297 /// node("source", src). |
|
298 /// node("target", trg). |
|
299 /// attribute("caption", caption). |
|
300 /// run(); |
|
301 ///\endcode |
|
302 /// |
|
303 /// By default the reader uses the first section in the file of the |
|
304 /// proper type. If a section has an optional name, then it can be |
|
305 /// selected for reading by giving an optional name parameter to |
|
306 /// the \c nodes(), \c arcs() or \c attributes() |
|
307 /// functions. |
|
308 /// |
|
309 /// The \c useNodes() and \c useArcs() functions are used to tell the reader |
|
310 /// that the nodes or arcs should not be constructed (added to the |
|
311 /// graph) during the reading, but instead the label map of the items |
|
312 /// are given as a parameter of these functions. An |
|
313 /// application of these function is multipass reading, which is |
|
314 /// important if two \e \@arcs sections must be read from the |
|
315 /// file. In this example the first phase would read the node set and one |
|
316 /// of the arc sets, while the second phase would read the second arc |
|
317 /// set into an \e ArcSet class (\c SmartArcSet or \c ListArcSet). |
|
318 /// The previously read label node map should be passed to the \c |
|
319 /// useNodes() functions. Another application of multipass reading when |
|
320 /// paths are given as a node map or an arc map. It is impossible read this in |
|
321 /// a single pass, because the arcs are not constructed when the node |
|
322 /// maps are read. |
300 template <typename _Digraph> |
323 template <typename _Digraph> |
301 class DigraphReader { |
324 class DigraphReader { |
302 public: |
325 public: |
303 |
326 |
304 typedef _Digraph Digraph; |
327 typedef _Digraph Digraph; |
339 int line_num; |
362 int line_num; |
340 std::istringstream line; |
363 std::istringstream line; |
341 |
364 |
342 public: |
365 public: |
343 |
366 |
344 /// \e |
367 /// \brief Constructor |
|
368 /// |
|
369 /// Construct a directed graph reader, which reads from the given |
|
370 /// input stream. |
345 DigraphReader(std::istream& is, Digraph& digraph) |
371 DigraphReader(std::istream& is, Digraph& digraph) |
346 : _is(&is), local_is(false), _digraph(digraph), |
372 : _is(&is), local_is(false), _digraph(digraph), |
347 _use_nodes(false), _use_arcs(false) {} |
373 _use_nodes(false), _use_arcs(false) {} |
348 |
374 |
349 /// \e |
375 /// \brief Constructor |
|
376 /// |
|
377 /// Construct a directed graph reader, which reads from the given |
|
378 /// file. |
350 DigraphReader(const std::string& fn, Digraph& digraph) |
379 DigraphReader(const std::string& fn, Digraph& digraph) |
351 : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph), |
380 : _is(new std::ifstream(fn.c_str())), local_is(true), _digraph(digraph), |
352 _use_nodes(false), _use_arcs(false) {} |
381 _use_nodes(false), _use_arcs(false) {} |
353 |
382 |
354 |
383 /// \brief Constructor |
355 /// \e |
384 /// |
|
385 /// Construct a directed graph reader, which reads from the given |
|
386 /// file. |
356 DigraphReader(const char* fn, Digraph& digraph) |
387 DigraphReader(const char* fn, Digraph& digraph) |
357 : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph), |
388 : _is(new std::ifstream(fn)), local_is(true), _digraph(digraph), |
358 _use_nodes(false), _use_arcs(false) {} |
389 _use_nodes(false), _use_arcs(false) {} |
359 |
390 |
360 /// \e |
391 /// \brief Copy constructor |
|
392 /// |
|
393 /// The copy constructor transfers all data from the other reader, |
|
394 /// therefore the copied reader will not be usable more. |
361 DigraphReader(DigraphReader& other) |
395 DigraphReader(DigraphReader& other) |
362 : _is(other._is), local_is(other.local_is), _digraph(other._digraph), |
396 : _is(other._is), local_is(other.local_is), _digraph(other._digraph), |
363 _use_nodes(other._use_nodes), _use_arcs(other._use_arcs) { |
397 _use_nodes(other._use_nodes), _use_arcs(other._use_arcs) { |
364 |
398 |
365 other.is = 0; |
399 other.is = 0; |
404 |
438 |
405 DigraphReader& operator=(const DigraphReader&); |
439 DigraphReader& operator=(const DigraphReader&); |
406 |
440 |
407 public: |
441 public: |
408 |
442 |
409 /// \e |
443 /// \name Reading rules |
|
444 /// @{ |
|
445 |
|
446 /// \brief Node map reading rule |
|
447 /// |
|
448 /// Add a node map reading rule to the reader. |
410 template <typename Map> |
449 template <typename Map> |
411 DigraphReader& nodeMap(const std::string& caption, Map& map) { |
450 DigraphReader& nodeMap(const std::string& caption, Map& map) { |
412 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
451 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
413 _reader_bits::MapStorageBase<Node>* storage = |
452 _reader_bits::MapStorageBase<Node>* storage = |
414 new _reader_bits::MapStorage<Node, Map>(map); |
453 new _reader_bits::MapStorage<Node, Map>(map); |
415 _node_maps.push_back(std::make_pair(caption, storage)); |
454 _node_maps.push_back(std::make_pair(caption, storage)); |
416 return *this; |
455 return *this; |
417 } |
456 } |
418 |
457 |
419 /// \e |
458 /// \brief Node map reading rule |
|
459 /// |
|
460 /// Add a node map reading rule with specialized converter to the |
|
461 /// reader. |
420 template <typename Map, typename Converter> |
462 template <typename Map, typename Converter> |
421 DigraphReader& nodeMap(const std::string& caption, Map& map, |
463 DigraphReader& nodeMap(const std::string& caption, Map& map, |
422 const Converter& converter = Converter()) { |
464 const Converter& converter = Converter()) { |
423 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
465 checkConcept<concepts::WriteMap<Node, typename Map::Value>, Map>(); |
424 _reader_bits::MapStorageBase<Node>* storage = |
466 _reader_bits::MapStorageBase<Node>* storage = |
425 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
467 new _reader_bits::MapStorage<Node, Map, Converter>(map, converter); |
426 _node_maps.push_back(std::make_pair(caption, storage)); |
468 _node_maps.push_back(std::make_pair(caption, storage)); |
427 return *this; |
469 return *this; |
428 } |
470 } |
429 |
471 |
430 /// \e |
472 /// \brief Arc map reading rule |
|
473 /// |
|
474 /// Add an arc map reading rule to the reader. |
431 template <typename Map> |
475 template <typename Map> |
432 DigraphReader& arcMap(const std::string& caption, Map& map) { |
476 DigraphReader& arcMap(const std::string& caption, Map& map) { |
433 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
477 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
434 _reader_bits::MapStorageBase<Arc>* storage = |
478 _reader_bits::MapStorageBase<Arc>* storage = |
435 new _reader_bits::MapStorage<Arc, Map>(map); |
479 new _reader_bits::MapStorage<Arc, Map>(map); |
436 _arc_maps.push_back(std::make_pair(caption, storage)); |
480 _arc_maps.push_back(std::make_pair(caption, storage)); |
437 return *this; |
481 return *this; |
438 } |
482 } |
439 |
483 |
440 /// \e |
484 /// \brief Arc map reading rule |
|
485 /// |
|
486 /// Add an arc map reading rule with specialized converter to the |
|
487 /// reader. |
441 template <typename Map, typename Converter> |
488 template <typename Map, typename Converter> |
442 DigraphReader& arcMap(const std::string& caption, Map& map, |
489 DigraphReader& arcMap(const std::string& caption, Map& map, |
443 const Converter& converter = Converter()) { |
490 const Converter& converter = Converter()) { |
444 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
491 checkConcept<concepts::WriteMap<Arc, typename Map::Value>, Map>(); |
445 _reader_bits::MapStorageBase<Arc>* storage = |
492 _reader_bits::MapStorageBase<Arc>* storage = |
446 new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter); |
493 new _reader_bits::MapStorage<Arc, Map, Converter>(map, converter); |
447 _arc_maps.push_back(std::make_pair(caption, storage)); |
494 _arc_maps.push_back(std::make_pair(caption, storage)); |
448 return *this; |
495 return *this; |
449 } |
496 } |
450 |
497 |
451 /// \e |
498 /// \brief Attribute reading rule |
|
499 /// |
|
500 /// Add an attribute reading rule to the reader. |
452 template <typename Value> |
501 template <typename Value> |
453 DigraphReader& attribute(const std::string& caption, Value& value) { |
502 DigraphReader& attribute(const std::string& caption, Value& value) { |
454 _reader_bits::ValueStorageBase* storage = |
503 _reader_bits::ValueStorageBase* storage = |
455 new _reader_bits::ValueStorage<Value>(value); |
504 new _reader_bits::ValueStorage<Value>(value); |
456 _attributes.insert(std::make_pair(caption, storage)); |
505 _attributes.insert(std::make_pair(caption, storage)); |
457 return *this; |
506 return *this; |
458 } |
507 } |
459 |
508 |
460 /// \e |
509 /// \brief Attribute reading rule |
|
510 /// |
|
511 /// Add an attribute reading rule with specialized converter to the |
|
512 /// reader. |
461 template <typename Value, typename Converter> |
513 template <typename Value, typename Converter> |
462 DigraphReader& attribute(const std::string& caption, Value& value, |
514 DigraphReader& attribute(const std::string& caption, Value& value, |
463 const Converter& converter = Converter()) { |
515 const Converter& converter = Converter()) { |
464 _reader_bits::ValueStorageBase* storage = |
516 _reader_bits::ValueStorageBase* storage = |
465 new _reader_bits::ValueStorage<Value, Converter>(value, converter); |
517 new _reader_bits::ValueStorage<Value, Converter>(value, converter); |
466 _attributes.insert(std::make_pair(caption, storage)); |
518 _attributes.insert(std::make_pair(caption, storage)); |
467 return *this; |
519 return *this; |
468 } |
520 } |
469 |
521 |
470 /// \e |
522 /// \brief Node reading rule |
|
523 /// |
|
524 /// Add a node reading rule to reader. |
471 DigraphReader& node(const std::string& caption, Node& node) { |
525 DigraphReader& node(const std::string& caption, Node& node) { |
472 typedef _reader_bits::MapLookUpConverter<Node> Converter; |
526 typedef _reader_bits::MapLookUpConverter<Node> Converter; |
473 Converter converter(_node_index); |
527 Converter converter(_node_index); |
474 _reader_bits::ValueStorageBase* storage = |
528 _reader_bits::ValueStorageBase* storage = |
475 new _reader_bits::ValueStorage<Node, Converter>(node, converter); |
529 new _reader_bits::ValueStorage<Node, Converter>(node, converter); |
476 _attributes.insert(std::make_pair(caption, storage)); |
530 _attributes.insert(std::make_pair(caption, storage)); |
477 return *this; |
531 return *this; |
478 } |
532 } |
479 |
533 |
480 /// \e |
534 /// \brief Arc reading rule |
|
535 /// |
|
536 /// Add an arc reading rule to reader. |
481 DigraphReader& arc(const std::string& caption, Arc& arc) { |
537 DigraphReader& arc(const std::string& caption, Arc& arc) { |
482 typedef _reader_bits::MapLookUpConverter<Arc> Converter; |
538 typedef _reader_bits::MapLookUpConverter<Arc> Converter; |
483 Converter converter(_arc_index); |
539 Converter converter(_arc_index); |
484 _reader_bits::ValueStorageBase* storage = |
540 _reader_bits::ValueStorageBase* storage = |
485 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); |
541 new _reader_bits::ValueStorage<Arc, Converter>(arc, converter); |
486 _attributes.insert(std::make_pair(caption, storage)); |
542 _attributes.insert(std::make_pair(caption, storage)); |
487 return *this; |
543 return *this; |
488 } |
544 } |
489 |
545 |
490 /// \e |
546 /// @} |
|
547 |
|
548 /// \name Select section by name |
|
549 /// @{ |
|
550 |
|
551 /// \brief Set \c \@nodes section to be read |
|
552 /// |
|
553 /// Set \c \@nodes section to be read |
491 DigraphReader& nodes(const std::string& caption) { |
554 DigraphReader& nodes(const std::string& caption) { |
492 _nodes_caption = caption; |
555 _nodes_caption = caption; |
493 return *this; |
556 return *this; |
494 } |
557 } |
495 |
558 |
496 /// \e |
559 /// \brief Set \c \@arcs section to be read |
|
560 /// |
|
561 /// Set \c \@arcs section to be read |
497 DigraphReader& arcs(const std::string& caption) { |
562 DigraphReader& arcs(const std::string& caption) { |
498 _arcs_caption = caption; |
563 _arcs_caption = caption; |
499 return *this; |
564 return *this; |
500 } |
565 } |
501 |
566 |
502 /// \e |
567 /// \brief Set \c \@attributes section to be read |
|
568 /// |
|
569 /// Set \c \@attributes section to be read |
503 DigraphReader& attributes(const std::string& caption) { |
570 DigraphReader& attributes(const std::string& caption) { |
504 _attributes_caption = caption; |
571 _attributes_caption = caption; |
505 return *this; |
572 return *this; |
506 } |
573 } |
507 |
574 |
508 /// \e |
575 /// @} |
|
576 |
|
577 /// \name Using previously constructed node or arc set |
|
578 /// @{ |
|
579 |
|
580 /// \brief Use previously constructed node set |
|
581 /// |
|
582 /// Use previously constructed node set, and specify the node |
|
583 /// label map. |
509 template <typename Map> |
584 template <typename Map> |
510 DigraphReader& useNodes(const Map& map) { |
585 DigraphReader& useNodes(const Map& map) { |
511 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
586 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>(); |
512 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); |
587 LEMON_ASSERT(!_use_nodes, "Multiple usage of useNodes() member"); |
513 _use_nodes = true; |
588 _use_nodes = true; |