223 Writer writer; |
223 Writer writer; |
224 }; |
224 }; |
225 |
225 |
226 |
226 |
227 template <typename _Item> |
227 template <typename _Item> |
228 class IdWriterBase { |
228 class LabelWriterBase { |
229 public: |
229 public: |
230 typedef _Item Item; |
230 typedef _Item Item; |
231 virtual ~IdWriterBase() {} |
231 virtual ~LabelWriterBase() {} |
232 virtual void write(std::ostream&, const Item&) const = 0; |
232 virtual void write(std::ostream&, const Item&) const = 0; |
233 virtual bool isIdWriter() const = 0; |
233 virtual bool isLabelWriter() const = 0; |
234 }; |
234 }; |
235 |
235 |
236 template <typename _Item, typename _BoxedIdWriter> |
236 template <typename _Item, typename _BoxedLabelWriter> |
237 class IdWriter : public IdWriterBase<_Item> { |
237 class LabelWriter : public LabelWriterBase<_Item> { |
238 public: |
238 public: |
239 typedef _Item Item; |
239 typedef _Item Item; |
240 typedef _BoxedIdWriter BoxedIdWriter; |
240 typedef _BoxedLabelWriter BoxedLabelWriter; |
241 |
241 |
242 const BoxedIdWriter& idWriter; |
242 const BoxedLabelWriter& labelWriter; |
243 |
243 |
244 IdWriter(const BoxedIdWriter& _idWriter) |
244 LabelWriter(const BoxedLabelWriter& _labelWriter) |
245 : idWriter(_idWriter) {} |
245 : labelWriter(_labelWriter) {} |
246 |
246 |
247 virtual void write(std::ostream& os, const Item& item) const { |
247 virtual void write(std::ostream& os, const Item& item) const { |
248 idWriter.writeId(os, item); |
248 labelWriter.writeLabel(os, item); |
249 } |
249 } |
250 |
250 |
251 virtual bool isIdWriter() const { |
251 virtual bool isLabelWriter() const { |
252 return idWriter.isIdWriter(); |
252 return labelWriter.isLabelWriter(); |
253 } |
253 } |
254 }; |
254 }; |
255 |
255 |
256 } |
256 } |
257 |
257 |
372 |
372 |
373 /// \ingroup io_group |
373 /// \ingroup io_group |
374 /// \brief SectionWriter for writing a graph's nodeset. |
374 /// \brief SectionWriter for writing a graph's nodeset. |
375 /// |
375 /// |
376 /// The lemon format can store multiple graph nodesets with several maps. |
376 /// The lemon format can store multiple graph nodesets with several maps. |
377 /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the |
377 /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but |
378 /// \c nodeset_id may be empty. |
378 /// the \c nodeset_name may be empty. |
379 /// |
379 /// |
380 /// The first line of the section contains the names of the maps separated |
380 /// The first line of the section contains the names of the maps separated |
381 /// with white spaces. Each next lines describes a node in the nodeset, and |
381 /// with white spaces. Each next lines describes a node in the nodeset, and |
382 /// contains the mapped values for each map. |
382 /// contains the mapped values for each map. |
383 /// |
383 /// |
384 /// If the nodeset contains an \c "id" named map then it will be regarded |
384 /// If the nodeset contains an \c "label" named map then it will be regarded |
385 /// as id map. This map should contain only unique values and when the |
385 /// as label map. This map should contain only unique values and when the |
386 /// \c writeId() member will be called with a node it will write it's id. |
386 /// \c writeLabel() member will be called with a node it will write it's |
387 /// Otherwise if the \c _forceIdMap constructor parameter is true then |
387 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true |
388 /// the id map will be the id in the graph. |
388 /// then the label map will be the id in the graph. |
389 /// |
389 /// |
390 /// \relates LemonWriter |
390 /// \relates LemonWriter |
391 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
391 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
392 class NodeSetWriter : public LemonWriter::SectionWriter { |
392 class NodeSetWriter : public LemonWriter::SectionWriter { |
393 typedef LemonWriter::SectionWriter Parent; |
393 typedef LemonWriter::SectionWriter Parent; |
398 typedef typename Graph::Node Node; |
398 typedef typename Graph::Node Node; |
399 |
399 |
400 /// \brief Constructor. |
400 /// \brief Constructor. |
401 /// |
401 /// |
402 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and |
402 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and |
403 /// attach it into the given LemonWriter. If the \c _forceIdMap |
403 /// attach it into the given LemonWriter. If the \c _forceLabelMap |
404 /// parameter is true then the writer will write own id map when |
404 /// parameter is true then the writer will write own label map when |
405 /// the user does not give "id" named map. |
405 /// the user does not give "label" named map. |
406 NodeSetWriter(LemonWriter& _writer, const Graph& _graph, |
406 NodeSetWriter(LemonWriter& _writer, const Graph& _graph, |
407 const std::string& _id = std::string(), |
407 const std::string& _name = std::string(), |
408 bool _forceIdMap = true) |
408 bool _forceLabelMap = true) |
409 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
409 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
410 graph(_graph), id(_id) {} |
410 graph(_graph), name(_name) {} |
411 |
411 |
412 /// \brief Destructor. |
412 /// \brief Destructor. |
413 /// |
413 /// |
414 /// Destructor for NodeSetWriter. |
414 /// Destructor for NodeSetWriter. |
415 virtual ~NodeSetWriter() { |
415 virtual ~NodeSetWriter() { |
452 |
452 |
453 /// \brief The header of the section. |
453 /// \brief The header of the section. |
454 /// |
454 /// |
455 /// It gives back the header of the section. |
455 /// It gives back the header of the section. |
456 virtual std::string header() { |
456 virtual std::string header() { |
457 return "@nodeset " + id; |
457 return "@nodeset " + name; |
458 } |
458 } |
459 |
459 |
460 /// \brief Writer function of the section. |
460 /// \brief Writer function of the section. |
461 /// |
461 /// |
462 /// Write the content of the section. |
462 /// Write the content of the section. |
463 virtual void write(std::ostream& os) { |
463 virtual void write(std::ostream& os) { |
464 for (int i = 0; i < (int)writers.size(); ++i) { |
464 for (int i = 0; i < (int)writers.size(); ++i) { |
465 if (writers[i].first == "id") { |
465 if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) { |
466 idMap = writers[i].second; |
466 labelMap = writers[i].second; |
467 forceIdMap = false; |
467 forceLabelMap = false; |
468 break; |
468 break; |
469 } |
469 } |
470 } |
470 } |
471 if (forceIdMap) { |
471 if (forceLabelMap) { |
472 os << "id\t"; |
472 os << "label\t"; |
473 } |
473 } |
474 for (int i = 0; i < (int)writers.size(); ++i) { |
474 for (int i = 0; i < (int)writers.size(); ++i) { |
475 os << writers[i].first << '\t'; |
475 os << writers[i].first << '\t'; |
476 } |
476 } |
477 os << std::endl; |
477 os << std::endl; |
478 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { |
478 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) { |
479 if (forceIdMap) { |
479 if (forceLabelMap) { |
480 os << graph.id(it) << '\t'; |
480 os << graph.id(it) << '\t'; |
481 } |
481 } |
482 for (int i = 0; i < (int)writers.size(); ++i) { |
482 for (int i = 0; i < (int)writers.size(); ++i) { |
483 writers[i].second->write(os, it); |
483 writers[i].second->write(os, it); |
484 os << '\t'; |
484 os << '\t'; |
487 } |
487 } |
488 } |
488 } |
489 |
489 |
490 public: |
490 public: |
491 |
491 |
492 /// \brief Returns true if the nodeset can write the ids of the nodes. |
492 /// \brief Returns true if the nodeset can write the labels of the nodes. |
493 /// |
493 /// |
494 /// Returns true if the nodeset can write the ids of the nodes. |
494 /// Returns true if the nodeset can write the labels of the nodes. |
495 /// It is possible only if an "id" named map was written or the |
495 /// It is possible only if an "label" named map was written or the |
496 /// \c _forceIdMap constructor parameter was true. |
496 /// \c _forceLabelMap constructor parameter was true. |
497 bool isIdWriter() const { |
497 bool isLabelWriter() const { |
498 return idMap != 0 || forceIdMap; |
498 return labelMap != 0 || forceLabelMap; |
499 } |
499 } |
500 |
500 |
501 /// \brief Write the id of the given node. |
501 /// \brief Write the label of the given node. |
502 /// |
502 /// |
503 /// It writes the id of the given node. If there was written an "id" |
503 /// It writes the label of the given node. If there was written an "label" |
504 /// named map then it will write the map value belongs to the node. |
504 /// named map then it will write the map value belongs to the node. |
505 /// Otherwise if the \c forceId parameter was true it will write |
505 /// Otherwise if the \c forceLabel parameter was true it will write |
506 /// its id in the graph. |
506 /// its label in the graph. |
507 void writeId(std::ostream& os, const Node& item) const { |
507 void writeLabel(std::ostream& os, const Node& item) const { |
508 if (forceIdMap) { |
508 if (forceLabelMap) { |
509 os << graph.id(item); |
509 os << graph.id(item); |
510 } else { |
510 } else { |
511 idMap->write(os, item); |
511 labelMap->write(os, item); |
512 } |
512 } |
513 } |
513 } |
514 |
514 |
515 private: |
515 private: |
516 |
516 |
517 typedef std::vector<std::pair<std::string, _writer_bits:: |
517 typedef std::vector<std::pair<std::string, _writer_bits:: |
518 MapWriterBase<Node>*> > MapWriters; |
518 MapWriterBase<Node>*> > MapWriters; |
519 MapWriters writers; |
519 MapWriters writers; |
520 |
520 |
521 _writer_bits::MapWriterBase<Node>* idMap; |
521 _writer_bits::MapWriterBase<Node>* labelMap; |
522 bool forceIdMap; |
522 bool forceLabelMap; |
523 |
523 |
524 const Graph& graph; |
524 const Graph& graph; |
525 std::string id; |
525 std::string name; |
526 |
526 |
527 }; |
527 }; |
528 |
528 |
529 /// \ingroup io_group |
529 /// \ingroup io_group |
530 /// \brief SectionWriter for writing a graph's edgesets. |
530 /// \brief SectionWriter for writing a graph's edgesets. |
531 /// |
531 /// |
532 /// The lemon format can store multiple graph edgesets with several maps. |
532 /// The lemon format can store multiple graph edgesets with several maps. |
533 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the |
533 /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but |
534 /// \c edgeset_id may be empty. |
534 /// the \c edgeset_name may be empty. |
535 /// |
535 /// |
536 /// The first line of the section contains the names of the maps separated |
536 /// The first line of the section contains the names of the maps separated |
537 /// with white spaces. Each next lines describes a edge in the edgeset. The |
537 /// with white spaces. Each next lines describes a edge in the edgeset. The |
538 /// line contains the source and the target nodes' id and the mapped |
538 /// line contains the source and the target nodes' label and the mapped |
539 /// values for each map. |
539 /// values for each map. |
540 /// |
540 /// |
541 /// If the edgeset contains an \c "id" named map then it will be regarded |
541 /// If the edgeset contains an \c "label" named map then it will be regarded |
542 /// as id map. This map should contain only unique values and when the |
542 /// as label map. This map should contain only unique values and when the |
543 /// \c writeId() member will be called with an edge it will write it's id. |
543 /// \c writeLabel() member will be called with an edge it will write it's |
544 /// Otherwise if the \c _forceIdMap constructor parameter is true then |
544 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true |
545 /// the id map will be the id in the graph. |
545 /// then the label map will be the id in the graph. |
546 /// |
546 /// |
547 /// The edgeset writer needs a node id writer to identify which nodes |
547 /// The edgeset writer needs a node label writer to identify which nodes |
548 /// have to be connected. If a NodeSetWriter can write the nodes' id, |
548 /// have to be connected. If a NodeSetWriter can write the nodes' label, |
549 /// it will be able to use with this class. |
549 /// it will be able to use with this class. |
550 /// |
550 /// |
551 /// \relates LemonWriter |
551 /// \relates LemonWriter |
552 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
552 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
553 class EdgeSetWriter : public LemonWriter::SectionWriter { |
553 class EdgeSetWriter : public LemonWriter::SectionWriter { |
560 typedef typename Graph::Edge Edge; |
560 typedef typename Graph::Edge Edge; |
561 |
561 |
562 /// \brief Constructor. |
562 /// \brief Constructor. |
563 /// |
563 /// |
564 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and |
564 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and |
565 /// attach it into the given LemonWriter. It will write node ids by |
565 /// attach it into the given LemonWriter. It will write node labels by |
566 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true |
566 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true |
567 /// then the writer will write own id map if the user does not give |
567 /// then the writer will write own label map if the user does not give |
568 /// "id" named map. |
568 /// "label" named map. |
569 template <typename NodeIdWriter> |
569 template <typename NodeLabelWriter> |
570 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
570 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
571 const NodeIdWriter& _nodeIdWriter, |
571 const NodeLabelWriter& _nodeLabelWriter, |
572 const std::string& _id = std::string(), |
572 const std::string& _name = std::string(), |
573 bool _forceIdMap = true) |
573 bool _forceLabelMap = true) |
574 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
574 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
575 graph(_graph), id(_id) { |
575 graph(_graph), name(_name) { |
576 checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>(); |
576 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>(); |
577 nodeIdWriter.reset(new _writer_bits:: |
577 nodeLabelWriter.reset(new _writer_bits:: |
578 IdWriter<Node, NodeIdWriter>(_nodeIdWriter)); |
578 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter)); |
579 } |
579 } |
580 |
580 |
581 /// \brief Destructor. |
581 /// \brief Destructor. |
582 /// |
582 /// |
583 /// Destructor for EdgeSetWriter. |
583 /// Destructor for EdgeSetWriter. |
621 |
621 |
622 /// \brief The header of the section. |
622 /// \brief The header of the section. |
623 /// |
623 /// |
624 /// It gives back the header of the section. |
624 /// It gives back the header of the section. |
625 virtual std::string header() { |
625 virtual std::string header() { |
626 return "@edgeset " + id; |
626 return "@edgeset " + name; |
627 } |
627 } |
628 |
628 |
629 /// \brief Writer function of the section. |
629 /// \brief Writer function of the section. |
630 /// |
630 /// |
631 /// Write the content of the section. |
631 /// Write the content of the section. |
632 virtual void write(std::ostream& os) { |
632 virtual void write(std::ostream& os) { |
633 if (!nodeIdWriter->isIdWriter()) { |
633 if (!nodeLabelWriter->isLabelWriter()) { |
634 throw DataFormatError("Cannot find nodeset or ID map"); |
634 throw DataFormatError("Cannot find nodeset or label map"); |
635 } |
635 } |
636 for (int i = 0; i < (int)writers.size(); ++i) { |
636 for (int i = 0; i < (int)writers.size(); ++i) { |
637 if (writers[i].first == "id") { |
637 if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) { |
638 idMap = writers[i].second; |
638 labelMap = writers[i].second; |
639 forceIdMap = false; |
639 forceLabelMap = false; |
640 break; |
640 break; |
641 } |
641 } |
642 } |
642 } |
643 os << "\t\t"; |
643 os << "\t\t"; |
644 if (forceIdMap) { |
644 if (forceLabelMap) { |
645 os << "id\t"; |
645 os << "label\t"; |
646 } |
646 } |
647 for (int i = 0; i < (int)writers.size(); ++i) { |
647 for (int i = 0; i < (int)writers.size(); ++i) { |
648 os << writers[i].first << '\t'; |
648 os << writers[i].first << '\t'; |
649 } |
649 } |
650 os << std::endl; |
650 os << std::endl; |
651 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) { |
651 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) { |
652 nodeIdWriter->write(os, graph.source(it)); |
652 nodeLabelWriter->write(os, graph.source(it)); |
653 os << '\t'; |
653 os << '\t'; |
654 nodeIdWriter->write(os, graph.target(it)); |
654 nodeLabelWriter->write(os, graph.target(it)); |
655 os << '\t'; |
655 os << '\t'; |
656 if (forceIdMap) { |
656 if (forceLabelMap) { |
657 os << graph.id(it) << '\t'; |
657 os << graph.id(it) << '\t'; |
658 } |
658 } |
659 for (int i = 0; i < (int)writers.size(); ++i) { |
659 for (int i = 0; i < (int)writers.size(); ++i) { |
660 writers[i].second->write(os, it); |
660 writers[i].second->write(os, it); |
661 os << '\t'; |
661 os << '\t'; |
664 } |
664 } |
665 } |
665 } |
666 |
666 |
667 public: |
667 public: |
668 |
668 |
669 /// \brief Returns true if the edgeset can write the ids of the edges. |
669 /// \brief Returns true if the edgeset can write the labels of the edges. |
670 /// |
670 /// |
671 /// Returns true if the edgeset can write the ids of the edges. |
671 /// Returns true if the edgeset can write the labels of the edges. |
672 /// It is possible only if an "id" named map was written or the |
672 /// It is possible only if an "label" named map was written or the |
673 /// \c _forceIdMap constructor parameter was true. |
673 /// \c _forceLabelMap constructor parameter was true. |
674 bool isIdWriter() const { |
674 bool isLabelWriter() const { |
675 return forceIdMap || idMap != 0; |
675 return forceLabelMap || labelMap != 0; |
676 } |
676 } |
677 |
677 |
678 /// \brief Write the id of the given edge. |
678 /// \brief Write the label of the given edge. |
679 /// |
679 /// |
680 /// It writes the id of the given edge. If there was written an "id" |
680 /// It writes the label of the given edge. If there was written an "label" |
681 /// named map then it will write the map value belongs to the edge. |
681 /// named map then it will write the map value belongs to the edge. |
682 /// Otherwise if the \c forceId parameter was true it will write |
682 /// Otherwise if the \c forceLabel parameter was true it will write |
683 /// its id in the graph. |
683 /// its label in the graph. |
684 void writeId(std::ostream& os, const Edge& item) const { |
684 void writeLabel(std::ostream& os, const Edge& item) const { |
685 if (forceIdMap) { |
685 if (forceLabelMap) { |
686 os << graph.id(item); |
686 os << graph.id(item); |
687 } else { |
687 } else { |
688 idMap->write(os, item); |
688 labelMap->write(os, item); |
689 } |
689 } |
690 } |
690 } |
691 |
691 |
692 private: |
692 private: |
693 |
693 |
694 typedef std::vector<std::pair<std::string, _writer_bits:: |
694 typedef std::vector<std::pair<std::string, _writer_bits:: |
695 MapWriterBase<Edge>*> > MapWriters; |
695 MapWriterBase<Edge>*> > MapWriters; |
696 MapWriters writers; |
696 MapWriters writers; |
697 |
697 |
698 _writer_bits::MapWriterBase<Edge>* idMap; |
698 _writer_bits::MapWriterBase<Edge>* labelMap; |
699 bool forceIdMap; |
699 bool forceLabelMap; |
700 |
700 |
701 const Graph& graph; |
701 const Graph& graph; |
702 std::string id; |
702 std::string name; |
703 |
703 |
704 std::auto_ptr<_writer_bits::IdWriterBase<Node> > nodeIdWriter; |
704 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter; |
705 }; |
705 }; |
706 |
706 |
707 /// \ingroup io_group |
707 /// \ingroup io_group |
708 /// \brief SectionWriter for writing a undirected edgeset. |
708 /// \brief SectionWriter for writing a undirected edgeset. |
709 /// |
709 /// |
710 /// The lemon format can store multiple undirected edgesets with several |
710 /// The lemon format can store multiple undirected edgesets with several |
711 /// maps. The undirected edgeset section's header line is \c \@undiredgeset |
711 /// maps. The undirected edgeset section's header line is \c \@undiredgeset |
712 /// \c undiredgeset_id, but the \c undiredgeset_id may be empty. |
712 /// \c undiredgeset_name, but the \c undiredgeset_name may be empty. |
713 /// |
713 /// |
714 /// The first line of the section contains the names of the maps separated |
714 /// The first line of the section contains the names of the maps separated |
715 /// with white spaces. Each next lines describes an undirected edge in the |
715 /// with white spaces. Each next lines describes an undirected edge in the |
716 /// edgeset. The line contains the two connected nodes' id and the mapped |
716 /// edgeset. The line contains the two connected nodes' label and the mapped |
717 /// values for each undirected map. |
717 /// values for each undirected map. |
718 /// |
718 /// |
719 /// The section can handle the directed as a syntactical sugar. Two |
719 /// The section can handle the directed as a syntactical sugar. Two |
720 /// undirected edge map describes one directed edge map. This two maps |
720 /// undirected edge map describes one directed edge map. This two maps |
721 /// are the forward map and the backward map and the names of this map |
721 /// are the forward map and the backward map and the names of this map |
722 /// is near the same just with a prefix \c '+' or \c '-' character |
722 /// is near the same just with a prefix \c '+' or \c '-' character |
723 /// difference. |
723 /// difference. |
724 /// |
724 /// |
725 /// If the edgeset contains an \c "id" named map then it will be regarded |
725 /// If the edgeset contains an \c "label" named map then it will be regarded |
726 /// as id map. This map should contain only unique values and when the |
726 /// as label map. This map should contain only unique values and when the |
727 /// \c writeId() member will be called with an undirected edge it will |
727 /// \c writeLabel() member will be called with an undirected edge it will |
728 /// write it's id. Otherwise if the \c _forceIdMap constructor parameter |
728 /// write it's label. Otherwise if the \c _forceLabelMap constructor |
729 /// is true then the id map will be the id in the graph. |
729 /// parameter is true then the label map will be the id in the graph. |
730 /// |
730 /// |
731 /// The undirected edgeset writer needs a node id writer to identify |
731 /// The undirected edgeset writer needs a node label writer to identify |
732 /// which nodes have to be connected. If a NodeSetWriter can write the |
732 /// which nodes have to be connected. If a NodeSetWriter can write the |
733 /// nodes' id, it will be able to use with this class. |
733 /// nodes' label, it will be able to use with this class. |
734 /// |
734 /// |
735 /// \relates LemonWriter |
735 /// \relates LemonWriter |
736 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
736 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
737 class UndirEdgeSetWriter : public LemonWriter::SectionWriter { |
737 class UndirEdgeSetWriter : public LemonWriter::SectionWriter { |
738 typedef LemonWriter::SectionWriter Parent; |
738 typedef LemonWriter::SectionWriter Parent; |
745 typedef typename Graph::UndirEdge UndirEdge; |
745 typedef typename Graph::UndirEdge UndirEdge; |
746 |
746 |
747 /// \brief Constructor. |
747 /// \brief Constructor. |
748 /// |
748 /// |
749 /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter |
749 /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter |
750 /// and attach it into the given LemonWriter. It will write node ids by |
750 /// and attach it into the given LemonWriter. It will write node labels by |
751 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true |
751 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true |
752 /// then the writer will write own id map if the user does not give |
752 /// then the writer will write own label map if the user does not give |
753 /// "id" named map. |
753 /// "label" named map. |
754 template <typename NodeIdWriter> |
754 template <typename NodeLabelWriter> |
755 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
755 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
756 const NodeIdWriter& _nodeIdWriter, |
756 const NodeLabelWriter& _nodeLabelWriter, |
757 const std::string& _id = std::string(), |
757 const std::string& _name = std::string(), |
758 bool _forceIdMap = true) |
758 bool _forceLabelMap = true) |
759 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
759 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap), |
760 graph(_graph), id(_id) { |
760 graph(_graph), name(_name) { |
761 checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>(); |
761 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>(); |
762 nodeIdWriter.reset(new _writer_bits:: |
762 nodeLabelWriter.reset(new _writer_bits:: |
763 IdWriter<Node, NodeIdWriter>(_nodeIdWriter)); |
763 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter)); |
764 } |
764 } |
765 |
765 |
766 /// \brief Destructor. |
766 /// \brief Destructor. |
767 /// |
767 /// |
768 /// Destructor for UndirEdgeSetWriter. |
768 /// Destructor for UndirEdgeSetWriter. |
830 |
830 |
831 /// \brief The header of the section. |
831 /// \brief The header of the section. |
832 /// |
832 /// |
833 /// It gives back the header of the section. |
833 /// It gives back the header of the section. |
834 virtual std::string header() { |
834 virtual std::string header() { |
835 return "@undiredgeset " + id; |
835 return "@undiredgeset " + name; |
836 } |
836 } |
837 |
837 |
838 /// \brief Writer function of the section. |
838 /// \brief Writer function of the section. |
839 /// |
839 /// |
840 /// Write the content of the section. |
840 /// Write the content of the section. |
841 virtual void write(std::ostream& os) { |
841 virtual void write(std::ostream& os) { |
842 if (!nodeIdWriter->isIdWriter()) { |
842 if (!nodeLabelWriter->isLabelWriter()) { |
843 throw DataFormatError("Cannot find nodeset or ID map"); |
843 throw DataFormatError("Cannot find nodeset or label map"); |
844 } |
844 } |
845 for (int i = 0; i < (int)writers.size(); ++i) { |
845 for (int i = 0; i < (int)writers.size(); ++i) { |
846 if (writers[i].first == "id") { |
846 if (writers[i].first == "label") { |
847 idMap = writers[i].second; |
847 labelMap = writers[i].second; |
848 forceIdMap = false; |
848 forceLabelMap = false; |
849 break; |
849 break; |
850 } |
850 } |
851 } |
851 } |
852 os << "\t\t"; |
852 os << "\t\t"; |
853 if (forceIdMap) { |
853 if (forceLabelMap) { |
854 os << "id\t"; |
854 os << "label\t"; |
855 } |
855 } |
856 for (int i = 0; i < (int)writers.size(); ++i) { |
856 for (int i = 0; i < (int)writers.size(); ++i) { |
857 os << writers[i].first << '\t'; |
857 os << writers[i].first << '\t'; |
858 } |
858 } |
859 os << std::endl; |
859 os << std::endl; |
860 for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) { |
860 for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) { |
861 nodeIdWriter->write(os, graph.source(it)); |
861 nodeLabelWriter->write(os, graph.source(it)); |
862 os << '\t'; |
862 os << '\t'; |
863 nodeIdWriter->write(os, graph.target(it)); |
863 nodeLabelWriter->write(os, graph.target(it)); |
864 os << '\t'; |
864 os << '\t'; |
865 if (forceIdMap) { |
865 if (forceLabelMap) { |
866 os << graph.id(it) << '\t'; |
866 os << graph.id(it) << '\t'; |
867 } |
867 } |
868 for (int i = 0; i < (int)writers.size(); ++i) { |
868 for (int i = 0; i < (int)writers.size(); ++i) { |
869 writers[i].second->write(os, it); |
869 writers[i].second->write(os, it); |
870 os << '\t'; |
870 os << '\t'; |
873 } |
873 } |
874 } |
874 } |
875 |
875 |
876 public: |
876 public: |
877 |
877 |
878 /// \brief Returns true if the undirected edgeset can write the ids of |
878 /// \brief Returns true if the undirected edgeset can write the labels of |
879 /// the edges. |
879 /// the edges. |
880 /// |
880 /// |
881 /// Returns true if the undirected edgeset can write the ids of the |
881 /// Returns true if the undirected edgeset can write the labels of the |
882 /// undirected edges. It is possible only if an "id" named map was |
882 /// undirected edges. It is possible only if an "label" named map was |
883 /// written or the \c _forceIdMap constructor parameter was true. |
883 /// written or the \c _forceLabelMap constructor parameter was true. |
884 bool isIdWriter() const { |
884 bool isLabelWriter() const { |
885 return forceIdMap || idMap != 0; |
885 return forceLabelMap || labelMap != 0; |
886 } |
886 } |
887 |
887 |
888 /// \brief Write the id of the given undirected edge. |
888 /// \brief Write the label of the given undirected edge. |
889 /// |
889 /// |
890 /// It writes the id of the given undirected edge. If there was written |
890 /// It writes the label of the given undirected edge. If there was written |
891 /// an "id" named map then it will write the map value belongs to the |
891 /// an "label" named map then it will write the map value belongs to the |
892 /// undirected edge. Otherwise if the \c forceId parameter was true it |
892 /// undirected edge. Otherwise if the \c forceLabel parameter was true it |
893 /// will write its id in the graph. |
893 /// will write its id in the graph. |
894 void writeId(std::ostream& os, const UndirEdge& item) const { |
894 void writeLabel(std::ostream& os, const UndirEdge& item) const { |
895 if (forceIdMap) { |
895 if (forceLabelMap) { |
896 os << graph.id(item); |
896 os << graph.id(item); |
897 } else { |
897 } else { |
898 idMap->write(os, item); |
898 labelMap->write(os, item); |
899 } |
899 } |
900 } |
900 } |
901 |
901 |
902 /// \brief Write the id of the given edge. |
902 /// \brief Write the label of the given edge. |
903 /// |
903 /// |
904 /// It writes the id of the given edge. If there was written |
904 /// It writes the label of the given edge. If there was written |
905 /// an "id" named map then it will write the map value belongs to the |
905 /// an "label" named map then it will write the map value belongs to the |
906 /// edge. Otherwise if the \c forceId parameter was true it |
906 /// edge. Otherwise if the \c forceLabel parameter was true it |
907 /// will write its id in the graph. If the edge is forward map |
907 /// will write its id in the graph. If the edge is forward map |
908 /// then its prefix character is \c '+' elsewhere \c '-'. |
908 /// then its prefix character is \c '+' elsewhere \c '-'. |
909 void writeId(std::ostream& os, const Edge& item) const { |
909 void writeLabel(std::ostream& os, const Edge& item) const { |
910 if (graph.direction(item)) { |
910 if (graph.direction(item)) { |
911 os << "+ "; |
911 os << "+ "; |
912 } else { |
912 } else { |
913 os << "- "; |
913 os << "- "; |
914 } |
914 } |
915 if (forceIdMap) { |
915 if (forceLabelMap) { |
916 os << graph.id(item); |
916 os << graph.id(item); |
917 } else { |
917 } else { |
918 idMap->write(os, item); |
918 labelMap->write(os, item); |
919 } |
919 } |
920 } |
920 } |
921 |
921 |
922 private: |
922 private: |
923 |
923 |
924 typedef std::vector<std::pair<std::string, _writer_bits:: |
924 typedef std::vector<std::pair<std::string, _writer_bits:: |
925 MapWriterBase<UndirEdge>*> > MapWriters; |
925 MapWriterBase<UndirEdge>*> > MapWriters; |
926 MapWriters writers; |
926 MapWriters writers; |
927 |
927 |
928 _writer_bits::MapWriterBase<UndirEdge>* idMap; |
928 _writer_bits::MapWriterBase<UndirEdge>* labelMap; |
929 bool forceIdMap; |
929 bool forceLabelMap; |
930 |
930 |
931 const Graph& graph; |
931 const Graph& graph; |
932 std::string id; |
932 std::string name; |
933 |
933 |
934 std::auto_ptr<_writer_bits::IdWriterBase<Node> > nodeIdWriter; |
934 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter; |
935 }; |
935 }; |
936 |
936 |
937 /// \ingroup io_group |
937 /// \ingroup io_group |
938 /// \brief SectionWriter for writing labeled nodes. |
938 /// \brief SectionWriter for writing named nodes. |
939 /// |
939 /// |
940 /// The nodes section's header line is \c \@nodes \c nodes_id, but the |
940 /// The nodes section's header line is \c \@nodes \c nodes_name, but the |
941 /// \c nodes_id may be empty. |
941 /// \c nodes_name may be empty. |
942 /// |
942 /// |
943 /// Each line in the section contains the label of the node and |
943 /// Each line in the section contains the name of the node and |
944 /// then the node id. |
944 /// then the node label. |
945 /// |
945 /// |
946 /// \relates LemonWriter |
946 /// \relates LemonWriter |
947 template <typename _Graph> |
947 template <typename _Graph> |
948 class NodeWriter : public LemonWriter::SectionWriter { |
948 class NodeWriter : public LemonWriter::SectionWriter { |
949 typedef LemonWriter::SectionWriter Parent; |
949 typedef LemonWriter::SectionWriter Parent; |
952 public: |
952 public: |
953 |
953 |
954 /// \brief Constructor. |
954 /// \brief Constructor. |
955 /// |
955 /// |
956 /// Constructor for NodeWriter. It creates the NodeWriter and |
956 /// Constructor for NodeWriter. It creates the NodeWriter and |
957 /// attach it into the given LemonWriter. The given \c _IdWriter |
957 /// attach it into the given LemonWriter. The given \c _LabelWriter |
958 /// will write the nodes' id what can be a nodeset writer. |
958 /// will write the nodes' label what can be a nodeset writer. |
959 template <typename _IdWriter> |
959 template <typename _LabelWriter> |
960 NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
960 NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, |
961 const std::string& _id = std::string()) |
961 const std::string& _name = std::string()) |
962 : Parent(_writer), id(_id) { |
962 : Parent(_writer), name(_name) { |
963 checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>(); |
963 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>(); |
964 idWriter.reset(new _writer_bits::IdWriter<Node, _IdWriter>(_idWriter)); |
964 labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter> |
|
965 (_labelWriter)); |
965 } |
966 } |
966 |
967 |
967 |
968 |
968 /// \brief Destructor. |
969 /// \brief Destructor. |
969 /// |
970 /// |
983 writers.push_back(make_pair(name, &item)); |
984 writers.push_back(make_pair(name, &item)); |
984 } |
985 } |
985 |
986 |
986 protected: |
987 protected: |
987 |
988 |
988 /// \brief Header checking function. |
989 /// \brief The header of the section. |
989 /// |
990 /// |
990 /// It gives back true when the header line start with \c \@nodes, |
991 /// It gives back the header of the section. |
991 /// and the header line's id and the writer's id are the same. |
|
992 virtual std::string header() { |
992 virtual std::string header() { |
993 return "@nodes " + id; |
993 return "@nodes " + name; |
994 } |
994 } |
995 |
995 |
996 /// \brief Writer function of the section. |
996 /// \brief Writer function of the section. |
997 /// |
997 /// |
998 /// Write the content of the section. |
998 /// Write the content of the section. |
999 virtual void write(std::ostream& os) { |
999 virtual void write(std::ostream& os) { |
1000 if (!idWriter->isIdWriter()) { |
1000 if (!labelWriter->isLabelWriter()) { |
1001 throw DataFormatError("Cannot find nodeset or ID map"); |
1001 throw DataFormatError("Cannot find nodeset or label map"); |
1002 } |
1002 } |
1003 for (int i = 0; i < (int)writers.size(); ++i) { |
1003 for (int i = 0; i < (int)writers.size(); ++i) { |
1004 os << writers[i].first << ' '; |
1004 os << writers[i].first << ' '; |
1005 idWriter->write(os, *(writers[i].second)); |
1005 labelWriter->write(os, *(writers[i].second)); |
1006 os << std::endl; |
1006 os << std::endl; |
1007 } |
1007 } |
1008 } |
1008 } |
1009 |
1009 |
1010 private: |
1010 private: |
1011 |
1011 |
1012 std::string id; |
1012 std::string name; |
1013 |
1013 |
1014 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters; |
1014 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters; |
1015 NodeWriters writers; |
1015 NodeWriters writers; |
1016 std::auto_ptr<_writer_bits::IdWriterBase<Node> > idWriter; |
1016 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter; |
1017 }; |
1017 }; |
1018 |
1018 |
1019 /// \ingroup io_group |
1019 /// \ingroup io_group |
1020 /// \brief SectionWriter for writing labeled edges. |
1020 /// \brief SectionWriter for writing named edges. |
1021 /// |
1021 /// |
1022 /// The edges section's header line is \c \@edges \c edges_id, but the |
1022 /// The edges section's header line is \c \@edges \c edges_name, but the |
1023 /// \c edges_id may be empty. |
1023 /// \c edges_name may be empty. |
1024 /// |
1024 /// |
1025 /// Each line in the section contains the label of the edge and |
1025 /// Each line in the section contains the name of the edge and |
1026 /// then the edge id. |
1026 /// then the edge label. |
1027 /// |
1027 /// |
1028 /// \relates LemonWriter |
1028 /// \relates LemonWriter |
1029 template <typename _Graph> |
1029 template <typename _Graph> |
1030 class EdgeWriter : public LemonWriter::SectionWriter { |
1030 class EdgeWriter : public LemonWriter::SectionWriter { |
1031 typedef LemonWriter::SectionWriter Parent; |
1031 typedef LemonWriter::SectionWriter Parent; |
1034 public: |
1034 public: |
1035 |
1035 |
1036 /// \brief Constructor. |
1036 /// \brief Constructor. |
1037 /// |
1037 /// |
1038 /// Constructor for EdgeWriter. It creates the EdgeWriter and |
1038 /// Constructor for EdgeWriter. It creates the EdgeWriter and |
1039 /// attach it into the given LemonWriter. The given \c _IdWriter |
1039 /// attach it into the given LemonWriter. The given \c _LabelWriter |
1040 /// will write the edges' id what can be a edgeset writer. |
1040 /// will write the edges' label what can be a edgeset writer. |
1041 template <typename _IdWriter> |
1041 template <typename _LabelWriter> |
1042 EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
1042 EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, |
1043 const std::string& _id = std::string()) |
1043 const std::string& _name = std::string()) |
1044 : Parent(_writer), id(_id) { |
1044 : Parent(_writer), name(_name) { |
1045 checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>(); |
1045 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>(); |
1046 idWriter.reset(new _writer_bits::IdWriter<Edge, _IdWriter>(_idWriter)); |
1046 labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter)); |
1047 } |
1047 } |
1048 |
1048 |
1049 /// \brief Destructor. |
1049 /// \brief Destructor. |
1050 /// |
1050 /// |
1051 /// Destructor for EdgeWriter. |
1051 /// Destructor for EdgeWriter. |
1063 writers.push_back(make_pair(name, &item)); |
1063 writers.push_back(make_pair(name, &item)); |
1064 } |
1064 } |
1065 |
1065 |
1066 protected: |
1066 protected: |
1067 |
1067 |
1068 /// \brief Header checking function. |
1068 /// \brief The header of the section. |
1069 /// |
1069 /// |
1070 /// It gives back true when the header line start with \c \@edges, |
1070 /// It gives back the header of the section. |
1071 /// and the header line's id and the writer's id are the same. |
|
1072 virtual std::string header() { |
1071 virtual std::string header() { |
1073 return "@edges " + id; |
1072 return "@edges " + name; |
1074 } |
1073 } |
1075 |
1074 |
1076 /// \brief Writer function of the section. |
1075 /// \brief Writer function of the section. |
1077 /// |
1076 /// |
1078 /// Write the content of the section. |
1077 /// Write the content of the section. |
1079 virtual void write(std::ostream& os) { |
1078 virtual void write(std::ostream& os) { |
1080 if (!idWriter->isIdWriter()) { |
1079 if (!labelWriter->isLabelWriter()) { |
1081 throw DataFormatError("Cannot find edgeset or ID map"); |
1080 throw DataFormatError("Cannot find edgeset or label map"); |
1082 } |
1081 } |
1083 for (int i = 0; i < (int)writers.size(); ++i) { |
1082 for (int i = 0; i < (int)writers.size(); ++i) { |
1084 os << writers[i].first << ' '; |
1083 os << writers[i].first << ' '; |
1085 idWriter->write(os, *(writers[i].second)); |
1084 labelWriter->write(os, *(writers[i].second)); |
1086 os << std::endl; |
1085 os << std::endl; |
1087 } |
1086 } |
1088 } |
1087 } |
1089 |
1088 |
1090 private: |
1089 private: |
1091 |
1090 |
1092 std::string id; |
1091 std::string name; |
1093 |
1092 |
1094 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters; |
1093 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters; |
1095 EdgeWriters writers; |
1094 EdgeWriters writers; |
1096 |
1095 |
1097 std::auto_ptr<_writer_bits::IdWriterBase<Edge> > idWriter; |
1096 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter; |
1098 }; |
1097 }; |
1099 |
1098 |
1100 /// \ingroup io_group |
1099 /// \ingroup io_group |
1101 /// \brief SectionWriter for writing labeled undirected edges. |
1100 /// \brief SectionWriter for writing named undirected edges. |
1102 /// |
1101 /// |
1103 /// The undirected edges section's header line is \c \@undiredges |
1102 /// The undirected edges section's header line is \c \@undiredges |
1104 /// \c undiredges_id, but the \c undiredges_id may be empty. |
1103 /// \c undiredges_name, but the \c undiredges_name may be empty. |
1105 /// |
1104 /// |
1106 /// Each line in the section contains the label of the undirected edge and |
1105 /// Each line in the section contains the name of the undirected edge and |
1107 /// then the undirected edge id. |
1106 /// then the undirected edge label. |
1108 /// |
1107 /// |
1109 /// \relates LemonWriter |
1108 /// \relates LemonWriter |
1110 template <typename _Graph> |
1109 template <typename _Graph> |
1111 class UndirEdgeWriter : public LemonWriter::SectionWriter { |
1110 class UndirEdgeWriter : public LemonWriter::SectionWriter { |
1112 typedef LemonWriter::SectionWriter Parent; |
1111 typedef LemonWriter::SectionWriter Parent; |
1117 public: |
1116 public: |
1118 |
1117 |
1119 /// \brief Constructor. |
1118 /// \brief Constructor. |
1120 /// |
1119 /// |
1121 /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and |
1120 /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and |
1122 /// attach it into the given LemonWriter. The given \c _IdWriter |
1121 /// attach it into the given LemonWriter. The given \c _LabelWriter |
1123 /// will write the undirected edges' id what can be an undirected |
1122 /// will write the undirected edges' label what can be an undirected |
1124 /// edgeset writer. |
1123 /// edgeset writer. |
1125 template <typename _IdWriter> |
1124 template <typename _LabelWriter> |
1126 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
1125 UndirEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter, |
1127 const std::string& _id = std::string()) |
1126 const std::string& _name = std::string()) |
1128 : Parent(_writer), id(_id) { |
1127 : Parent(_writer), name(_name) { |
1129 checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>(); |
1128 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>(); |
1130 checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>(); |
1129 checkConcept<_writer_bits::ItemLabelWriter<UndirEdge>, _LabelWriter>(); |
1131 undirEdgeIdWriter.reset(new _writer_bits:: |
1130 undirEdgeLabelWriter.reset(new _writer_bits:: |
1132 IdWriter<UndirEdge, _IdWriter>(_idWriter)); |
1131 LabelWriter<UndirEdge, _LabelWriter>(_labelWriter)); |
1133 edgeIdWriter.reset(new _writer_bits:: |
1132 edgeLabelWriter.reset(new _writer_bits:: |
1134 IdWriter<Edge, _IdWriter>(_idWriter)); |
1133 LabelWriter<Edge, _LabelWriter>(_labelWriter)); |
1135 } |
1134 } |
1136 |
1135 |
1137 /// \brief Destructor. |
1136 /// \brief Destructor. |
1138 /// |
1137 /// |
1139 /// Destructor for UndirEdgeWriter. |
1138 /// Destructor for UndirEdgeWriter. |
1158 undirEdgeWriters.push_back(make_pair(name, &item)); |
1157 undirEdgeWriters.push_back(make_pair(name, &item)); |
1159 } |
1158 } |
1160 |
1159 |
1161 protected: |
1160 protected: |
1162 |
1161 |
1163 /// \brief Header checking function. |
1162 /// \brief The header of the section. |
1164 /// |
1163 /// |
1165 /// It gives back true when the header line start with \c \@undiredges, |
1164 /// It gives back the header of the section. |
1166 /// and the header line's id and the writer's id are the same. |
|
1167 virtual std::string header() { |
1165 virtual std::string header() { |
1168 return "@undiredges " + id; |
1166 return "@undiredges " + name; |
1169 } |
1167 } |
1170 |
1168 |
1171 /// \brief Writer function of the section. |
1169 /// \brief Writer function of the section. |
1172 /// |
1170 /// |
1173 /// Write the content of the section. |
1171 /// Write the content of the section. |
1174 virtual void write(std::ostream& os) { |
1172 virtual void write(std::ostream& os) { |
1175 if (!edgeIdWriter->isIdWriter()) { |
1173 if (!edgeLabelWriter->isLabelWriter()) { |
1176 throw DataFormatError("Cannot find undirected edgeset or ID map"); |
1174 throw DataFormatError("Cannot find undirected edgeset or label map"); |
1177 } |
1175 } |
1178 if (!undirEdgeIdWriter->isIdWriter()) { |
1176 if (!undirEdgeLabelWriter->isLabelWriter()) { |
1179 throw DataFormatError("Cannot find undirected edgeset or ID map"); |
1177 throw DataFormatError("Cannot find undirected edgeset or label map"); |
1180 } |
1178 } |
1181 for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) { |
1179 for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) { |
1182 os << undirEdgeWriters[i].first << ' '; |
1180 os << undirEdgeWriters[i].first << ' '; |
1183 undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second)); |
1181 undirEdgeLabelWriter->write(os, *(undirEdgeWriters[i].second)); |
1184 os << std::endl; |
1182 os << std::endl; |
1185 } |
1183 } |
1186 for (int i = 0; i < (int)edgeWriters.size(); ++i) { |
1184 for (int i = 0; i < (int)edgeWriters.size(); ++i) { |
1187 os << edgeWriters[i].first << ' '; |
1185 os << edgeWriters[i].first << ' '; |
1188 edgeIdWriter->write(os, *(edgeWriters[i].second)); |
1186 edgeLabelWriter->write(os, *(edgeWriters[i].second)); |
1189 os << std::endl; |
1187 os << std::endl; |
1190 } |
1188 } |
1191 } |
1189 } |
1192 |
1190 |
1193 private: |
1191 private: |
1194 |
1192 |
1195 std::string id; |
1193 std::string name; |
1196 |
1194 |
1197 typedef std::vector<std::pair<std::string, |
1195 typedef std::vector<std::pair<std::string, |
1198 const UndirEdge*> > UndirEdgeWriters; |
1196 const UndirEdge*> > UndirEdgeWriters; |
1199 UndirEdgeWriters undirEdgeWriters; |
1197 UndirEdgeWriters undirEdgeWriters; |
1200 std::auto_ptr<_writer_bits::IdWriterBase<UndirEdge> > undirEdgeIdWriter; |
1198 std::auto_ptr<_writer_bits::LabelWriterBase<UndirEdge> > undirEdgeLabelWriter; |
1201 |
1199 |
1202 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters; |
1200 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters; |
1203 EdgeWriters edgeWriters; |
1201 EdgeWriters edgeWriters; |
1204 std::auto_ptr<_writer_bits::IdWriterBase<Edge> > edgeIdWriter; |
1202 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter; |
1205 |
1203 |
1206 }; |
1204 }; |
1207 |
1205 |
1208 /// \ingroup io_group |
1206 /// \ingroup io_group |
1209 /// \brief SectionWriter for attributes. |
1207 /// \brief SectionWriter for attributes. |
1210 /// |
1208 /// |
1211 /// The lemon format can store multiple attribute set. Each set has |
1209 /// The lemon format can store multiple attribute set. Each set has |
1212 /// the header line \c \@attributes \c attributeset_id, but the |
1210 /// the header line \c \@attributes \c attributes_name, but the |
1213 /// attributeset_id may be empty. |
1211 /// attributeset_name may be empty. |
1214 /// |
1212 /// |
1215 /// The attributeset section contains several lines. Each of them starts |
1213 /// The attributeset section contains several lines. Each of them starts |
1216 /// with the name of attribute and then the value. |
1214 /// with the name of attribute and then the value. |
1217 /// |
1215 /// |
1218 /// \relates LemonWriter |
1216 /// \relates LemonWriter |