304 |
305 |
305 /// \brief Add a new node map writer command for the writer. |
306 /// \brief Add a new node map writer command for the writer. |
306 /// |
307 /// |
307 /// Add a new node map writer command for the writer. |
308 /// Add a new node map writer command for the writer. |
308 template <typename Map> |
309 template <typename Map> |
309 NodeSetWriter& writeMap(std::string name, const Map& map) { |
310 NodeSetWriter& writeNodeMap(std::string name, const Map& map) { |
310 return writeMap<typename Traits:: |
311 return writeNodeMap<typename Traits:: |
311 template Writer<typename Map::Value>, Map>(name, map); |
312 template Writer<typename Map::Value>, Map>(name, map); |
312 } |
313 } |
313 |
314 |
314 /// \brief Add a new node map writer command for the writer. |
315 /// \brief Add a new node map writer command for the writer. |
315 /// |
316 /// |
316 /// Add a new node map writer command for the writer. |
317 /// Add a new node map writer command for the writer. |
317 template <typename Writer, typename Map> |
318 template <typename Writer, typename Map> |
318 NodeSetWriter& writeMap(std::string name, const Map& map, |
319 NodeSetWriter& writeNodeMap(std::string name, const Map& map, |
319 const Writer& writer = Writer()) { |
320 const Writer& writer = Writer()) { |
320 writers.push_back( |
321 writers.push_back( |
321 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); |
322 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); |
322 return *this; |
323 return *this; |
323 } |
324 } |
324 |
325 |
392 MapWriters writers; |
393 MapWriters writers; |
393 |
394 |
394 WriterBase<Item>* idMap; |
395 WriterBase<Item>* idMap; |
395 bool forceIdMap; |
396 bool forceIdMap; |
396 |
397 |
397 const Graph& graph; |
398 typename SmartConstReference<Graph>::Type graph; |
398 std::string id; |
399 std::string id; |
399 |
400 |
400 }; |
401 }; |
401 |
402 |
402 /// \ingroup io_group |
403 /// \ingroup io_group |
403 /// \brief SectionWriter for writing a graph's edgeset. |
404 /// \brief SectionWriter for writing a graph's edgesets. |
404 /// |
405 /// |
405 /// The lemon format can store multiple graph edgesets with several maps. |
406 /// The lemon format can store multiple graph edgesets with several maps. |
406 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the |
407 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the |
407 /// \c edgeset_id may be empty. |
408 /// \c edgeset_id may be empty. |
408 /// |
409 /// |
409 /// The first line of the section contains the names of the maps separated |
410 /// The first line of the section contains the names of the maps separated |
410 /// with white spaces. Each next lines describes a edge in the edgeset. The |
411 /// with white spaces. Each next lines describes a edge in the edgeset. The |
411 /// line contains the source and the target nodes' id and the mapped |
412 /// line contains the source and the target nodes' id and the mapped |
412 /// values for each map. |
413 /// values for each map. |
413 /// |
414 /// |
414 /// If the edgeset contains an \c "id" named map then it will be regarded |
415 /// If the edgeset contains an \c "id" named map then it will be regarded |
415 /// as id map. This map should contain only unique values and when the |
416 /// as id map. This map should contain only unique values and when the |
416 /// \c writeId() member will be called with a edge it will write it's id. |
417 /// \c writeId() member will be called with an edge it will write it's id. |
417 /// Otherwise if the \c _forceIdMap constructor parameter is true then |
418 /// Otherwise if the \c _forceIdMap constructor parameter is true then |
418 /// the id map will be the id in the graph. |
419 /// the id map will be the id in the graph. |
419 /// |
420 /// |
420 /// The edgeset writer needs a node id writer to identify which nodes |
421 /// The edgeset writer needs a node id writer to identify which nodes |
421 /// have to be connected. If a NodeSetWriter can write the nodes' id, |
422 /// have to be connected. If a NodeSetWriter can write the nodes' id, |
462 EdgeSetWriter(const EdgeSetWriter&); |
463 EdgeSetWriter(const EdgeSetWriter&); |
463 void operator=(const EdgeSetWriter&); |
464 void operator=(const EdgeSetWriter&); |
464 |
465 |
465 public: |
466 public: |
466 |
467 |
467 /// \brief Add a new node map writer command for the writer. |
468 /// \brief Add a new edge map writer command for the writer. |
468 /// |
469 /// |
469 /// Add a new node map writer command for the writer. |
470 /// Add a new edge map writer command for the writer. |
470 template <typename Map> |
471 template <typename Map> |
471 EdgeSetWriter& writeMap(std::string name, const Map& map) { |
472 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { |
472 return writeMap<typename Traits:: |
473 return writeEdgeMap<typename Traits:: |
473 template Writer<typename Map::Value>, Map>(name, map); |
474 template Writer<typename Map::Value>, Map>(name, map); |
474 } |
475 } |
475 |
476 |
476 /// \brief Add a new node map writer command for the writer. |
477 /// \brief Add a new edge map writer command for the writer. |
477 /// |
478 /// |
478 /// Add a new node map writer command for the writer. |
479 /// Add a new edge map writer command for the writer. |
479 template <typename Writer, typename Map> |
480 template <typename Writer, typename Map> |
480 EdgeSetWriter& writeMap(std::string name, const Map& map, |
481 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, |
481 const Writer& writer = Writer()) { |
482 const Writer& writer = Writer()) { |
482 writers.push_back( |
483 writers.push_back( |
483 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); |
484 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); |
484 return *this; |
485 return *this; |
485 } |
486 } |
486 |
487 |
559 MapWriters writers; |
560 MapWriters writers; |
560 |
561 |
561 WriterBase<Item>* idMap; |
562 WriterBase<Item>* idMap; |
562 bool forceIdMap; |
563 bool forceIdMap; |
563 |
564 |
564 const Graph& graph; |
565 typename SmartConstReference<Graph>::Type graph; |
|
566 std::string id; |
|
567 |
|
568 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter; |
|
569 }; |
|
570 |
|
571 /// \ingroup io_group |
|
572 /// \brief SectionWriter for writing a undirected edgeset. |
|
573 /// |
|
574 /// The lemon format can store multiple undirected edgesets with several |
|
575 /// maps. The undirected edgeset section's header line is \c \@undiredgeset |
|
576 /// \c undiredgeset_id, but the \c undiredgeset_id may be empty. |
|
577 /// |
|
578 /// The first line of the section contains the names of the maps separated |
|
579 /// with white spaces. Each next lines describes an undirected edge in the |
|
580 /// edgeset. The line contains the two connected nodes' id and the mapped |
|
581 /// values for each undirected map. |
|
582 /// |
|
583 /// The section can handle the directed as a syntactical sugar. Two |
|
584 /// undirected edge map describes one directed edge map. This two maps |
|
585 /// are the forward map and the backward map and the names of this map |
|
586 /// is near the same just with a prefix \c '+' or \c '-' character |
|
587 /// difference. |
|
588 /// |
|
589 /// If the edgeset contains an \c "id" named map then it will be regarded |
|
590 /// as id map. This map should contain only unique values and when the |
|
591 /// \c writeId() member will be called with an undirected edge it will |
|
592 /// write it's id. Otherwise if the \c _forceIdMap constructor parameter |
|
593 /// is true then the id map will be the id in the graph. |
|
594 /// |
|
595 /// The undirected edgeset writer needs a node id writer to identify |
|
596 /// which nodes have to be connected. If a NodeSetWriter can write the |
|
597 /// nodes' id, it will be able to use with this class. |
|
598 /// |
|
599 /// \relates LemonWriter |
|
600 template <typename _Graph, typename _Traits = DefaultWriterTraits> |
|
601 class UndirEdgeSetWriter : public CommonSectionWriterBase { |
|
602 typedef CommonSectionWriterBase Parent; |
|
603 public: |
|
604 |
|
605 typedef _Graph Graph; |
|
606 typedef _Traits Traits; |
|
607 typedef typename Graph::UndirEdge Item; |
|
608 |
|
609 /// \brief Constructor. |
|
610 /// |
|
611 /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter |
|
612 /// and attach it into the given LemonWriter. It will write node ids by |
|
613 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true |
|
614 /// then the writer will write own id map if the user does not give |
|
615 /// "id" named map. |
|
616 template <typename NodeIdWriter> |
|
617 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
|
618 const NodeIdWriter& _nodeIdWriter, |
|
619 const std::string& _id = std::string(), |
|
620 bool _forceIdMap = true) |
|
621 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
|
622 graph(_graph), id(_id), |
|
623 nodeIdWriter(new IdWriter<typename Graph::Node, NodeIdWriter> |
|
624 (_nodeIdWriter)) {} |
|
625 |
|
626 /// \brief Destructor. |
|
627 /// |
|
628 /// Destructor for UndirEdgeSetWriter. |
|
629 virtual ~UndirEdgeSetWriter() { |
|
630 typename MapWriters::iterator it; |
|
631 for (it = writers.begin(); it != writers.end(); ++it) { |
|
632 delete it->second; |
|
633 } |
|
634 } |
|
635 |
|
636 private: |
|
637 UndirEdgeSetWriter(const UndirEdgeSetWriter&); |
|
638 void operator=(const UndirEdgeSetWriter&); |
|
639 |
|
640 public: |
|
641 |
|
642 /// \brief Add a new undirected edge map writer command for the writer. |
|
643 /// |
|
644 /// Add a new undirected map writer command for the writer. |
|
645 template <typename Map> |
|
646 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) { |
|
647 return writeUndirEdgeMap<typename Traits:: |
|
648 template Writer<typename Map::Value>, Map>(name, map); |
|
649 } |
|
650 |
|
651 /// \brief Add a new undirected map writer command for the writer. |
|
652 /// |
|
653 /// Add a new undirected map writer command for the writer. |
|
654 template <typename Writer, typename Map> |
|
655 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, |
|
656 const Writer& writer = Writer()) { |
|
657 writers.push_back( |
|
658 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer))); |
|
659 return *this; |
|
660 } |
|
661 |
|
662 /// \brief Add a new directed edge map writer command for the writer. |
|
663 /// |
|
664 /// Add a new directed map writer command for the writer. |
|
665 template <typename Map> |
|
666 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { |
|
667 writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map)); |
|
668 writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map)); |
|
669 return *this; |
|
670 } |
|
671 |
|
672 /// \brief Add a new directed map writer command for the writer. |
|
673 /// |
|
674 /// Add a new directed map writer command for the writer. |
|
675 template <typename Writer, typename Map> |
|
676 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, |
|
677 const Writer& writer = Writer()) { |
|
678 writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer); |
|
679 writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer); |
|
680 return *this; |
|
681 } |
|
682 |
|
683 protected: |
|
684 |
|
685 /// \brief The header of the section. |
|
686 /// |
|
687 /// It gives back the header of the section. |
|
688 virtual std::string header() { |
|
689 return "@undiredgeset " + id; |
|
690 } |
|
691 |
|
692 /// \brief Writer function of the section. |
|
693 /// |
|
694 /// Write the content of the section. |
|
695 virtual void write(std::ostream& os) { |
|
696 for (int i = 0; i < (int)writers.size(); ++i) { |
|
697 if (writers[i].first == "id") { |
|
698 idMap = writers[i].second; |
|
699 forceIdMap = false; |
|
700 break; |
|
701 } |
|
702 } |
|
703 os << "\t\t"; |
|
704 if (forceIdMap) { |
|
705 os << "id\t"; |
|
706 } |
|
707 for (int i = 0; i < (int)writers.size(); ++i) { |
|
708 os << writers[i].first << '\t'; |
|
709 } |
|
710 os << std::endl; |
|
711 for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) { |
|
712 nodeIdWriter->write(os, graph.source(it)); |
|
713 os << '\t'; |
|
714 nodeIdWriter->write(os, graph.target(it)); |
|
715 os << '\t'; |
|
716 if (forceIdMap) { |
|
717 os << graph.id(it) << '\t'; |
|
718 } |
|
719 for (int i = 0; i < (int)writers.size(); ++i) { |
|
720 writers[i].second->write(os, it); |
|
721 os << '\t'; |
|
722 } |
|
723 os << std::endl; |
|
724 } |
|
725 } |
|
726 |
|
727 public: |
|
728 |
|
729 /// \brief Returns true if the undirected edgeset can write the ids of |
|
730 /// the edges. |
|
731 /// |
|
732 /// Returns true if the undirected edgeset can write the ids of the |
|
733 /// undirected edges. It is possible only if an "id" named map was |
|
734 /// written or the \c _forceIdMap constructor parameter was true. |
|
735 bool isIdWriter() const { |
|
736 return forceIdMap || idMap != 0; |
|
737 } |
|
738 |
|
739 /// \brief Write the id of the given undirected edge. |
|
740 /// |
|
741 /// It writes the id of the given undirected edge. If there was written |
|
742 /// an "id" named map then it will write the map value belongs to the |
|
743 /// undirected edge. Otherwise if the \c forceId parameter was true it |
|
744 /// will write its id in the graph. |
|
745 void writeId(std::ostream& os, const Item& item) const { |
|
746 if (forceIdMap) { |
|
747 os << graph.id(item); |
|
748 } else { |
|
749 idMap->write(os, item); |
|
750 } |
|
751 } |
|
752 |
|
753 private: |
|
754 |
|
755 typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters; |
|
756 MapWriters writers; |
|
757 |
|
758 WriterBase<Item>* idMap; |
|
759 bool forceIdMap; |
|
760 |
|
761 typename SmartConstReference<Graph>::Type graph; |
565 std::string id; |
762 std::string id; |
566 |
763 |
567 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter; |
764 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter; |
568 }; |
765 }; |
569 |
766 |
679 EdgeWriter(const EdgeWriter&); |
876 EdgeWriter(const EdgeWriter&); |
680 void operator=(const EdgeWriter&); |
877 void operator=(const EdgeWriter&); |
681 |
878 |
682 public: |
879 public: |
683 |
880 |
684 /// \brief Add an edge writer command for the NodeWriter. |
881 /// \brief Add an edge writer command for the EdgeWriter. |
685 /// |
882 /// |
686 /// Add an edge writer command for the NodeWriter. |
883 /// Add an edge writer command for the EdgeWriter. |
687 void writeEdge(const std::string& name, const Item& item) { |
884 void writeEdge(const std::string& name, const Item& item) { |
688 writers.push_back(make_pair(name, &item)); |
885 writers.push_back(make_pair(name, &item)); |
689 } |
886 } |
690 |
887 |
691 protected: |
888 protected: |
692 |
889 |
693 /// \brief Header checking function. |
890 /// \brief Header checking function. |
694 /// |
891 /// |
695 /// It gives back true when the header line start with \c @nodes, |
892 /// It gives back true when the header line start with \c \@edges, |
|
893 /// and the header line's id and the writer's id are the same. |
|
894 virtual std::string header() { |
|
895 return "@edges " + id; |
|
896 } |
|
897 |
|
898 /// \brief Writer function of the section. |
|
899 /// |
|
900 /// Write the content of the section. |
|
901 virtual void write(std::ostream& os) { |
|
902 for (int i = 0; i < (int)writers.size(); ++i) { |
|
903 os << writers[i].first << ' '; |
|
904 idWriter->write(os, *(writers[i].second)); |
|
905 os << std::endl; |
|
906 } |
|
907 } |
|
908 |
|
909 private: |
|
910 |
|
911 std::string id; |
|
912 |
|
913 typedef std::vector<std::pair<std::string, const Item*> > ItemWriters; |
|
914 ItemWriters writers; |
|
915 |
|
916 std::auto_ptr<IdWriterBase<Item> > idWriter; |
|
917 }; |
|
918 |
|
919 /// \ingroup io_group |
|
920 /// \brief SectionWriter for writing labeled undirected edges. |
|
921 /// |
|
922 /// The undirected edges section's header line is \c \@undiredges |
|
923 /// \c undiredges_id, but the \c undiredges_id may be empty. |
|
924 /// |
|
925 /// Each line in the section contains the label of the undirected edge and |
|
926 /// then the undirected edge id. |
|
927 /// |
|
928 /// \relates LemonWriter |
|
929 template <typename _Graph> |
|
930 class UndirEdgeWriter : public CommonSectionWriterBase { |
|
931 typedef CommonSectionWriterBase Parent; |
|
932 typedef _Graph Graph; |
|
933 typedef typename Graph::UndirEdge Item; |
|
934 public: |
|
935 |
|
936 /// \brief Constructor. |
|
937 /// |
|
938 /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and |
|
939 /// attach it into the given LemonWriter. The given \c _IdWriter |
|
940 /// will write the undirected edges' id what can be an undirected |
|
941 /// edgeset writer. |
|
942 template <typename _IdWriter> |
|
943 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
|
944 const std::string& _id = std::string()) |
|
945 : Parent(_writer), id(_id), |
|
946 idWriter(new IdWriter<typename Graph::UndirEdge, _IdWriter> |
|
947 (_idWriter)) {} |
|
948 |
|
949 /// \brief Destructor. |
|
950 /// |
|
951 /// Destructor for UndirEdgeWriter. |
|
952 virtual ~UndirEdgeWriter() {} |
|
953 private: |
|
954 UndirEdgeWriter(const UndirEdgeWriter&); |
|
955 void operator=(const UndirEdgeWriter&); |
|
956 |
|
957 public: |
|
958 |
|
959 /// \brief Add an undirected edge writer command for the UndirEdgeWriter. |
|
960 /// |
|
961 /// Add an edge writer command for the UndirEdgeWriter. |
|
962 void writeUndirEdge(const std::string& name, const Item& item) { |
|
963 writers.push_back(make_pair(name, &item)); |
|
964 } |
|
965 |
|
966 protected: |
|
967 |
|
968 /// \brief Header checking function. |
|
969 /// |
|
970 /// It gives back true when the header line start with \c \@undiredges, |
696 /// and the header line's id and the writer's id are the same. |
971 /// and the header line's id and the writer's id are the same. |
697 virtual std::string header() { |
972 virtual std::string header() { |
698 return "@edges " + id; |
973 return "@edges " + id; |
699 } |
974 } |
700 |
975 |