2 * 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 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 Node;
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<Node, 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 Node& item) const {
384 os << graph.id(item);
386 idMap->write(os, item);
392 typedef std::vector<std::pair<std::string, WriterBase<Node>*> > MapWriters;
395 WriterBase<Node>* 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::Node Node;
434 typedef typename Graph::Edge Edge;
436 /// \brief Constructor.
438 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
439 /// attach it into the given LemonWriter. It will write node ids by
440 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
441 /// then the writer will write own id map if the user does not give
443 template <typename NodeIdWriter>
444 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
445 const NodeIdWriter& _nodeIdWriter,
446 const std::string& _id = std::string(),
447 bool _forceIdMap = true)
448 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
449 graph(_graph), id(_id),
450 nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_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<Edge, 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 Edge& item) const {
551 os << graph.id(item);
553 idMap->write(os, item);
559 typedef std::vector<std::pair<std::string, WriterBase<Edge>*> > MapWriters;
562 WriterBase<Edge>* idMap;
565 typename SmartConstReference<Graph>::Type graph;
568 std::auto_ptr<IdWriterBase<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::Node Node;
608 typedef typename Graph::Edge Edge;
609 typedef typename Graph::UndirEdge UndirEdge;
611 /// \brief Constructor.
613 /// Constructor for UndirEdgeSetWriter. It creates the UndirEdgeSetWriter
614 /// and attach it into the given LemonWriter. It will write node ids by
615 /// the \c _nodeIdWriter. If the \c _forceIdMap parameter is true
616 /// then the writer will write own id map if the user does not give
618 template <typename NodeIdWriter>
619 UndirEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
620 const NodeIdWriter& _nodeIdWriter,
621 const std::string& _id = std::string(),
622 bool _forceIdMap = true)
623 : Parent(_writer), idMap(0), forceIdMap(_forceIdMap),
624 graph(_graph), id(_id),
625 nodeIdWriter(new IdWriter<Node, NodeIdWriter>(_nodeIdWriter)) {}
627 /// \brief Destructor.
629 /// Destructor for UndirEdgeSetWriter.
630 virtual ~UndirEdgeSetWriter() {
631 typename MapWriters::iterator it;
632 for (it = writers.begin(); it != writers.end(); ++it) {
638 UndirEdgeSetWriter(const UndirEdgeSetWriter&);
639 void operator=(const UndirEdgeSetWriter&);
643 /// \brief Add a new undirected edge map writer command for the writer.
645 /// Add a new undirected map writer command for the writer.
646 template <typename Map>
647 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map) {
648 return writeUndirEdgeMap<typename Traits::
649 template Writer<typename Map::Value>, Map>(name, map);
652 /// \brief Add a new undirected map writer command for the writer.
654 /// Add a new undirected map writer command for the writer.
655 template <typename Writer, typename Map>
656 UndirEdgeSetWriter& writeUndirEdgeMap(std::string name, const Map& map,
657 const Writer& writer = Writer()) {
659 make_pair(name, new MapWriter<UndirEdge, Map, Writer>(map, writer)));
663 /// \brief Add a new directed edge map writer command for the writer.
665 /// Add a new directed map writer command for the writer.
666 template <typename Map>
667 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
668 writeUndirEdgeMap("+" + name, composeMap(forwardMap(graph), map));
669 writeUndirEdgeMap("-" + name, composeMap(backwardMap(graph), map));
673 /// \brief Add a new directed map writer command for the writer.
675 /// Add a new directed map writer command for the writer.
676 template <typename Writer, typename Map>
677 UndirEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
678 const Writer& writer = Writer()) {
679 writeUndirEdge("+" + name, composeMap(forwardMap(graph), map), writer);
680 writeUndirEdge("-" + name, composeMap(forwardMap(graph), map), writer);
686 /// \brief The header of the section.
688 /// It gives back the header of the section.
689 virtual std::string header() {
690 return "@undiredgeset " + id;
693 /// \brief Writer function of the section.
695 /// Write the content of the section.
696 virtual void write(std::ostream& os) {
697 for (int i = 0; i < (int)writers.size(); ++i) {
698 if (writers[i].first == "id") {
699 idMap = writers[i].second;
708 for (int i = 0; i < (int)writers.size(); ++i) {
709 os << writers[i].first << '\t';
712 for (typename Graph::UndirEdgeIt it(graph); it != INVALID; ++it) {
713 nodeIdWriter->write(os, graph.source(it));
715 nodeIdWriter->write(os, graph.target(it));
718 os << graph.id(it) << '\t';
720 for (int i = 0; i < (int)writers.size(); ++i) {
721 writers[i].second->write(os, it);
730 /// \brief Returns true if the undirected edgeset can write the ids of
733 /// Returns true if the undirected edgeset can write the ids of the
734 /// undirected edges. It is possible only if an "id" named map was
735 /// written or the \c _forceIdMap constructor parameter was true.
736 bool isIdWriter() const {
737 return forceIdMap || idMap != 0;
740 /// \brief Write the id of the given undirected edge.
742 /// It writes the id of the given undirected edge. If there was written
743 /// an "id" named map then it will write the map value belongs to the
744 /// undirected edge. Otherwise if the \c forceId parameter was true it
745 /// will write its id in the graph.
746 void writeId(std::ostream& os, const UndirEdge& item) const {
748 os << graph.id(item);
750 idMap->write(os, item);
754 /// \brief Write the id of the given edge.
756 /// It writes the id of the given edge. If there was written
757 /// an "id" named map then it will write the map value belongs to the
758 /// edge. Otherwise if the \c forceId parameter was true it
759 /// will write its id in the graph. If the edge is forward map
760 /// then its prefix character is \c '+' elsewhere \c '-'.
761 void writeId(std::ostream& os, const Edge& item) const {
762 if (graph.forward(item)) {
768 os << graph.id(item);
770 idMap->write(os, item);
776 typedef std::vector<std::pair<std::string,
777 WriterBase<UndirEdge>*> > MapWriters;
780 WriterBase<UndirEdge>* idMap;
783 typename SmartConstReference<Graph>::Type graph;
786 std::auto_ptr<IdWriterBase<Node> > nodeIdWriter;
789 /// \ingroup io_group
790 /// \brief SectionWriter for writing labeled nodes.
792 /// The nodes section's header line is \c \@nodes \c nodes_id, but the
793 /// \c nodes_id may be empty.
795 /// Each line in the section contains the label of the node and
796 /// then the node id.
798 /// \relates LemonWriter
799 template <typename _Graph>
800 class NodeWriter : public CommonSectionWriterBase {
801 typedef CommonSectionWriterBase Parent;
802 typedef _Graph Graph;
803 typedef typename Graph::Node Node;
806 /// \brief Constructor.
808 /// Constructor for NodeWriter. It creates the NodeWriter and
809 /// attach it into the given LemonWriter. The given \c _IdWriter
810 /// will write the nodes' id what can be a nodeset writer.
811 template <typename _IdWriter>
812 NodeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
813 const std::string& _id = std::string())
814 : Parent(_writer), id(_id),
815 idWriter(new IdWriter<typename Graph::Node, _IdWriter>(_idWriter)) {}
817 /// \brief Destructor.
819 /// Destructor for NodeWriter.
820 virtual ~NodeWriter() {}
823 NodeWriter(const NodeWriter&);
824 void operator=(const NodeWriter&);
828 /// \brief Add a node writer command for the NodeWriter.
830 /// Add a node writer command for the NodeWriter.
831 void writeNode(const std::string& name, const Node& item) {
832 writers.push_back(make_pair(name, &item));
837 /// \brief Header checking function.
839 /// It gives back true when the header line start with \c \@nodes,
840 /// and the header line's id and the writer's id are the same.
841 virtual std::string header() {
842 return "@nodes " + id;
845 /// \brief Writer function of the section.
847 /// Write the content of the section.
848 virtual void write(std::ostream& os) {
849 for (int i = 0; i < (int)writers.size(); ++i) {
850 os << writers[i].first << ' ';
851 idWriter->write(os, *(writers[i].second));
860 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
862 std::auto_ptr<IdWriterBase<Node> > idWriter;
865 /// \ingroup io_group
866 /// \brief SectionWriter for writing labeled edges.
868 /// The edges section's header line is \c \@edges \c edges_id, but the
869 /// \c edges_id may be empty.
871 /// Each line in the section contains the label of the edge and
872 /// then the edge id.
874 /// \relates LemonWriter
875 template <typename _Graph>
876 class EdgeWriter : public CommonSectionWriterBase {
877 typedef CommonSectionWriterBase Parent;
878 typedef _Graph Graph;
879 typedef typename Graph::Edge Edge;
882 /// \brief Constructor.
884 /// Constructor for EdgeWriter. It creates the EdgeWriter and
885 /// attach it into the given LemonWriter. The given \c _IdWriter
886 /// will write the edges' id what can be a edgeset writer.
887 template <typename _IdWriter>
888 EdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
889 const std::string& _id = std::string())
890 : Parent(_writer), id(_id),
891 idWriter(new IdWriter<typename Graph::Edge, _IdWriter>(_idWriter)) {}
893 /// \brief Destructor.
895 /// Destructor for EdgeWriter.
896 virtual ~EdgeWriter() {}
898 EdgeWriter(const EdgeWriter&);
899 void operator=(const EdgeWriter&);
903 /// \brief Add an edge writer command for the EdgeWriter.
905 /// Add an edge writer command for the EdgeWriter.
906 void writeEdge(const std::string& name, const Edge& item) {
907 writers.push_back(make_pair(name, &item));
912 /// \brief Header checking function.
914 /// It gives back true when the header line start with \c \@edges,
915 /// and the header line's id and the writer's id are the same.
916 virtual std::string header() {
917 return "@edges " + id;
920 /// \brief Writer function of the section.
922 /// Write the content of the section.
923 virtual void write(std::ostream& os) {
924 for (int i = 0; i < (int)writers.size(); ++i) {
925 os << writers[i].first << ' ';
926 idWriter->write(os, *(writers[i].second));
935 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
938 std::auto_ptr<IdWriterBase<Edge> > idWriter;
941 /// \ingroup io_group
942 /// \brief SectionWriter for writing labeled undirected edges.
944 /// The undirected edges section's header line is \c \@undiredges
945 /// \c undiredges_id, but the \c undiredges_id may be empty.
947 /// Each line in the section contains the label of the undirected edge and
948 /// then the undirected edge id.
950 /// \relates LemonWriter
951 template <typename _Graph>
952 class UndirEdgeWriter : public CommonSectionWriterBase {
953 typedef CommonSectionWriterBase Parent;
954 typedef _Graph Graph;
955 typedef typename Graph::Node Node;
956 typedef typename Graph::Edge Edge;
957 typedef typename Graph::UndirEdge UndirEdge;
960 /// \brief Constructor.
962 /// Constructor for UndirEdgeWriter. It creates the UndirEdgeWriter and
963 /// attach it into the given LemonWriter. The given \c _IdWriter
964 /// will write the undirected edges' id what can be an undirected
966 template <typename _IdWriter>
967 UndirEdgeWriter(LemonWriter& _writer, const _IdWriter& _idWriter,
968 const std::string& _id = std::string())
969 : Parent(_writer), id(_id),
970 undirEdgeIdWriter(new IdWriter<UndirEdge, _IdWriter>(_idWriter)),
971 edgeIdWriter(new IdWriter<Edge, _IdWriter>(_idWriter)) {}
973 /// \brief Destructor.
975 /// Destructor for UndirEdgeWriter.
976 virtual ~UndirEdgeWriter() {}
978 UndirEdgeWriter(const UndirEdgeWriter&);
979 void operator=(const UndirEdgeWriter&);
983 /// \brief Add an edge writer command for the UndirEdgeWriter.
985 /// Add an edge writer command for the UndirEdgeWriter.
986 void writeEdge(const std::string& name, const Edge& item) {
987 edgeWriters.push_back(make_pair(name, &item));
990 /// \brief Add an undirected edge writer command for the UndirEdgeWriter.
992 /// Add an undirected edge writer command for the UndirEdgeWriter.
993 void writeUndirEdge(const std::string& name, const UndirEdge& item) {
994 undirEdgeWriters.push_back(make_pair(name, &item));
999 /// \brief Header checking function.
1001 /// It gives back true when the header line start with \c \@undiredges,
1002 /// and the header line's id and the writer's id are the same.
1003 virtual std::string header() {
1004 return "@undiredges " + id;
1007 /// \brief Writer function of the section.
1009 /// Write the content of the section.
1010 virtual void write(std::ostream& os) {
1011 for (int i = 0; i < (int)undirEdgeWriters.size(); ++i) {
1012 os << undirEdgeWriters[i].first << ' ';
1013 undirEdgeIdWriter->write(os, *(undirEdgeWriters[i].second));
1016 for (int i = 0; i < (int)edgeWriters.size(); ++i) {
1017 os << edgeWriters[i].first << ' ';
1018 edgeIdWriter->write(os, *(edgeWriters[i].second));
1027 typedef std::vector<std::pair<std::string,
1028 const UndirEdge*> > UndirEdgeWriters;
1029 UndirEdgeWriters undirEdgeWriters;
1030 std::auto_ptr<IdWriterBase<UndirEdge> > undirEdgeIdWriter;
1032 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1033 EdgeWriters edgeWriters;
1034 std::auto_ptr<IdWriterBase<Edge> > edgeIdWriter;
1038 /// \ingroup io_group
1039 /// \brief SectionWriter for attributes.
1041 /// The lemon format can store multiple attribute set. Each set has
1042 /// the header line \c \@attributes \c attributeset_id, but the
1043 /// attributeset_id may be empty.
1045 /// The attributeset section contains several lines. Each of them starts
1046 /// with the name of attribute and then the value.
1048 /// \relates LemonWriter
1049 template <typename _Traits = DefaultWriterTraits>
1050 class AttributeWriter : public CommonSectionWriterBase {
1051 typedef CommonSectionWriterBase Parent;
1052 typedef _Traits Traits;
1054 /// \brief Constructor.
1056 /// Constructor for AttributeWriter. It creates the AttributeWriter and
1057 /// attach it into the given LemonWriter.
1058 AttributeWriter(LemonWriter& _writer,
1059 const std::string& _id = std::string())
1060 : Parent(_writer), id(_id) {}
1062 /// \brief Destructor.
1064 /// Destructor for AttributeWriter.
1065 virtual ~AttributeWriter() {
1066 typename Writers::iterator it;
1067 for (it = writers.begin(); it != writers.end(); ++it) {
1073 AttributeWriter(const AttributeWriter&);
1074 void operator=(AttributeWriter&);
1077 /// \brief Add an attribute writer command for the writer.
1079 /// Add an attribute writer command for the writer.
1080 template <typename Value>
1081 AttributeWriter& writeAttribute(const std::string& id,
1082 const Value& value) {
1084 writeAttribute<typename Traits::template Writer<Value> >(id, value);
1087 /// \brief Add an attribute writer command for the writer.
1089 /// Add an attribute writer command for the writer.
1090 template <typename Writer, typename Value>
1091 AttributeWriter& writeAttribute(const std::string& name,
1093 const Writer& writer = Writer()) {
1094 writers.push_back(make_pair(name, new ValueWriter<Value, Writer>
1101 /// \brief The header of section.
1103 /// It gives back the header of the section.
1104 std::string header() {
1105 return "@attributes " + id;
1108 /// \brief Writer function of the section.
1110 /// Write the content of the section.
1111 void write(std::ostream& os) {
1112 typename Writers::iterator it;
1113 for (it = writers.begin(); it != writers.end(); ++it) {
1114 os << it->first << ' ';
1115 it->second->write(os);
1123 typedef std::vector<std::pair<std::string, ValueWriterBase*> > Writers;