3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Lemon Format writer.
23 #ifndef LEMON_LEMON_WRITER_H
24 #define LEMON_LEMON_WRITER_H
34 #include <lemon/error.h>
35 #include <lemon/invalid.h>
36 #include <lemon/graph_utils.h>
37 #include <lemon/bits/item_writer.h>
38 #include <lemon/utility.h>
39 #include <lemon/maps.h>
42 #include <lemon/concept_check.h>
43 #include <lemon/concept/maps.h>
48 namespace _writer_bits {
50 template <typename Item>
51 class ItemLabelWriter {
54 bool isLabelWriter() { return true; }
56 void writeLabel(std::ostream&, const Item&) {}
58 template <class _ItemLabelWriter>
61 bool b = writer.isLabelWriter();
62 ignore_unused_variable_warning(b);
63 writer.writeLabel(os, item);
65 _ItemLabelWriter& writer;
72 template <typename Item>
76 void write(std::ostream&, const Item&) {}
78 template <class _ItemWriter>
81 writer.write(os, item);
90 template <typename Map>
91 struct Ref { typedef const Map& Type; };
93 template <typename Graph, typename Map>
94 class ForwardComposeMap {
96 typedef typename Graph::UEdge Key;
97 typedef typename Map::Value Value;
99 ForwardComposeMap(const Graph& _graph, const Map& _map)
100 : graph(_graph), map(_map) {}
102 Value operator[](const Key& key) {
103 return map[graph.direct(key, false)];
107 typename Ref<Map>::Type map;
111 template <typename Graph, typename Map>
112 ForwardComposeMap<Graph, Map>
113 forwardComposeMap(const Graph& graph, const Map& map) {
114 return ForwardComposeMap<Graph, Map>(graph, map);
117 template <typename Graph, typename Map>
118 class BackwardComposeMap {
120 typedef typename Graph::UEdge Key;
121 typedef typename Map::Value Value;
123 BackwardComposeMap(const Graph& _graph, const Map& _map)
124 : graph(_graph), map(_map) {}
126 Value operator[](const Key& key) {
127 return map[graph.direct(key, false)];
131 typename Ref<Map>::Type map;
135 template <typename Graph, typename Map>
136 BackwardComposeMap<Graph, Map>
137 backwardComposeMap(const Graph& graph, const Map& map) {
138 return BackwardComposeMap<Graph, Map>(graph, map);
141 template <typename Graph, typename Map>
142 struct Ref<ForwardComposeMap<Graph, Map> > {
143 typedef ForwardComposeMap<Graph, Map> Type;
146 template <typename Graph, typename Map>
147 struct Ref<BackwardComposeMap<Graph, Map> > {
148 typedef BackwardComposeMap<Graph, Map> Type;
151 template <typename Map>
152 struct Ref<XMap<Map> > {
153 typedef XMap<Map> Type;
155 template <typename Map>
156 struct Ref<ConstXMap<Map> > {
157 typedef ConstXMap<Map> Type;
160 template <typename Map>
161 struct Ref<YMap<Map> > {
162 typedef YMap<Map> Type;
164 template <typename Map>
165 struct Ref<ConstYMap<Map> > {
166 typedef ConstYMap<Map> Type;
170 template <typename _Item>
171 class MapWriterBase {
175 virtual ~MapWriterBase() {}
177 virtual void write(std::ostream& os, const Item& item) const = 0;
181 template <typename _Item, typename _Map, typename _Writer>
182 class MapWriter : public MapWriterBase<_Item> {
185 typedef _Writer Writer;
186 typedef typename Writer::Value Value;
189 typename _writer_bits::Ref<Map>::Type map;
192 MapWriter(const Map& _map, const Writer& _writer)
193 : map(_map), writer(_writer) {}
195 virtual ~MapWriter() {}
197 virtual void write(std::ostream& os, const Item& item) const {
198 Value value = map[item];
199 writer.write(os, value);
205 class ValueWriterBase {
207 virtual ~ValueWriterBase() {}
208 virtual void write(std::ostream&) = 0;
211 template <typename _Value, typename _Writer>
212 class ValueWriter : public ValueWriterBase {
214 typedef _Value Value;
215 typedef _Writer Writer;
217 ValueWriter(const Value& _value, const Writer& _writer)
218 : value(_value), writer(_writer) {}
220 virtual void write(std::ostream& os) {
221 writer.write(os, value);
229 template <typename _Item>
230 class LabelWriterBase {
233 virtual ~LabelWriterBase() {}
234 virtual void write(std::ostream&, const Item&) const = 0;
235 virtual bool isLabelWriter() const = 0;
238 template <typename _Item, typename _BoxedLabelWriter>
239 class LabelWriter : public LabelWriterBase<_Item> {
242 typedef _BoxedLabelWriter BoxedLabelWriter;
244 const BoxedLabelWriter& labelWriter;
246 LabelWriter(const BoxedLabelWriter& _labelWriter)
247 : labelWriter(_labelWriter) {}
249 virtual void write(std::ostream& os, const Item& item) const {
250 labelWriter.writeLabel(os, item);
253 virtual bool isLabelWriter() const {
254 return labelWriter.isLabelWriter();
260 /// \ingroup io_group
261 /// \brief Lemon Format writer class.
263 /// The Lemon Format contains several sections. We do not want to
264 /// determine what sections are in a lemon file we give only a framework
265 /// to write a section oriented format.
267 /// In the Lemon Format each section starts with a line contains a \c \@
268 /// character on the first not white space position. This line is the
269 /// header line of the section. Each next lines belong to this section
270 /// while it does not starts with \c \@ character. This line can start a
271 /// new section or if it can close the file with the \c \@end line.
272 /// The file format ignore the empty lines and it may contain comments
273 /// started with a \c # character to the end of the line.
275 /// The framework provides an abstract LemonWriter::SectionWriter class
276 /// what defines the interface of a SectionWriter. The SectionWriter
277 /// has the \c header() member function what gives back the header of the
278 /// section. After that it will be called the \c write() member which
279 /// should write the content of the section.
281 /// \relates GraphWriter
282 /// \relates NodeSetWriter
283 /// \relates EdgeSetWriter
284 /// \relates NodesWriter
285 /// \relates EdgesWriter
286 /// \relates AttributeWriter
290 /// \brief Abstract base class for writing a section.
292 /// This class has an \c header() member function what gives back
293 /// the header line of the section. The \c write() member should
294 /// write the content of the section to the stream.
295 class SectionWriter {
296 friend class LemonWriter;
298 /// \brief Constructor for SectionWriter.
300 /// Constructor for SectionWriter. It attach this writer to
301 /// the given LemonWriter.
302 SectionWriter(LemonWriter& writer) {
303 writer.attach(*this);
306 virtual ~SectionWriter() {}
308 /// \brief The header of section.
310 /// It gives back the header of the section.
311 virtual std::string header() = 0;
313 /// \brief Writer function of the section.
315 /// Write the content of the section.
316 virtual void write(std::ostream& os) = 0;
319 /// \brief Constructor for LemonWriter.
321 /// Constructor for LemonWriter which writes to the given stream.
322 LemonWriter(std::ostream& _os)
323 : os(&_os), own_os(false) {}
325 /// \brief Constructor for LemonWriter.
327 /// Constructor for LemonWriter which writes to the given file.
328 LemonWriter(const std::string& filename)
329 : os(0), own_os(true) {
330 os = new std::ofstream(filename.c_str());
333 /// \brief Desctructor for LemonWriter.
335 /// Desctructor for LemonWriter.
343 LemonWriter(const LemonWriter&);
344 void operator=(const LemonWriter&);
346 void attach(SectionWriter& writer) {
347 writers.push_back(&writer);
352 /// \brief Executes the LemonWriter.
354 /// It executes the LemonWriter.
356 SectionWriters::iterator it;
357 for (it = writers.begin(); it != writers.end(); ++it) {
358 *os << (*it)->header() << std::endl;
361 *os << "@end" << std::endl;
370 typedef std::vector<SectionWriter*> SectionWriters;
371 SectionWriters writers;
375 /// \ingroup io_group
376 /// \brief SectionWriter for writing a graph's nodeset.
378 /// The lemon format can store multiple graph nodesets with several maps.
379 /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but
380 /// the \c nodeset_name may be empty.
382 /// The first line of the section contains the names of the maps separated
383 /// with white spaces. Each next lines describes a node in the nodeset, and
384 /// contains the mapped values for each map.
386 /// If the nodeset contains an \c "label" named map then it will be regarded
387 /// as label map. This map should contain only unique values and when the
388 /// \c writeLabel() member will be called with a node it will write it's
389 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
390 /// then the label map will be the id in the graph.
392 /// \relates LemonWriter
393 template <typename _Graph, typename _Traits = DefaultWriterTraits>
394 class NodeSetWriter : public LemonWriter::SectionWriter {
395 typedef LemonWriter::SectionWriter Parent;
398 typedef _Graph Graph;
399 typedef _Traits Traits;
400 typedef typename Graph::Node Node;
402 /// \brief Constructor.
404 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
405 /// attach it into the given LemonWriter. If the \c _forceLabelMap
406 /// parameter is true then the writer will write own label map when
407 /// the user does not give "label" named map.
408 NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
409 const std::string& _name = std::string(),
410 bool _forceLabelMap = true)
411 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
412 graph(_graph), name(_name) {}
414 /// \brief Destructor.
416 /// Destructor for NodeSetWriter.
417 virtual ~NodeSetWriter() {
418 typename MapWriters::iterator it;
419 for (it = writers.begin(); it != writers.end(); ++it) {
425 NodeSetWriter(const NodeSetWriter&);
426 void operator=(const NodeSetWriter&);
430 /// \brief Add a new node map writer command for the writer.
432 /// Add a new node map writer command for the writer.
433 template <typename Map>
434 NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
435 return writeNodeMap<typename Traits::
436 template Writer<typename Map::Value>, Map>(name, map);
439 /// \brief Add a new node map writer command for the writer.
441 /// Add a new node map writer command for the writer.
442 template <typename Writer, typename Map>
443 NodeSetWriter& writeNodeMap(std::string name, const Map& map,
444 const Writer& writer = Writer()) {
445 checkConcept<concept::ReadMap<Node, typename Map::Value>, Map>();
446 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
448 make_pair(name, new _writer_bits::
449 MapWriter<Node, Map, Writer>(map, writer)));
455 /// \brief The header of the section.
457 /// It gives back the header of the section.
458 virtual std::string header() {
459 return "@nodeset " + name;
462 /// \brief Writer function of the section.
464 /// Write the content of the section.
465 virtual void write(std::ostream& os) {
466 for (int i = 0; i < (int)writers.size(); ++i) {
467 if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
468 labelMap = writers[i].second;
469 forceLabelMap = false;
476 for (int i = 0; i < (int)writers.size(); ++i) {
477 os << writers[i].first << '\t';
480 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
482 os << graph.id(it) << '\t';
484 for (int i = 0; i < (int)writers.size(); ++i) {
485 writers[i].second->write(os, it);
494 /// \brief Returns true if the nodeset can write the labels of the nodes.
496 /// Returns true if the nodeset can write the labels of the nodes.
497 /// It is possible only if an "label" named map was written or the
498 /// \c _forceLabelMap constructor parameter was true.
499 bool isLabelWriter() const {
500 return labelMap != 0 || forceLabelMap;
503 /// \brief Write the label of the given node.
505 /// It writes the label of the given node. If there was written an "label"
506 /// named map then it will write the map value belongs to the node.
507 /// Otherwise if the \c forceLabel parameter was true it will write
508 /// its label in the graph.
509 void writeLabel(std::ostream& os, const Node& item) const {
511 os << graph.id(item);
513 labelMap->write(os, item);
519 typedef std::vector<std::pair<std::string, _writer_bits::
520 MapWriterBase<Node>*> > MapWriters;
523 _writer_bits::MapWriterBase<Node>* labelMap;
531 /// \ingroup io_group
532 /// \brief SectionWriter for writing a graph's edgesets.
534 /// The lemon format can store multiple graph edgesets with several maps.
535 /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but
536 /// the \c edgeset_name may be empty.
538 /// The first line of the section contains the names of the maps separated
539 /// with white spaces. Each next lines describes a edge in the edgeset. The
540 /// line contains the source and the target nodes' label and the mapped
541 /// values for each map.
543 /// If the edgeset contains an \c "label" named map then it will be regarded
544 /// as label map. This map should contain only unique values and when the
545 /// \c writeLabel() member will be called with an edge it will write it's
546 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
547 /// then the label map will be the id in the graph.
549 /// The edgeset writer needs a node label writer to identify which nodes
550 /// have to be connected. If a NodeSetWriter can write the nodes' label,
551 /// it will be able to use with this class.
553 /// \relates LemonWriter
554 template <typename _Graph, typename _Traits = DefaultWriterTraits>
555 class EdgeSetWriter : public LemonWriter::SectionWriter {
556 typedef LemonWriter::SectionWriter Parent;
559 typedef _Graph Graph;
560 typedef _Traits Traits;
561 typedef typename Graph::Node Node;
562 typedef typename Graph::Edge Edge;
564 /// \brief Constructor.
566 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
567 /// attach it into the given LemonWriter. It will write node labels by
568 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true
569 /// then the writer will write own label map if the user does not give
570 /// "label" named map.
571 template <typename NodeLabelWriter>
572 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
573 const NodeLabelWriter& _nodeLabelWriter,
574 const std::string& _name = std::string(),
575 bool _forceLabelMap = true)
576 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
577 graph(_graph), name(_name) {
578 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
579 nodeLabelWriter.reset(new _writer_bits::
580 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
583 /// \brief Destructor.
585 /// Destructor for EdgeSetWriter.
586 virtual ~EdgeSetWriter() {
587 typename MapWriters::iterator it;
588 for (it = writers.begin(); it != writers.end(); ++it) {
594 EdgeSetWriter(const EdgeSetWriter&);
595 void operator=(const EdgeSetWriter&);
599 /// \brief Add a new edge map writer command for the writer.
601 /// Add a new edge map writer command for the writer.
602 template <typename Map>
603 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
604 return writeEdgeMap<typename Traits::
605 template Writer<typename Map::Value>, Map>(name, map);
608 /// \brief Add a new edge map writer command for the writer.
610 /// Add a new edge map writer command for the writer.
611 template <typename Writer, typename Map>
612 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
613 const Writer& writer = Writer()) {
614 checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
615 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
617 make_pair(name, new _writer_bits::
618 MapWriter<Edge, Map, Writer>(map, writer)));
624 /// \brief The header of the section.
626 /// It gives back the header of the section.
627 virtual std::string header() {
628 return "@edgeset " + name;
631 /// \brief Writer function of the section.
633 /// Write the content of the section.
634 virtual void write(std::ostream& os) {
635 if (!nodeLabelWriter->isLabelWriter()) {
636 throw DataFormatError("Cannot find nodeset or label map");
638 for (int i = 0; i < (int)writers.size(); ++i) {
639 if (writers[i].first == "label" || (writers[i].first == "id" && labelMap == 0)) {
640 labelMap = writers[i].second;
641 forceLabelMap = false;
649 for (int i = 0; i < (int)writers.size(); ++i) {
650 os << writers[i].first << '\t';
653 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
654 nodeLabelWriter->write(os, graph.source(it));
656 nodeLabelWriter->write(os, graph.target(it));
659 os << graph.id(it) << '\t';
661 for (int i = 0; i < (int)writers.size(); ++i) {
662 writers[i].second->write(os, it);
671 /// \brief Returns true if the edgeset can write the labels of the edges.
673 /// Returns true if the edgeset can write the labels of the edges.
674 /// It is possible only if an "label" named map was written or the
675 /// \c _forceLabelMap constructor parameter was true.
676 bool isLabelWriter() const {
677 return forceLabelMap || labelMap != 0;
680 /// \brief Write the label of the given edge.
682 /// It writes the label of the given edge. If there was written an "label"
683 /// named map then it will write the map value belongs to the edge.
684 /// Otherwise if the \c forceLabel parameter was true it will write
685 /// its label in the graph.
686 void writeLabel(std::ostream& os, const Edge& item) const {
688 os << graph.id(item);
690 labelMap->write(os, item);
696 typedef std::vector<std::pair<std::string, _writer_bits::
697 MapWriterBase<Edge>*> > MapWriters;
700 _writer_bits::MapWriterBase<Edge>* labelMap;
706 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
709 /// \ingroup io_group
710 /// \brief SectionWriter for writing a undirected edgeset.
712 /// The lemon format can store multiple undirected edgesets with several
713 /// maps. The undirected edgeset section's header line is \c \@uedgeset
714 /// \c uedgeset_name, but the \c uedgeset_name may be empty.
716 /// The first line of the section contains the names of the maps separated
717 /// with white spaces. Each next lines describes an undirected edge in the
718 /// edgeset. The line contains the two connected nodes' label and the mapped
719 /// values for each undirected map.
721 /// The section can handle the directed as a syntactical sugar. Two
722 /// undirected edge map describes one directed edge map. This two maps
723 /// are the forward map and the backward map and the names of this map
724 /// is near the same just with a prefix \c '+' or \c '-' character
727 /// If the edgeset contains an \c "label" named map then it will be regarded
728 /// as label map. This map should contain only unique values and when the
729 /// \c writeLabel() member will be called with an undirected edge it will
730 /// write it's label. Otherwise if the \c _forceLabelMap constructor
731 /// parameter is true then the label map will be the id in the graph.
733 /// The undirected edgeset writer needs a node label writer to identify
734 /// which nodes have to be connected. If a NodeSetWriter can write the
735 /// nodes' label, it will be able to use with this class.
737 /// \relates LemonWriter
738 template <typename _Graph, typename _Traits = DefaultWriterTraits>
739 class UEdgeSetWriter : public LemonWriter::SectionWriter {
740 typedef LemonWriter::SectionWriter Parent;
743 typedef _Graph Graph;
744 typedef _Traits Traits;
745 typedef typename Graph::Node Node;
746 typedef typename Graph::Edge Edge;
747 typedef typename Graph::UEdge UEdge;
749 /// \brief Constructor.
751 /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
752 /// and attach it into the given LemonWriter. It will write node labels by
753 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true
754 /// then the writer will write own label map if the user does not give
755 /// "label" named map.
756 template <typename NodeLabelWriter>
757 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
758 const NodeLabelWriter& _nodeLabelWriter,
759 const std::string& _name = std::string(),
760 bool _forceLabelMap = true)
761 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
762 graph(_graph), name(_name) {
763 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
764 nodeLabelWriter.reset(new _writer_bits::
765 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
768 /// \brief Destructor.
770 /// Destructor for UEdgeSetWriter.
771 virtual ~UEdgeSetWriter() {
772 typename MapWriters::iterator it;
773 for (it = writers.begin(); it != writers.end(); ++it) {
779 UEdgeSetWriter(const UEdgeSetWriter&);
780 void operator=(const UEdgeSetWriter&);
784 /// \brief Add a new undirected edge map writer command for the writer.
786 /// Add a new undirected map writer command for the writer.
787 template <typename Map>
788 UEdgeSetWriter& writeUEdgeMap(std::string name, const Map& map) {
789 return writeUEdgeMap<typename Traits::
790 template Writer<typename Map::Value>, Map>(name, map);
793 /// \brief Add a new undirected map writer command for the writer.
795 /// Add a new undirected map writer command for the writer.
796 template <typename Writer, typename Map>
797 UEdgeSetWriter& writeUEdgeMap(std::string name, const Map& map,
798 const Writer& writer = Writer()) {
799 checkConcept<concept::ReadMap<UEdge, typename Map::Value>, Map>();
800 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
802 make_pair(name, new _writer_bits::
803 MapWriter<UEdge, Map, Writer>(map, writer)));
807 /// \brief Add a new directed edge map writer command for the writer.
809 /// Add a new directed map writer command for the writer.
810 template <typename Map>
811 UEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
812 return writeEdgeMap<typename Traits::
813 template Writer<typename Map::Value>, Map>(name, map);
816 /// \brief Add a new directed map writer command for the writer.
818 /// Add a new directed map writer command for the writer.
819 template <typename Writer, typename Map>
820 UEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
821 const Writer& writer = Writer()) {
822 checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
823 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
824 writeUEdge("+" + name,
825 _writer_bits::forwardComposeMap(graph, map), writer);
826 writeUEdge("-" + name,
827 _writer_bits::backwardComposeMap(graph, map), writer);
833 /// \brief The header of the section.
835 /// It gives back the header of the section.
836 virtual std::string header() {
837 return "@uedgeset " + name;
840 /// \brief Writer function of the section.
842 /// Write the content of the section.
843 virtual void write(std::ostream& os) {
844 if (!nodeLabelWriter->isLabelWriter()) {
845 throw DataFormatError("Cannot find nodeset or label map");
847 for (int i = 0; i < (int)writers.size(); ++i) {
848 if (writers[i].first == "label") {
849 labelMap = writers[i].second;
850 forceLabelMap = false;
858 for (int i = 0; i < (int)writers.size(); ++i) {
859 os << writers[i].first << '\t';
862 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
863 nodeLabelWriter->write(os, graph.source(it));
865 nodeLabelWriter->write(os, graph.target(it));
868 os << graph.id(it) << '\t';
870 for (int i = 0; i < (int)writers.size(); ++i) {
871 writers[i].second->write(os, it);
880 /// \brief Returns true if the undirected edgeset can write the labels of
883 /// Returns true if the undirected edgeset can write the labels of the
884 /// undirected edges. It is possible only if an "label" named map was
885 /// written or the \c _forceLabelMap constructor parameter was true.
886 bool isLabelWriter() const {
887 return forceLabelMap || labelMap != 0;
890 /// \brief Write the label of the given undirected edge.
892 /// It writes the label of the given undirected edge. If there was written
893 /// an "label" named map then it will write the map value belongs to the
894 /// undirected edge. Otherwise if the \c forceLabel parameter was true it
895 /// will write its id in the graph.
896 void writeLabel(std::ostream& os, const UEdge& item) const {
898 os << graph.id(item);
900 labelMap->write(os, item);
904 /// \brief Write the label of the given edge.
906 /// It writes the label of the given edge. If there was written
907 /// an "label" named map then it will write the map value belongs to the
908 /// edge. Otherwise if the \c forceLabel parameter was true it
909 /// will write its id in the graph. If the edge is forward map
910 /// then its prefix character is \c '+' elsewhere \c '-'.
911 void writeLabel(std::ostream& os, const Edge& item) const {
912 if (graph.direction(item)) {
918 os << graph.id(item);
920 labelMap->write(os, item);
926 typedef std::vector<std::pair<std::string, _writer_bits::
927 MapWriterBase<UEdge>*> > MapWriters;
930 _writer_bits::MapWriterBase<UEdge>* labelMap;
936 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
939 /// \ingroup io_group
940 /// \brief SectionWriter for writing named nodes.
942 /// The nodes section's header line is \c \@nodes \c nodes_name, but the
943 /// \c nodes_name may be empty.
945 /// Each line in the section contains the name of the node and
946 /// then the node label.
948 /// \relates LemonWriter
949 template <typename _Graph>
950 class NodeWriter : public LemonWriter::SectionWriter {
951 typedef LemonWriter::SectionWriter Parent;
952 typedef _Graph Graph;
953 typedef typename Graph::Node Node;
956 /// \brief Constructor.
958 /// Constructor for NodeWriter. It creates the NodeWriter and
959 /// attach it into the given LemonWriter. The given \c _LabelWriter
960 /// will write the nodes' label what can be a nodeset writer.
961 template <typename _LabelWriter>
962 NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
963 const std::string& _name = std::string())
964 : Parent(_writer), name(_name) {
965 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
966 labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
971 /// \brief Destructor.
973 /// Destructor for NodeWriter.
974 virtual ~NodeWriter() {}
977 NodeWriter(const NodeWriter&);
978 void operator=(const NodeWriter&);
982 /// \brief Add a node writer command for the NodeWriter.
984 /// Add a node writer command for the NodeWriter.
985 void writeNode(const std::string& name, const Node& item) {
986 writers.push_back(make_pair(name, &item));
991 /// \brief The header of the section.
993 /// It gives back the header of the section.
994 virtual std::string header() {
995 return "@nodes " + name;
998 /// \brief Writer function of the section.
1000 /// Write the content of the section.
1001 virtual void write(std::ostream& os) {
1002 if (!labelWriter->isLabelWriter()) {
1003 throw DataFormatError("Cannot find nodeset or label map");
1005 for (int i = 0; i < (int)writers.size(); ++i) {
1006 os << writers[i].first << ' ';
1007 labelWriter->write(os, *(writers[i].second));
1016 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1017 NodeWriters writers;
1018 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1021 /// \ingroup io_group
1022 /// \brief SectionWriter for writing named edges.
1024 /// The edges section's header line is \c \@edges \c edges_name, but the
1025 /// \c edges_name may be empty.
1027 /// Each line in the section contains the name of the edge and
1028 /// then the edge label.
1030 /// \relates LemonWriter
1031 template <typename _Graph>
1032 class EdgeWriter : public LemonWriter::SectionWriter {
1033 typedef LemonWriter::SectionWriter Parent;
1034 typedef _Graph Graph;
1035 typedef typename Graph::Edge Edge;
1038 /// \brief Constructor.
1040 /// Constructor for EdgeWriter. It creates the EdgeWriter and
1041 /// attach it into the given LemonWriter. The given \c _LabelWriter
1042 /// will write the edges' label what can be a edgeset writer.
1043 template <typename _LabelWriter>
1044 EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1045 const std::string& _name = std::string())
1046 : Parent(_writer), name(_name) {
1047 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1048 labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
1051 /// \brief Destructor.
1053 /// Destructor for EdgeWriter.
1054 virtual ~EdgeWriter() {}
1056 EdgeWriter(const EdgeWriter&);
1057 void operator=(const EdgeWriter&);
1061 /// \brief Add an edge writer command for the EdgeWriter.
1063 /// Add an edge writer command for the EdgeWriter.
1064 void writeEdge(const std::string& name, const Edge& item) {
1065 writers.push_back(make_pair(name, &item));
1070 /// \brief The header of the section.
1072 /// It gives back the header of the section.
1073 virtual std::string header() {
1074 return "@edges " + name;
1077 /// \brief Writer function of the section.
1079 /// Write the content of the section.
1080 virtual void write(std::ostream& os) {
1081 if (!labelWriter->isLabelWriter()) {
1082 throw DataFormatError("Cannot find edgeset or label map");
1084 for (int i = 0; i < (int)writers.size(); ++i) {
1085 os << writers[i].first << ' ';
1086 labelWriter->write(os, *(writers[i].second));
1095 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1096 EdgeWriters writers;
1098 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1101 /// \ingroup io_group
1102 /// \brief SectionWriter for writing named undirected edges.
1104 /// The undirected edges section's header line is \c \@uedges
1105 /// \c uedges_name, but the \c uedges_name may be empty.
1107 /// Each line in the section contains the name of the undirected edge and
1108 /// then the undirected edge label.
1110 /// \relates LemonWriter
1111 template <typename _Graph>
1112 class UEdgeWriter : public LemonWriter::SectionWriter {
1113 typedef LemonWriter::SectionWriter Parent;
1114 typedef _Graph Graph;
1115 typedef typename Graph::Node Node;
1116 typedef typename Graph::Edge Edge;
1117 typedef typename Graph::UEdge UEdge;
1120 /// \brief Constructor.
1122 /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
1123 /// attach it into the given LemonWriter. The given \c _LabelWriter
1124 /// will write the undirected edges' label what can be an undirected
1126 template <typename _LabelWriter>
1127 UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1128 const std::string& _name = std::string())
1129 : Parent(_writer), name(_name) {
1130 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1131 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1132 uEdgeLabelWriter.reset(new _writer_bits::
1133 LabelWriter<UEdge, _LabelWriter>(_labelWriter));
1134 edgeLabelWriter.reset(new _writer_bits::
1135 LabelWriter<Edge, _LabelWriter>(_labelWriter));
1138 /// \brief Destructor.
1140 /// Destructor for UEdgeWriter.
1141 virtual ~UEdgeWriter() {}
1143 UEdgeWriter(const UEdgeWriter&);
1144 void operator=(const UEdgeWriter&);
1148 /// \brief Add an edge writer command for the UEdgeWriter.
1150 /// Add an edge writer command for the UEdgeWriter.
1151 void writeEdge(const std::string& name, const Edge& item) {
1152 edgeWriters.push_back(make_pair(name, &item));
1155 /// \brief Add an undirected edge writer command for the UEdgeWriter.
1157 /// Add an undirected edge writer command for the UEdgeWriter.
1158 void writeUEdge(const std::string& name, const UEdge& item) {
1159 uEdgeWriters.push_back(make_pair(name, &item));
1164 /// \brief The header of the section.
1166 /// It gives back the header of the section.
1167 virtual std::string header() {
1168 return "@uedges " + name;
1171 /// \brief Writer function of the section.
1173 /// Write the content of the section.
1174 virtual void write(std::ostream& os) {
1175 if (!edgeLabelWriter->isLabelWriter()) {
1176 throw DataFormatError("Cannot find undirected edgeset or label map");
1178 if (!uEdgeLabelWriter->isLabelWriter()) {
1179 throw DataFormatError("Cannot find undirected edgeset or label map");
1181 for (int i = 0; i < (int)uEdgeWriters.size(); ++i) {
1182 os << uEdgeWriters[i].first << ' ';
1183 uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
1186 for (int i = 0; i < (int)edgeWriters.size(); ++i) {
1187 os << edgeWriters[i].first << ' ';
1188 edgeLabelWriter->write(os, *(edgeWriters[i].second));
1197 typedef std::vector<std::pair<std::string,
1198 const UEdge*> > UEdgeWriters;
1199 UEdgeWriters uEdgeWriters;
1200 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
1202 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1203 EdgeWriters edgeWriters;
1204 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
1208 /// \ingroup io_group
1209 /// \brief SectionWriter for attributes.
1211 /// The lemon format can store multiple attribute set. Each set has
1212 /// the header line \c \@attributes \c attributes_name, but the
1213 /// attributeset_name may be empty.
1215 /// The attributeset section contains several lines. Each of them starts
1216 /// with the name of attribute and then the value.
1218 /// \relates LemonWriter
1219 template <typename _Traits = DefaultWriterTraits>
1220 class AttributeWriter : public LemonWriter::SectionWriter {
1221 typedef LemonWriter::SectionWriter Parent;
1222 typedef _Traits Traits;
1224 /// \brief Constructor.
1226 /// Constructor for AttributeWriter. It creates the AttributeWriter and
1227 /// attach it into the given LemonWriter.
1228 AttributeWriter(LemonWriter& _writer,
1229 const std::string& _name = std::string())
1230 : Parent(_writer), name(_name) {}
1232 /// \brief Destructor.
1234 /// Destructor for AttributeWriter.
1235 virtual ~AttributeWriter() {
1236 typename Writers::iterator it;
1237 for (it = writers.begin(); it != writers.end(); ++it) {
1243 AttributeWriter(const AttributeWriter&);
1244 void operator=(AttributeWriter&);
1247 /// \brief Add an attribute writer command for the writer.
1249 /// Add an attribute writer command for the writer.
1250 template <typename Value>
1251 AttributeWriter& writeAttribute(const std::string& name,
1252 const Value& value) {
1254 writeAttribute<typename Traits::template Writer<Value> >(name, value);
1257 /// \brief Add an attribute writer command for the writer.
1259 /// Add an attribute writer command for the writer.
1260 template <typename Writer, typename Value>
1261 AttributeWriter& writeAttribute(const std::string& name,
1263 const Writer& writer = Writer()) {
1264 checkConcept<_writer_bits::ItemWriter<Value>, Writer>();
1265 writers.push_back(make_pair(name, new _writer_bits::
1266 ValueWriter<Value, Writer>(value, writer)));
1272 /// \brief The header of section.
1274 /// It gives back the header of the section.
1275 std::string header() {
1276 return "@attributes " + name;
1279 /// \brief Writer function of the section.
1281 /// Write the content of the section.
1282 void write(std::ostream& os) {
1283 typename Writers::iterator it;
1284 for (it = writers.begin(); it != writers.end(); ++it) {
1285 os << it->first << ' ';
1286 it->second->write(os);
1294 typedef std::vector<std::pair<std::string,
1295 _writer_bits::ValueWriterBase*> > Writers;