2 * src/lemon/lemon_writer.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
19 ///\brief Lemon Format writer.
21 #ifndef LEMON_LEMON_WRITER_H
22 #define LEMON_LEMON_WRITER_H
32 #include <lemon/error.h>
33 #include <lemon/invalid.h>
34 #include <lemon/graph_utils.h>
35 #include <lemon/bits/item_writer.h>
36 #include <lemon/utility.h>
37 #include <lemon/maps.h>
43 /// \brief Lemon Format writer class.
45 /// The Lemon Format contains several sections. We do not want to
46 /// determine what sections are in a lemon file we give only a framework
47 /// to write a section oriented format.
49 /// In the Lemon Format each section starts with a line contains a \c \@
50 /// character on the first not white space position. This line is the
51 /// header line of the section. Each next lines belong to this section
52 /// while it does not starts with \c \@ character. This line can start a
53 /// new section or if it can close the file with the \c \@end line.
54 /// The file format ignore the empty lines and it may contain comments
55 /// started with a \c # character to the end of the line.
57 /// The framework provides an abstract LemonWriter::SectionWriter class
58 /// what defines the interface of a SectionWriter. The SectionWriter
59 /// has the \c header() member function what gives back the header of the
60 /// section. After that it will be called the \c write() member which
61 /// should write the content of the section.
63 /// \relates GraphWriter
64 /// \relates NodeSetWriter
65 /// \relates EdgeSetWriter
66 /// \relates NodesWriter
67 /// \relates EdgesWriter
68 /// \relates AttributeWriter
72 /// \brief Abstract base class for writing a section.
74 /// This class has an \c header() member function what gives back
75 /// the header line of the section. The \c write() member should
76 /// write the content of the section to the stream.
78 friend class LemonWriter;
80 /// \brief Constructor for SectionWriter.
82 /// Constructor for SectionWriter. It attach this writer to
83 /// the given LemonWriter.
84 SectionWriter(LemonWriter& writer) {
88 /// \brief The header of section.
90 /// It gives back the header of the section.
91 virtual std::string header() = 0;
93 /// \brief Writer function of the section.
95 /// Write the content of the section.
96 virtual void write(std::ostream& os) = 0;
99 /// \brief Constructor for LemonWriter.
101 /// Constructor for LemonWriter which writes to the given stream.
102 LemonWriter(std::ostream& _os)
103 : os(&_os), own_os(false) {}
105 /// \brief Constructor for LemonWriter.
107 /// Constructor for LemonWriter which writes to the given file.
108 LemonWriter(const std::string& filename)
109 : os(0), own_os(true) {
110 os = new std::ofstream(filename.c_str());
113 /// \brief Desctructor for LemonWriter.
115 /// Desctructor for LemonWriter.
123 LemonWriter(const LemonWriter&);
124 void operator=(const LemonWriter&);
126 void attach(SectionWriter& writer) {
127 writers.push_back(&writer);
132 /// \brief Executes the LemonWriter.
134 /// It executes the LemonWriter.
136 SectionWriters::iterator it;
137 for (it = writers.begin(); it != writers.end(); ++it) {
138 *os << (*it)->header() << std::endl;
141 *os << "@end" << std::endl;
150 typedef std::vector<SectionWriter*> SectionWriters;
151 SectionWriters writers;
155 /// \brief Helper class for implementing the common SectionWriters.
157 /// Helper class for implementing the common SectionWriters.
158 class CommonSectionWriterBase : public LemonWriter::SectionWriter {
159 typedef LemonWriter::SectionWriter Parent;
162 /// \brief Constructor for CommonSectionWriterBase.
164 /// Constructor for CommonSectionWriterBase. It attach this writer to
165 /// the given LemonWriter.
166 CommonSectionWriterBase(LemonWriter& _writer)
169 template <typename _Item>
174 virtual ~WriterBase() {}
176 virtual void write(std::ostream& os, const Item& item) = 0;
180 template <typename _Item, typename _Map, typename _Writer>
181 class MapWriter : public WriterBase<_Item> {
184 typedef _Writer Writer;
185 typedef typename Writer::Value Value;
188 typename SmartConstReference<Map>::Type map;
191 MapWriter(const Map& _map, const Writer& _writer)
192 : map(_map), writer(_writer) {}
194 virtual ~MapWriter() {}
196 virtual void write(std::ostream& os, const Item& item) {
197 Value value = map[item];
198 writer.write(os, value);
204 class ValueWriterBase {
206 virtual void write(std::ostream&) = 0;
209 template <typename _Value, typename _Writer>
210 class ValueWriter : public ValueWriterBase {
212 typedef _Value Value;
213 typedef _Writer Writer;
215 ValueWriter(const Value& _value, const Writer& _writer)
216 : value(_value), writer(_writer) {}
218 virtual void write(std::ostream& os) {
219 writer.write(os, value);
227 template <typename _Item>
231 virtual void write(std::ostream&, const Item&) const = 0;
234 template <typename _Item, typename _BoxedIdWriter>
235 class IdWriter : public IdWriterBase<_Item> {
238 typedef _BoxedIdWriter BoxedIdWriter;
240 const BoxedIdWriter& idWriter;
242 IdWriter(const BoxedIdWriter& _idWriter)
243 : idWriter(_idWriter) {}
245 virtual void write(std::ostream& os, const Item& item) const {
246 return idWriter.writeId(os, item);
251 /// \ingroup io_group
252 /// \brief SectionWriter for writing a graph's nodeset.
254 /// The lemon format can store multiple graph nodesets with several maps.
255 /// The nodeset section's header line is \c \@nodeset \c nodeset_id, but the
256 /// \c nodeset_id may be empty.
258 /// The first line of the section contains the names of the maps separated
259 /// with white spaces. Each next lines describes a node in the nodeset, and
260 /// contains the mapped values for each map.
262 /// If the nodeset contains an \c "id" named map then it will be regarded
263 /// as id map. This map should contain only unique values and when the
264 /// \c writeId() member will be called with a node it will write it's id.
265 /// Otherwise if the \c _forceIdMap constructor parameter is true then
266 /// the id map will be the id in the graph.
268 /// \relates LemonWriter
269 template <typename _Graph, typename _Traits = DefaultWriterTraits>
270 class NodeSetWriter : public CommonSectionWriterBase {
271 typedef CommonSectionWriterBase Parent;
274 typedef _Graph Graph;
275 typedef _Traits Traits;
276 typedef typename Graph::Node Item;
278 /// \brief Constructor.
280 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
281 /// attach it into the given LemonWriter. If the \c _forceIdMap
282 /// parameter is true then the writer will write own id map when
283 /// the user does not give "id" named map.
284 NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
285 const std::string& _id = std::string(),
286 bool _forceIdMap = true)
287 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
288 graph(_graph), id(_id) {}
290 /// \brief Destructor.
292 /// Destructor for NodeSetWriter.
293 virtual ~NodeSetWriter() {
294 typename MapWriters::iterator it;
295 for (it = writers.begin(); it != writers.end(); ++it) {
301 NodeSetWriter(const NodeSetWriter&);
302 void operator=(const NodeSetWriter&);
306 /// \brief Add a new node map writer command for the writer.
308 /// Add a new node map writer command for the writer.
309 template <typename Map>
310 NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
311 return writeNodeMap<typename Traits::
312 template Writer<typename Map::Value>, Map>(name, map);
315 /// \brief Add a new node map writer command for the writer.
317 /// Add a new node map writer command for the writer.
318 template <typename Writer, typename Map>
319 NodeSetWriter& writeNodeMap(std::string name, const Map& map,
320 const Writer& writer = Writer()) {
322 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
328 /// \brief The header of the section.
330 /// It gives back the header of the section.
331 virtual std::string header() {
332 return "@nodeset " + id;
335 /// \brief Writer function of the section.
337 /// Write the content of the section.
338 virtual void write(std::ostream& os) {
339 for (int i = 0; i < (int)writers.size(); ++i) {
340 if (writers[i].first == "id") {
341 idMap = writers[i].second;
349 for (int i = 0; i < (int)writers.size(); ++i) {
350 os << writers[i].first << '\t';
353 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
355 os << graph.id(it) << '\t';
357 for (int i = 0; i < (int)writers.size(); ++i) {
358 writers[i].second->write(os, it);
367 /// \brief Returns true if the nodeset can write the ids of the nodes.
369 /// Returns true if the nodeset can write the ids of the nodes.
370 /// It is possible only if an "id" named map was written or the
371 /// \c _forceIdMap constructor parameter was true.
372 bool isIdWriter() const {
373 return idMap != 0 || forceIdMap;
376 /// \brief Write the id of the given node.
378 /// It writes the id of the given node. If there was written an "id"
379 /// named map then it will write the map value belongs to the node.
380 /// Otherwise if the \c forceId parameter was true it will write
381 /// its id in the graph.
382 void writeId(std::ostream& os, const Item& item) const {
384 os << graph.id(item);
386 idMap->write(os, item);
392 typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters;
395 WriterBase<Item>* idMap;
398 typename SmartConstReference<Graph>::Type graph;
403 /// \ingroup io_group
404 /// \brief SectionWriter for writing a graph's edgesets.
406 /// The lemon format can store multiple graph edgesets with several maps.
407 /// The edgeset section's header line is \c \@edgeset \c edgeset_id, but the
408 /// \c edgeset_id may be empty.
410 /// The first line of the section contains the names of the maps separated
411 /// with white spaces. Each next lines describes a edge in the edgeset. The
412 /// line contains the source and the target nodes' id and the mapped
413 /// values for each map.
415 /// If the edgeset contains an \c "id" named map then it will be regarded
416 /// as id map. This map should contain only unique values and when the
417 /// \c writeId() member will be called with an edge it will write it's id.
418 /// Otherwise if the \c _forceIdMap constructor parameter is true then
419 /// the id map will be the id in the graph.
421 /// The edgeset writer needs a node id writer to identify which nodes
422 /// have to be connected. If a NodeSetWriter can write the nodes' id,
423 /// it will be able to use with this class.
425 /// \relates LemonWriter
426 template <typename _Graph, typename _Traits = DefaultWriterTraits>
427 class EdgeSetWriter : public CommonSectionWriterBase {
428 typedef CommonSectionWriterBase Parent;
431 typedef _Graph Graph;
432 typedef _Traits Traits;
433 typedef typename Graph::Edge Item;
435 /// \brief Constructor.
437 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
438 /// attach it into the given LemonWriter. It will write node ids by
439 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
440 /// then the writer will write own id map if the user does not give
442 template <typename NodeIdWriter>
443 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
444 const NodeIdWriter& _nodeIdWriter,
445 const std::string& _id = std::string(),
446 bool _forceIdMap = true)
447 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
448 graph(_graph), id(_id),
449 nodeIdWriter(new IdWriter<typename Graph::Node, NodeIdWriter>
452 /// \brief Destructor.
454 /// Destructor for EdgeSetWriter.
455 virtual ~EdgeSetWriter() {
456 typename MapWriters::iterator it;
457 for (it = writers.begin(); it != writers.end(); ++it) {
463 EdgeSetWriter(const EdgeSetWriter&);
464 void operator=(const EdgeSetWriter&);
468 /// \brief Add a new edge map writer command for the writer.
470 /// Add a new edge map writer command for the writer.
471 template <typename Map>
472 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
473 return writeEdgeMap<typename Traits::
474 template Writer<typename Map::Value>, Map>(name, map);
477 /// \brief Add a new edge map writer command for the writer.
479 /// Add a new edge map writer command for the writer.
480 template <typename Writer, typename Map>
481 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
482 const Writer& writer = Writer()) {
484 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
490 /// \brief The header of the section.
492 /// It gives back the header of the section.
493 virtual std::string header() {
494 return "@edgeset " + id;
497 /// \brief Writer function of the section.
499 /// Write the content of the section.
500 virtual void write(std::ostream& os) {
501 for (int i = 0; i < (int)writers.size(); ++i) {
502 if (writers[i].first == "id") {
503 idMap = writers[i].second;
512 for (int i = 0; i < (int)writers.size(); ++i) {
513 os << writers[i].first << '\t';
516 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
517 nodeIdWriter->write(os, graph.source(it));
519 nodeIdWriter->write(os, graph.target(it));
522 os << graph.id(it) << '\t';
524 for (int i = 0; i < (int)writers.size(); ++i) {
525 writers[i].second->write(os, it);
534 /// \brief Returns true if the edgeset can write the ids of the edges.
536 /// Returns true if the edgeset can write the ids of the edges.
537 /// It is possible only if an "id" named map was written or the
538 /// \c _forceIdMap constructor parameter was true.
539 bool isIdWriter() const {
540 return forceIdMap || idMap != 0;
543 /// \brief Write the id of the given edge.
545 /// It writes the id of the given edge. If there was written an "id"
546 /// named map then it will write the map value belongs to the edge.
547 /// Otherwise if the \c forceId parameter was true it will write
548 /// its id in the graph.
549 void writeId(std::ostream& os, const Item& item) const {
551 os << graph.id(item);
553 idMap->write(os, item);
559 typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters;
562 WriterBase<Item>* idMap;
565 typename SmartConstReference<Graph>::Type graph;
568 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
571 /// \ingroup io_group
572 /// \brief SectionWriter for writing a undirected edgeset.
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.
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.
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
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.
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.
599 /// \relates LemonWriter
600 template <typename _Graph, typename _Traits = DefaultWriterTraits>
601 class UndirEdgeSetWriter : public CommonSectionWriterBase {
602 typedef CommonSectionWriterBase Parent;
605 typedef _Graph Graph;
606 typedef _Traits Traits;
607 typedef typename Graph::UndirEdge Item;
609 /// \brief Constructor.
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
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>
626 /// \brief Destructor.
628 /// Destructor for UndirEdgeSetWriter.
629 virtual ~UndirEdgeSetWriter() {
630 typename MapWriters::iterator it;
631 for (it = writers.begin(); it != writers.end(); ++it) {
637 UndirEdgeSetWriter(const UndirEdgeSetWriter&);
638 void operator=(const UndirEdgeSetWriter&);
642 /// \brief Add a new undirected edge map writer command for the writer.
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);
651 /// \brief Add a new undirected map writer command for the writer.
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()) {
658 make_pair(name, new MapWriter<Item, Map, Writer>(map, writer)));
662 /// \brief Add a new directed edge map writer command for the writer.
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));
672 /// \brief Add a new directed map writer command for the writer.
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);
685 /// \brief The header of the section.
687 /// It gives back the header of the section.
688 virtual std::string header() {
689 return "@undiredgeset " + id;
692 /// \brief Writer function of the section.
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;
707 for (int i = 0; i < (int)writers.size(); ++i) {
708 os << writers[i].first << '\t';
711 for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
712 nodeIdWriter->write(os, graph.source(it));
714 nodeIdWriter->write(os, graph.target(it));
717 os << graph.id(it) << '\t';
719 for (int i = 0; i < (int)writers.size(); ++i) {
720 writers[i].second->write(os, it);
729 /// \brief Returns true if the undirected edgeset can write the ids of
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;
739 /// \brief Write the id of the given undirected edge.
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 {
747 os << graph.id(item);
749 idMap->write(os, item);
755 typedef std::vector<std::pair<std::string, WriterBase<Item>*> > MapWriters;
758 WriterBase<Item>* idMap;
761 typename SmartConstReference<Graph>::Type graph;
764 std::auto_ptr<IdWriterBase<typename Graph::Node> > nodeIdWriter;
767 /// \ingroup io_group
768 /// \brief SectionWriter for writing labeled nodes.
770 /// The nodes section's header line is \c \@nodes \c nodes_id, but the
771 /// \c nodes_id may be empty.
773 /// Each line in the section contains the label of the node and
774 /// then the node id.
776 /// \relates LemonWriter
777 template <typename _Graph>
778 class NodeWriter : public CommonSectionWriterBase {
779 typedef CommonSectionWriterBase Parent;
780 typedef _Graph Graph;
781 typedef typename Graph::Node Item;
784 /// \brief Constructor.
786 /// Constructor for NodeWriter. It creates the NodeWriter and
787 /// attach it into the given LemonWriter. The given \c _IdWriter
788 /// will write the nodes' id what can be a nodeset writer.
789 template <typename _IdWriter>
790 NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
791 const std::string& _id = std::string())
792 : Parent(_writer), id(_id),
793 idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {}
795 /// \brief Destructor.
797 /// Destructor for NodeWriter.
798 virtual ~NodeWriter() {}
801 NodeWriter(const NodeWriter&);
802 void operator=(const NodeWriter&);
806 /// \brief Add a node writer command for the NodeWriter.
808 /// Add a node writer command for the NodeWriter.
809 void writeNode(const std::string& name, const Item& item) {
810 writers.push_back(make_pair(name, &item));
815 /// \brief Header checking function.
817 /// It gives back true when the header line start with \c \@nodes,
818 /// and the header line's id and the writer's id are the same.
819 virtual std::string header() {
820 return "@nodes " + id;
823 /// \brief Writer function of the section.
825 /// Write the content of the section.
826 virtual void write(std::ostream& os) {
827 for (int i = 0; i < (int)writers.size(); ++i) {
828 os << writers[i].first << ' ';
829 idWriter->write(os, *(writers[i].second));
838 typedef std::vector<std::pair<std::string, const Item*> > ItemWriters;
840 std::auto_ptr<IdWriterBase<Item> > idWriter;
843 /// \ingroup io_group
844 /// \brief SectionWriter for writing labeled edges.
846 /// The edges section's header line is \c \@edges \c edges_id, but the
847 /// \c edges_id may be empty.
849 /// Each line in the section contains the label of the edge and
850 /// then the edge id.
852 /// \relates LemonWriter
853 template <typename _Graph>
854 class EdgeWriter : public CommonSectionWriterBase {
855 typedef CommonSectionWriterBase Parent;
856 typedef _Graph Graph;
857 typedef typename Graph::Edge Item;
860 /// \brief Constructor.
862 /// Constructor for EdgeWriter. It creates the EdgeWriter and
863 /// attach it into the given LemonWriter. The given \c _IdWriter
864 /// will write the edges' id what can be a edgeset writer.
865 template <typename _IdWriter>
866 EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
867 const std::string& _id = std::string())
868 : Parent(_writer), id(_id),
869 idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {}
871 /// \brief Destructor.
873 /// Destructor for EdgeWriter.
874 virtual ~EdgeWriter() {}
876 EdgeWriter(const EdgeWriter&);
877 void operator=(const EdgeWriter&);
881 /// \brief Add an edge writer command for the EdgeWriter.
883 /// Add an edge writer command for the EdgeWriter.
884 void writeEdge(const std::string& name, const Item& item) {
885 writers.push_back(make_pair(name, &item));
890 /// \brief Header checking function.
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;
898 /// \brief Writer function of the section.
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));
913 typedef std::vector<std::pair<std::string, const Item*> > ItemWriters;
916 std::auto_ptr<IdWriterBase<Item> > idWriter;
919 /// \ingroup io_group
920 /// \brief SectionWriter for writing labeled undirected edges.
922 /// The undirected edges section's header line is \c \@undiredges
923 /// \c undiredges_id, but the \c undiredges_id may be empty.
925 /// Each line in the section contains the label of the undirected edge and
926 /// then the undirected edge id.
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;
936 /// \brief Constructor.
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
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>
949 /// \brief Destructor.
951 /// Destructor for UndirEdgeWriter.
952 virtual ~UndirEdgeWriter() {}
954 UndirEdgeWriter(const UndirEdgeWriter&);
955 void operator=(const UndirEdgeWriter&);
959 /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
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));
968 /// \brief Header checking function.
970 /// It gives back true when the header line start with \c \@undiredges,
971 /// and the header line's id and the writer's id are the same.
972 virtual std::string header() {
973 return "@edges " + id;
976 /// \brief Writer function of the section.
978 /// Write the content of the section.
979 virtual void write(std::ostream& os) {
980 for (int i = 0; i < (int)writers.size(); ++i) {
981 os << writers[i].first << ' ';
982 idWriter->write(os, *(writers[i].second));
991 typedef std::vector<std::pair<std::string, const Item*> > ItemWriters;
994 std::auto_ptr<IdWriterBase<Item> > idWriter;
997 /// \ingroup io_group
998 /// \brief SectionWriter for attributes.
1000 /// The lemon format can store multiple attribute set. Each set has
1001 /// the header line \c \@attributes \c attributeset_id, but the
1002 /// attributeset_id may be empty.
1004 /// The attributeset section contains several lines. Each of them starts
1005 /// with the name of attribute and then the value.
1007 /// \relates LemonWriter
1008 template <typename _Traits = DefaultWriterTraits>
1009 class AttributeWriter : public CommonSectionWriterBase {
1010 typedef CommonSectionWriterBase Parent;
1011 typedef _Traits Traits;
1013 /// \brief Constructor.
1015 /// Constructor for AttributeWriter. It creates the AttributeWriter and
1016 /// attach it into the given LemonWriter.
1017 AttributeWriter(LemonWriter& _writer,
1018 const std::string& _id = std::string())
1019 : Parent(_writer), id(_id) {}
1021 /// \brief Destructor.
1023 /// Destructor for AttributeWriter.
1024 virtual ~AttributeWriter() {
1025 typename Writers::iterator it;
1026 for (it = writers.begin(); it != writers.end(); ++it) {
1032 AttributeWriter(const AttributeWriter&);
1033 void operator=(AttributeWriter&);
1036 /// \brief Add an attribute writer command for the writer.
1038 /// Add an attribute writer command for the writer.
1039 template <typename Value>
1040 AttributeWriter& writeAttribute(const std::string& id,
1041 const Value& value) {
1043 writeAttribute<typename Traits::template Writer<Value> >(id, value);
1046 /// \brief Add an attribute writer command for the writer.
1048 /// Add an attribute writer command for the writer.
1049 template <typename Writer, typename Value>
1050 AttributeWriter& writeAttribute(const std::string& name,
1052 const Writer& writer = Writer()) {
1053 writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
1060 /// \brief The header of section.
1062 /// It gives back the header of the section.
1063 std::string header() {
1064 return "@attributes " + id;
1067 /// \brief Writer function of the section.
1069 /// Write the content of the section.
1070 void write(std::ostream& os) {
1071 typename Writers::iterator it;
1072 for (it = writers.begin(); it != writers.end(); ++it) {
1073 os << it->first << ' ';
1074 it->second->write(os);
1082 typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;