34 #include <lemon/graph_utils.h> |
34 #include <lemon/graph_utils.h> |
35 #include <lemon/bits/item_writer.h> |
35 #include <lemon/bits/item_writer.h> |
36 #include <lemon/utility.h> |
36 #include <lemon/utility.h> |
37 #include <lemon/maps.h> |
37 #include <lemon/maps.h> |
38 |
38 |
|
39 #include <lemon/concept_check.h> |
|
40 #include <lemon/concept/maps.h> |
|
41 |
39 |
42 |
40 namespace lemon { |
43 namespace lemon { |
|
44 |
|
45 namespace _writer_bits { |
|
46 |
|
47 template <typename Item> |
|
48 class ItemIdWriter { |
|
49 public: |
|
50 |
|
51 bool isIdWriter() { return true; } |
|
52 |
|
53 void writeId(std::ostream&, const Item&) {} |
|
54 |
|
55 template <class _ItemIdWriter> |
|
56 struct Constraints { |
|
57 void constraints() { |
|
58 const Item item; |
|
59 bool b = writer.isIdWriter(); |
|
60 ignore_unused_variable_warning(b); |
|
61 writer.writeId(os, item); |
|
62 } |
|
63 _ItemIdWriter& writer; |
|
64 std::ostream& os; |
|
65 }; |
|
66 |
|
67 }; |
|
68 |
|
69 } |
41 |
70 |
42 /// \ingroup io_group |
71 /// \ingroup io_group |
43 /// \brief Lemon Format writer class. |
72 /// \brief Lemon Format writer class. |
44 /// |
73 /// |
45 /// The Lemon Format contains several sections. We do not want to |
74 /// The Lemon Format contains several sections. We do not want to |
227 template <typename _Item> |
256 template <typename _Item> |
228 class IdWriterBase { |
257 class IdWriterBase { |
229 public: |
258 public: |
230 typedef _Item Item; |
259 typedef _Item Item; |
231 virtual void write(std::ostream&, const Item&) const = 0; |
260 virtual void write(std::ostream&, const Item&) const = 0; |
|
261 virtual bool isIdWriter() const = 0; |
232 }; |
262 }; |
233 |
263 |
234 template <typename _Item, typename _BoxedIdWriter> |
264 template <typename _Item, typename _BoxedIdWriter> |
235 class IdWriter : public IdWriterBase<_Item> { |
265 class IdWriter : public IdWriterBase<_Item> { |
236 public: |
266 public: |
242 IdWriter(const BoxedIdWriter& _idWriter) |
272 IdWriter(const BoxedIdWriter& _idWriter) |
243 : idWriter(_idWriter) {} |
273 : idWriter(_idWriter) {} |
244 |
274 |
245 virtual void write(std::ostream& os, const Item& item) const { |
275 virtual void write(std::ostream& os, const Item& item) const { |
246 idWriter.writeId(os, item); |
276 idWriter.writeId(os, item); |
|
277 } |
|
278 |
|
279 virtual bool isIdWriter() const { |
|
280 return idWriter.isIdWriter(); |
247 } |
281 } |
248 }; |
282 }; |
249 }; |
283 }; |
250 |
284 |
251 /// \ingroup io_group |
285 /// \ingroup io_group |
316 /// |
350 /// |
317 /// Add a new node map writer command for the writer. |
351 /// Add a new node map writer command for the writer. |
318 template <typename Writer, typename Map> |
352 template <typename Writer, typename Map> |
319 NodeSetWriter& writeNodeMap(std::string name, const Map& map, |
353 NodeSetWriter& writeNodeMap(std::string name, const Map& map, |
320 const Writer& writer = Writer()) { |
354 const Writer& writer = Writer()) { |
|
355 checkConcept<concept::WriteMap<Node, typename Map::Value>, Map>(); |
321 writers.push_back( |
356 writers.push_back( |
322 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer))); |
357 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer))); |
323 return *this; |
358 return *this; |
324 } |
359 } |
325 |
360 |
444 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
479 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
445 const NodeIdWriter& _nodeIdWriter, |
480 const NodeIdWriter& _nodeIdWriter, |
446 const std::string& _id = std::string(), |
481 const std::string& _id = std::string(), |
447 bool _forceIdMap = true) |
482 bool _forceIdMap = true) |
448 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
483 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
449 graph(_graph), id(_id), |
484 graph(_graph), id(_id) { |
450 nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {} |
485 checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>(); |
|
486 nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)); |
|
487 } |
451 |
488 |
452 /// \brief Destructor. |
489 /// \brief Destructor. |
453 /// |
490 /// |
454 /// Destructor for EdgeSetWriter. |
491 /// Destructor for EdgeSetWriter. |
455 virtual ~EdgeSetWriter() { |
492 virtual ~EdgeSetWriter() { |
478 /// |
515 /// |
479 /// Add a new edge map writer command for the writer. |
516 /// Add a new edge map writer command for the writer. |
480 template <typename Writer, typename Map> |
517 template <typename Writer, typename Map> |
481 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, |
518 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map, |
482 const Writer& writer = Writer()) { |
519 const Writer& writer = Writer()) { |
|
520 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>(); |
483 writers.push_back( |
521 writers.push_back( |
484 make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer))); |
522 make_pair(name, new MapWriter<Edge, Map, Writer>(map, writer))); |
485 return *this; |
523 return *this; |
486 } |
524 } |
487 |
525 |
496 |
534 |
497 /// \brief Writer function of the section. |
535 /// \brief Writer function of the section. |
498 /// |
536 /// |
499 /// Write the content of the section. |
537 /// Write the content of the section. |
500 virtual void write(std::ostream& os) { |
538 virtual void write(std::ostream& os) { |
|
539 if (!nodeIdWriter->isIdWriter()) { |
|
540 throw DataFormatError("Cannot find nodeset or ID map"); |
|
541 } |
501 for (int i = 0; i < (int)writers.size(); ++i) { |
542 for (int i = 0; i < (int)writers.size(); ++i) { |
502 if (writers[i].first == "id") { |
543 if (writers[i].first == "id") { |
503 idMap = writers[i].second; |
544 idMap = writers[i].second; |
504 forceIdMap = false; |
545 forceIdMap = false; |
505 break; |
546 break; |
619 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
660 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph, |
620 const NodeIdWriter& _nodeIdWriter, |
661 const NodeIdWriter& _nodeIdWriter, |
621 const std::string& _id = std::string(), |
662 const std::string& _id = std::string(), |
622 bool _forceIdMap = true) |
663 bool _forceIdMap = true) |
623 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
664 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap), |
624 graph(_graph), id(_id), |
665 graph(_graph), id(_id) { |
625 nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {} |
666 checkConcept<_writer_bits::ItemIdWriter<Node>, NodeIdWriter>(); |
|
667 nodeIdWriter.reset(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)); |
|
668 } |
626 |
669 |
627 /// \brief Destructor. |
670 /// \brief Destructor. |
628 /// |
671 /// |
629 /// Destructor for UndirEdgeSetWriter. |
672 /// Destructor for UndirEdgeSetWriter. |
630 virtual ~UndirEdgeSetWriter() { |
673 virtual ~UndirEdgeSetWriter() { |
653 /// |
696 /// |
654 /// Add a new undirected map writer command for the writer. |
697 /// Add a new undirected map writer command for the writer. |
655 template <typename Writer, typename Map> |
698 template <typename Writer, typename Map> |
656 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, |
699 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map, |
657 const Writer& writer = Writer()) { |
700 const Writer& writer = Writer()) { |
|
701 checkConcept<concept::WriteMap<UndirEdge, typename Map::Value>, Map>(); |
658 writers.push_back( |
702 writers.push_back( |
659 make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer))); |
703 make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer))); |
660 return *this; |
704 return *this; |
661 } |
705 } |
662 |
706 |
663 /// \brief Add a new directed edge map writer command for the writer. |
707 /// \brief Add a new directed edge map writer command for the writer. |
664 /// |
708 /// |
665 /// Add a new directed map writer command for the writer. |
709 /// Add a new directed map writer command for the writer. |
666 template <typename Map> |
710 template <typename Map> |
667 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { |
711 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) { |
|
712 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>(); |
668 writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map)); |
713 writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map)); |
669 writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map)); |
714 writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map)); |
670 return *this; |
715 return *this; |
671 } |
716 } |
672 |
717 |
674 /// |
719 /// |
675 /// Add a new directed map writer command for the writer. |
720 /// Add a new directed map writer command for the writer. |
676 template <typename Writer, typename Map> |
721 template <typename Writer, typename Map> |
677 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, |
722 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map, |
678 const Writer& writer = Writer()) { |
723 const Writer& writer = Writer()) { |
|
724 checkConcept<concept::WriteMap<Edge, typename Map::Value>, Map>(); |
679 writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer); |
725 writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer); |
680 writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer); |
726 writeUndirEdge("-" + name, composeMap(backwardMap(graph), map), writer); |
681 return *this; |
727 return *this; |
682 } |
728 } |
683 |
729 |
684 protected: |
730 protected: |
685 |
731 |
692 |
738 |
693 /// \brief Writer function of the section. |
739 /// \brief Writer function of the section. |
694 /// |
740 /// |
695 /// Write the content of the section. |
741 /// Write the content of the section. |
696 virtual void write(std::ostream& os) { |
742 virtual void write(std::ostream& os) { |
|
743 if (!nodeIdWriter->isIdWriter()) { |
|
744 throw DataFormatError("Cannot find nodeset or ID map"); |
|
745 } |
697 for (int i = 0; i < (int)writers.size(); ++i) { |
746 for (int i = 0; i < (int)writers.size(); ++i) { |
698 if (writers[i].first == "id") { |
747 if (writers[i].first == "id") { |
699 idMap = writers[i].second; |
748 idMap = writers[i].second; |
700 forceIdMap = false; |
749 forceIdMap = false; |
701 break; |
750 break; |
809 /// attach it into the given LemonWriter. The given \c _IdWriter |
858 /// attach it into the given LemonWriter. The given \c _IdWriter |
810 /// will write the nodes' id what can be a nodeset writer. |
859 /// will write the nodes' id what can be a nodeset writer. |
811 template <typename _IdWriter> |
860 template <typename _IdWriter> |
812 NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
861 NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
813 const std::string& _id = std::string()) |
862 const std::string& _id = std::string()) |
814 : Parent(_writer), id(_id), |
863 : Parent(_writer), id(_id) { |
815 idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {} |
864 checkConcept<_writer_bits::ItemIdWriter<Node>, _IdWriter>(); |
|
865 idWriter.reset(new IdWriter<Node, _IdWriter>(_idWriter)); |
|
866 } |
|
867 |
816 |
868 |
817 /// \brief Destructor. |
869 /// \brief Destructor. |
818 /// |
870 /// |
819 /// Destructor for NodeWriter. |
871 /// Destructor for NodeWriter. |
820 virtual ~NodeWriter() {} |
872 virtual ~NodeWriter() {} |
844 |
896 |
845 /// \brief Writer function of the section. |
897 /// \brief Writer function of the section. |
846 /// |
898 /// |
847 /// Write the content of the section. |
899 /// Write the content of the section. |
848 virtual void write(std::ostream& os) { |
900 virtual void write(std::ostream& os) { |
|
901 if (!idWriter->isIdWriter()) { |
|
902 throw DataFormatError("Cannot find nodeset or ID map"); |
|
903 } |
849 for (int i = 0; i < (int)writers.size(); ++i) { |
904 for (int i = 0; i < (int)writers.size(); ++i) { |
850 os << writers[i].first << ' '; |
905 os << writers[i].first << ' '; |
851 idWriter->write(os, *(writers[i].second)); |
906 idWriter->write(os, *(writers[i].second)); |
852 os << std::endl; |
907 os << std::endl; |
853 } |
908 } |
885 /// attach it into the given LemonWriter. The given \c _IdWriter |
940 /// attach it into the given LemonWriter. The given \c _IdWriter |
886 /// will write the edges' id what can be a edgeset writer. |
941 /// will write the edges' id what can be a edgeset writer. |
887 template <typename _IdWriter> |
942 template <typename _IdWriter> |
888 EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
943 EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
889 const std::string& _id = std::string()) |
944 const std::string& _id = std::string()) |
890 : Parent(_writer), id(_id), |
945 : Parent(_writer), id(_id) { |
891 idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {} |
946 checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>(); |
|
947 idWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter)); |
|
948 } |
892 |
949 |
893 /// \brief Destructor. |
950 /// \brief Destructor. |
894 /// |
951 /// |
895 /// Destructor for EdgeWriter. |
952 /// Destructor for EdgeWriter. |
896 virtual ~EdgeWriter() {} |
953 virtual ~EdgeWriter() {} |
919 |
976 |
920 /// \brief Writer function of the section. |
977 /// \brief Writer function of the section. |
921 /// |
978 /// |
922 /// Write the content of the section. |
979 /// Write the content of the section. |
923 virtual void write(std::ostream& os) { |
980 virtual void write(std::ostream& os) { |
|
981 if (!idWriter->isIdWriter()) { |
|
982 throw DataFormatError("Cannot find edgeset or ID map"); |
|
983 } |
924 for (int i = 0; i < (int)writers.size(); ++i) { |
984 for (int i = 0; i < (int)writers.size(); ++i) { |
925 os << writers[i].first << ' '; |
985 os << writers[i].first << ' '; |
926 idWriter->write(os, *(writers[i].second)); |
986 idWriter->write(os, *(writers[i].second)); |
927 os << std::endl; |
987 os << std::endl; |
928 } |
988 } |
964 /// will write the undirected edges' id what can be an undirected |
1024 /// will write the undirected edges' id what can be an undirected |
965 /// edgeset writer. |
1025 /// edgeset writer. |
966 template <typename _IdWriter> |
1026 template <typename _IdWriter> |
967 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
1027 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter, |
968 const std::string& _id = std::string()) |
1028 const std::string& _id = std::string()) |
969 : Parent(_writer), id(_id), |
1029 : Parent(_writer), id(_id) { |
970 undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)), |
1030 checkConcept<_writer_bits::ItemIdWriter<Edge>, _IdWriter>(); |
971 edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {} |
1031 checkConcept<_writer_bits::ItemIdWriter<UndirEdge>, _IdWriter>(); |
|
1032 undirEdgeIdWriter.reset(new IdWriter<UndirEdge, _IdWriter>(_idWriter)); |
|
1033 edgeIdWriter.reset(new IdWriter<Edge, _IdWriter>(_idWriter)); |
|
1034 } |
972 |
1035 |
973 /// \brief Destructor. |
1036 /// \brief Destructor. |
974 /// |
1037 /// |
975 /// Destructor for UndirEdgeWriter. |
1038 /// Destructor for UndirEdgeWriter. |
976 virtual ~UndirEdgeWriter() {} |
1039 virtual ~UndirEdgeWriter() {} |
1006 |
1069 |
1007 /// \brief Writer function of the section. |
1070 /// \brief Writer function of the section. |
1008 /// |
1071 /// |
1009 /// Write the content of the section. |
1072 /// Write the content of the section. |
1010 virtual void write(std::ostream& os) { |
1073 virtual void write(std::ostream& os) { |
|
1074 if (!edgeIdWriter->isIdWriter()) { |
|
1075 throw DataFormatError("Cannot find undirected edgeset or ID map"); |
|
1076 } |
|
1077 if (!undirEdgeIdWriter->isIdWriter()) { |
|
1078 throw DataFormatError("Cannot find undirected edgeset or ID map"); |
|
1079 } |
1011 for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) { |
1080 for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) { |
1012 os << undirEdgeWriters[i].first << ' '; |
1081 os << undirEdgeWriters[i].first << ' '; |
1013 undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second)); |
1082 undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second)); |
1014 os << std::endl; |
1083 os << std::endl; |
1015 } |
1084 } |