Gettext is needed for bootstrapping.
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/bits/invalid.h>
36 #include <lemon/graph_utils.h>
37 #include <lemon/bits/item_writer.h>
38 #include <lemon/bits/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 lemon_io
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;
318 /// \brief Gives back true when the section should be written.
320 /// Gives back true when the section should be written.
321 virtual bool valid() { return true; }
324 /// \brief Constructor for LemonWriter.
326 /// Constructor for LemonWriter which writes to the given stream.
327 LemonWriter(std::ostream& _os)
328 : os(&_os), own_os(false) {}
330 /// \brief Constructor for LemonWriter.
332 /// Constructor for LemonWriter which writes to the given file.
333 LemonWriter(const std::string& filename)
334 : os(0), own_os(true) {
335 os = new std::ofstream(filename.c_str());
338 /// \brief Desctructor for LemonWriter.
340 /// Desctructor for LemonWriter.
348 LemonWriter(const LemonWriter&);
349 void operator=(const LemonWriter&);
351 void attach(SectionWriter& writer) {
352 writers.push_back(&writer);
357 /// \brief Executes the LemonWriter.
359 /// It executes the LemonWriter.
361 SectionWriters::iterator it;
362 for (it = writers.begin(); it != writers.end(); ++it) {
363 if ((*it)->valid()) {
364 *os << (*it)->header() << std::endl;
368 *os << "@end" << std::endl;
377 typedef std::vector<SectionWriter*> SectionWriters;
378 SectionWriters writers;
382 /// \ingroup section_io
383 /// \brief SectionWriter for writing a graph's nodeset.
385 /// The lemon format can store multiple graph nodesets with several maps.
386 /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but
387 /// the \c nodeset_name may be empty.
389 /// The first line of the section contains the names of the maps separated
390 /// with white spaces. Each next lines describes a node in the nodeset, and
391 /// contains the mapped values for each map.
393 /// If the nodeset contains an \c "label" named map then it will be regarded
394 /// as label map. This map should contain only unique values and when the
395 /// \c writeLabel() member will be called with a node it will write it's
396 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
397 /// then the label map will be the id in the graph.
399 /// \relates LemonWriter
400 template <typename _Graph, typename _Traits = DefaultWriterTraits>
401 class NodeSetWriter : public LemonWriter::SectionWriter {
402 typedef LemonWriter::SectionWriter Parent;
405 typedef _Graph Graph;
406 typedef _Traits Traits;
407 typedef typename Graph::Node Node;
409 /// \brief Constructor.
411 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
412 /// attach it into the given LemonWriter. If the \c _forceLabelMap
413 /// parameter is true then the writer will write own label map when
414 /// the user does not give "label" named map.
415 NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
416 const std::string& _name = std::string(),
417 bool _forceLabelMap = true)
418 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
419 graph(_graph), name(_name) {}
421 /// \brief Destructor.
423 /// Destructor for NodeSetWriter.
424 virtual ~NodeSetWriter() {
425 typename MapWriters::iterator it;
426 for (it = writers.begin(); it != writers.end(); ++it) {
432 NodeSetWriter(const NodeSetWriter&);
433 void operator=(const NodeSetWriter&);
437 /// \brief Add a new node map writer command for the writer.
439 /// Add a new node map writer command for the writer.
440 template <typename Map>
441 NodeSetWriter& writeNodeMap(std::string name, const Map& map) {
442 return writeNodeMap<typename Traits::
443 template Writer<typename Map::Value>, Map>(name, map);
446 /// \brief Add a new node map writer command for the writer.
448 /// Add a new node map writer command for the writer.
449 template <typename Writer, typename Map>
450 NodeSetWriter& writeNodeMap(std::string name, const Map& map,
451 const Writer& writer = Writer()) {
452 checkConcept<concept::ReadMap<Node, typename Map::Value>, Map>();
453 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
455 make_pair(name, new _writer_bits::
456 MapWriter<Node, Map, Writer>(map, writer)));
462 /// \brief The header of the section.
464 /// It gives back the header of the section.
465 virtual std::string header() {
466 return "@nodeset " + name;
469 /// \brief Writer function of the section.
471 /// Write the content of the section.
472 virtual void write(std::ostream& os) {
473 for (int i = 0; i < (int)writers.size(); ++i) {
474 if (writers[i].first == "label") {
475 labelMap = writers[i].second;
476 forceLabelMap = false;
483 for (int i = 0; i < (int)writers.size(); ++i) {
484 os << writers[i].first << '\t';
487 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
489 os << graph.id(it) << '\t';
491 for (int i = 0; i < (int)writers.size(); ++i) {
492 writers[i].second->write(os, it);
501 /// \brief Returns true if the nodeset can write the labels of the nodes.
503 /// Returns true if the nodeset can write the labels of the nodes.
504 /// It is possible only if an "label" named map was written or the
505 /// \c _forceLabelMap constructor parameter was true.
506 bool isLabelWriter() const {
507 return labelMap != 0 || forceLabelMap;
510 /// \brief Write the label of the given node.
512 /// It writes the label of the given node. If there was written an "label"
513 /// named map then it will write the map value belongs to the node.
514 /// Otherwise if the \c forceLabel parameter was true it will write
515 /// its label in the graph.
516 void writeLabel(std::ostream& os, const Node& item) const {
518 os << graph.id(item);
520 labelMap->write(os, item);
526 typedef std::vector<std::pair<std::string, _writer_bits::
527 MapWriterBase<Node>*> > MapWriters;
530 _writer_bits::MapWriterBase<Node>* labelMap;
538 /// \ingroup section_io
539 /// \brief SectionWriter for writing a graph's edgesets.
541 /// The lemon format can store multiple graph edgesets with several maps.
542 /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but
543 /// the \c edgeset_name may be empty.
545 /// The first line of the section contains the names of the maps separated
546 /// with white spaces. Each next lines describes a edge in the edgeset. The
547 /// line contains the source and the target nodes' label and the mapped
548 /// values for each map.
550 /// If the edgeset contains an \c "label" named map then it will be regarded
551 /// as label map. This map should contain only unique values and when the
552 /// \c writeLabel() member will be called with an edge it will write it's
553 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
554 /// then the label map will be the id in the graph.
556 /// The edgeset writer needs a node label writer to identify which nodes
557 /// have to be connected. If a NodeSetWriter can write the nodes' label,
558 /// it will be able to use with this class.
560 /// \relates LemonWriter
561 template <typename _Graph, typename _Traits = DefaultWriterTraits>
562 class EdgeSetWriter : public LemonWriter::SectionWriter {
563 typedef LemonWriter::SectionWriter Parent;
566 typedef _Graph Graph;
567 typedef _Traits Traits;
568 typedef typename Graph::Node Node;
569 typedef typename Graph::Edge Edge;
571 /// \brief Constructor.
573 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter and
574 /// attach it into the given LemonWriter. It will write node labels by
575 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true
576 /// then the writer will write own label map if the user does not give
577 /// "label" named map.
578 template <typename NodeLabelWriter>
579 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
580 const NodeLabelWriter& _nodeLabelWriter,
581 const std::string& _name = std::string(),
582 bool _forceLabelMap = true)
583 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
584 graph(_graph), name(_name) {
585 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
586 nodeLabelWriter.reset(new _writer_bits::
587 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
590 /// \brief Destructor.
592 /// Destructor for EdgeSetWriter.
593 virtual ~EdgeSetWriter() {
594 typename MapWriters::iterator it;
595 for (it = writers.begin(); it != writers.end(); ++it) {
601 EdgeSetWriter(const EdgeSetWriter&);
602 void operator=(const EdgeSetWriter&);
606 /// \brief Add a new edge map writer command for the writer.
608 /// Add a new edge map writer command for the writer.
609 template <typename Map>
610 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
611 return writeEdgeMap<typename Traits::
612 template Writer<typename Map::Value>, Map>(name, map);
615 /// \brief Add a new edge map writer command for the writer.
617 /// Add a new edge map writer command for the writer.
618 template <typename Writer, typename Map>
619 EdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
620 const Writer& writer = Writer()) {
621 checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
622 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
624 make_pair(name, new _writer_bits::
625 MapWriter<Edge, Map, Writer>(map, writer)));
631 /// \brief The header of the section.
633 /// It gives back the header of the section.
634 virtual std::string header() {
635 return "@edgeset " + name;
638 /// \brief Writer function of the section.
640 /// Write the content of the section.
641 virtual void write(std::ostream& os) {
642 if (!nodeLabelWriter->isLabelWriter()) {
643 throw DataFormatError("Cannot find nodeset or label map");
645 for (int i = 0; i < (int)writers.size(); ++i) {
646 if (writers[i].first == "label") {
647 labelMap = writers[i].second;
648 forceLabelMap = false;
656 for (int i = 0; i < (int)writers.size(); ++i) {
657 os << writers[i].first << '\t';
660 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
661 nodeLabelWriter->write(os, graph.source(it));
663 nodeLabelWriter->write(os, graph.target(it));
666 os << graph.id(it) << '\t';
668 for (int i = 0; i < (int)writers.size(); ++i) {
669 writers[i].second->write(os, it);
678 /// \brief Returns true if the edgeset can write the labels of the edges.
680 /// Returns true if the edgeset can write the labels of the edges.
681 /// It is possible only if an "label" named map was written or the
682 /// \c _forceLabelMap constructor parameter was true.
683 bool isLabelWriter() const {
684 return forceLabelMap || labelMap != 0;
687 /// \brief Write the label of the given edge.
689 /// It writes the label of the given edge. If there was written an "label"
690 /// named map then it will write the map value belongs to the edge.
691 /// Otherwise if the \c forceLabel parameter was true it will write
692 /// its label in the graph.
693 void writeLabel(std::ostream& os, const Edge& item) const {
695 os << graph.id(item);
697 labelMap->write(os, item);
703 typedef std::vector<std::pair<std::string, _writer_bits::
704 MapWriterBase<Edge>*> > MapWriters;
707 _writer_bits::MapWriterBase<Edge>* labelMap;
713 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
716 /// \ingroup section_io
717 /// \brief SectionWriter for writing a undirected edgeset.
719 /// The lemon format can store multiple undirected edgesets with several
720 /// maps. The undirected edgeset section's header line is \c \@uedgeset
721 /// \c uedgeset_name, but the \c uedgeset_name may be empty.
723 /// The first line of the section contains the names of the maps separated
724 /// with white spaces. Each next lines describes an undirected edge in the
725 /// edgeset. The line contains the two connected nodes' label and the mapped
726 /// values for each undirected map.
728 /// The section can handle the directed as a syntactical sugar. Two
729 /// undirected edge map describes one directed edge map. This two maps
730 /// are the forward map and the backward map and the names of this map
731 /// is near the same just with a prefix \c '+' or \c '-' character
734 /// If the edgeset contains an \c "label" named map then it will be regarded
735 /// as label map. This map should contain only unique values and when the
736 /// \c writeLabel() member will be called with an undirected edge it will
737 /// write it's label. Otherwise if the \c _forceLabelMap constructor
738 /// parameter is true then the label map will be the id in the graph.
740 /// The undirected edgeset writer needs a node label writer to identify
741 /// which nodes have to be connected. If a NodeSetWriter can write the
742 /// nodes' label, it will be able to use with this class.
744 /// \relates LemonWriter
745 template <typename _Graph, typename _Traits = DefaultWriterTraits>
746 class UEdgeSetWriter : public LemonWriter::SectionWriter {
747 typedef LemonWriter::SectionWriter Parent;
750 typedef _Graph Graph;
751 typedef _Traits Traits;
752 typedef typename Graph::Node Node;
753 typedef typename Graph::Edge Edge;
754 typedef typename Graph::UEdge UEdge;
756 /// \brief Constructor.
758 /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
759 /// and attach it into the given LemonWriter. It will write node labels by
760 /// the \c _nodeLabelWriter. If the \c _forceLabelMap parameter is true
761 /// then the writer will write own label map if the user does not give
762 /// "label" named map.
763 template <typename NodeLabelWriter>
764 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
765 const NodeLabelWriter& _nodeLabelWriter,
766 const std::string& _name = std::string(),
767 bool _forceLabelMap = true)
768 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
769 graph(_graph), name(_name) {
770 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
771 nodeLabelWriter.reset(new _writer_bits::
772 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
775 /// \brief Destructor.
777 /// Destructor for UEdgeSetWriter.
778 virtual ~UEdgeSetWriter() {
779 typename MapWriters::iterator it;
780 for (it = writers.begin(); it != writers.end(); ++it) {
786 UEdgeSetWriter(const UEdgeSetWriter&);
787 void operator=(const UEdgeSetWriter&);
791 /// \brief Add a new undirected edge map writer command for the writer.
793 /// Add a new undirected map writer command for the writer.
794 template <typename Map>
795 UEdgeSetWriter& writeUEdgeMap(std::string name, const Map& map) {
796 return writeUEdgeMap<typename Traits::
797 template Writer<typename Map::Value>, Map>(name, map);
800 /// \brief Add a new undirected map writer command for the writer.
802 /// Add a new undirected map writer command for the writer.
803 template <typename Writer, typename Map>
804 UEdgeSetWriter& writeUEdgeMap(std::string name, const Map& map,
805 const Writer& writer = Writer()) {
806 checkConcept<concept::ReadMap<UEdge, typename Map::Value>, Map>();
807 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
809 make_pair(name, new _writer_bits::
810 MapWriter<UEdge, Map, Writer>(map, writer)));
814 /// \brief Add a new directed edge map writer command for the writer.
816 /// Add a new directed map writer command for the writer.
817 template <typename Map>
818 UEdgeSetWriter& writeEdgeMap(std::string name, const Map& map) {
819 return writeEdgeMap<typename Traits::
820 template Writer<typename Map::Value>, Map>(name, map);
823 /// \brief Add a new directed map writer command for the writer.
825 /// Add a new directed map writer command for the writer.
826 template <typename Writer, typename Map>
827 UEdgeSetWriter& writeEdgeMap(std::string name, const Map& map,
828 const Writer& writer = Writer()) {
829 checkConcept<concept::ReadMap<Edge, typename Map::Value>, Map>();
830 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, Writer>();
831 writeUEdge("+" + name,
832 _writer_bits::forwardComposeMap(graph, map), writer);
833 writeUEdge("-" + name,
834 _writer_bits::backwardComposeMap(graph, map), writer);
840 /// \brief The header of the section.
842 /// It gives back the header of the section.
843 virtual std::string header() {
844 return "@uedgeset " + name;
847 /// \brief Writer function of the section.
849 /// Write the content of the section.
850 virtual void write(std::ostream& os) {
851 if (!nodeLabelWriter->isLabelWriter()) {
852 throw DataFormatError("Cannot find nodeset or label map");
854 for (int i = 0; i < (int)writers.size(); ++i) {
855 if (writers[i].first == "label") {
856 labelMap = writers[i].second;
857 forceLabelMap = false;
865 for (int i = 0; i < (int)writers.size(); ++i) {
866 os << writers[i].first << '\t';
869 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
870 nodeLabelWriter->write(os, graph.source(it));
872 nodeLabelWriter->write(os, graph.target(it));
875 os << graph.id(it) << '\t';
877 for (int i = 0; i < (int)writers.size(); ++i) {
878 writers[i].second->write(os, it);
887 /// \brief Returns true if the undirected edgeset can write the labels of
890 /// Returns true if the undirected edgeset can write the labels of the
891 /// undirected edges. It is possible only if an "label" named map was
892 /// written or the \c _forceLabelMap constructor parameter was true.
893 bool isLabelWriter() const {
894 return forceLabelMap || labelMap != 0;
897 /// \brief Write the label of the given undirected edge.
899 /// It writes the label of the given undirected edge. If there was written
900 /// an "label" named map then it will write the map value belongs to the
901 /// undirected edge. Otherwise if the \c forceLabel parameter was true it
902 /// will write its id in the graph.
903 void writeLabel(std::ostream& os, const UEdge& item) const {
905 os << graph.id(item);
907 labelMap->write(os, item);
911 /// \brief Write the label of the given edge.
913 /// It writes the label of the given edge. If there was written
914 /// an "label" named map then it will write the map value belongs to the
915 /// edge. Otherwise if the \c forceLabel parameter was true it
916 /// will write its id in the graph. If the edge is forward map
917 /// then its prefix character is \c '+' elsewhere \c '-'.
918 void writeLabel(std::ostream& os, const Edge& item) const {
919 if (graph.direction(item)) {
925 os << graph.id(item);
927 labelMap->write(os, item);
933 typedef std::vector<std::pair<std::string, _writer_bits::
934 MapWriterBase<UEdge>*> > MapWriters;
937 _writer_bits::MapWriterBase<UEdge>* labelMap;
943 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
946 /// \ingroup section_io
947 /// \brief SectionWriter for writing named nodes.
949 /// The nodes section's header line is \c \@nodes \c nodes_name, but the
950 /// \c nodes_name may be empty.
952 /// Each line in the section contains the name of the node and
953 /// then the node label.
955 /// \relates LemonWriter
956 template <typename _Graph>
957 class NodeWriter : public LemonWriter::SectionWriter {
958 typedef LemonWriter::SectionWriter Parent;
959 typedef _Graph Graph;
960 typedef typename Graph::Node Node;
963 /// \brief Constructor.
965 /// Constructor for NodeWriter. It creates the NodeWriter and
966 /// attach it into the given LemonWriter. The given \c _LabelWriter
967 /// will write the nodes' label what can be a nodeset writer.
968 template <typename _LabelWriter>
969 NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
970 const std::string& _name = std::string())
971 : Parent(_writer), name(_name) {
972 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
973 labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
978 /// \brief Destructor.
980 /// Destructor for NodeWriter.
981 virtual ~NodeWriter() {}
984 NodeWriter(const NodeWriter&);
985 void operator=(const NodeWriter&);
989 /// \brief Add a node writer command for the NodeWriter.
991 /// Add a node writer command for the NodeWriter.
992 void writeNode(const std::string& name, const Node& item) {
993 writers.push_back(make_pair(name, &item));
998 /// \brief The header of the section.
1000 /// It gives back the header of the section.
1001 virtual std::string header() {
1002 return "@nodes " + name;
1005 /// \brief Writer function of the section.
1007 /// Write the content of the section.
1008 virtual void write(std::ostream& os) {
1009 if (!labelWriter->isLabelWriter()) {
1010 throw DataFormatError("Cannot find nodeset or label map");
1012 for (int i = 0; i < (int)writers.size(); ++i) {
1013 os << writers[i].first << ' ';
1014 labelWriter->write(os, *(writers[i].second));
1019 /// \brief Gives back true when the section should be written.
1021 /// Gives back true when the section should be written.
1022 virtual bool valid() { return !writers.empty(); }
1028 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1029 NodeWriters writers;
1030 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1033 /// \ingroup section_io
1034 /// \brief SectionWriter for writing named edges.
1036 /// The edges section's header line is \c \@edges \c edges_name, but the
1037 /// \c edges_name may be empty.
1039 /// Each line in the section contains the name of the edge and
1040 /// then the edge label.
1042 /// \relates LemonWriter
1043 template <typename _Graph>
1044 class EdgeWriter : public LemonWriter::SectionWriter {
1045 typedef LemonWriter::SectionWriter Parent;
1046 typedef _Graph Graph;
1047 typedef typename Graph::Edge Edge;
1050 /// \brief Constructor.
1052 /// Constructor for EdgeWriter. It creates the EdgeWriter and
1053 /// attach it into the given LemonWriter. The given \c _LabelWriter
1054 /// will write the edges' label what can be a edgeset writer.
1055 template <typename _LabelWriter>
1056 EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1057 const std::string& _name = std::string())
1058 : Parent(_writer), name(_name) {
1059 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1060 labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
1063 /// \brief Destructor.
1065 /// Destructor for EdgeWriter.
1066 virtual ~EdgeWriter() {}
1068 EdgeWriter(const EdgeWriter&);
1069 void operator=(const EdgeWriter&);
1073 /// \brief Add an edge writer command for the EdgeWriter.
1075 /// Add an edge writer command for the EdgeWriter.
1076 void writeEdge(const std::string& name, const Edge& item) {
1077 writers.push_back(make_pair(name, &item));
1082 /// \brief The header of the section.
1084 /// It gives back the header of the section.
1085 virtual std::string header() {
1086 return "@edges " + name;
1089 /// \brief Writer function of the section.
1091 /// Write the content of the section.
1092 virtual void write(std::ostream& os) {
1093 if (!labelWriter->isLabelWriter()) {
1094 throw DataFormatError("Cannot find edgeset or label map");
1096 for (int i = 0; i < (int)writers.size(); ++i) {
1097 os << writers[i].first << ' ';
1098 labelWriter->write(os, *(writers[i].second));
1103 /// \brief Gives back true when the section should be written.
1105 /// Gives back true when the section should be written.
1106 virtual bool valid() { return !writers.empty(); }
1112 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1113 EdgeWriters writers;
1115 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1118 /// \ingroup section_io
1119 /// \brief SectionWriter for writing named undirected edges.
1121 /// The undirected edges section's header line is \c \@uedges
1122 /// \c uedges_name, but the \c uedges_name may be empty.
1124 /// Each line in the section contains the name of the undirected edge and
1125 /// then the undirected edge label.
1127 /// \relates LemonWriter
1128 template <typename _Graph>
1129 class UEdgeWriter : public LemonWriter::SectionWriter {
1130 typedef LemonWriter::SectionWriter Parent;
1131 typedef _Graph Graph;
1132 typedef typename Graph::Node Node;
1133 typedef typename Graph::Edge Edge;
1134 typedef typename Graph::UEdge UEdge;
1137 /// \brief Constructor.
1139 /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
1140 /// attach it into the given LemonWriter. The given \c _LabelWriter
1141 /// will write the undirected edges' label what can be an undirected
1143 template <typename _LabelWriter>
1144 UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1145 const std::string& _name = std::string())
1146 : Parent(_writer), name(_name) {
1147 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1148 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1149 uEdgeLabelWriter.reset(new _writer_bits::
1150 LabelWriter<UEdge, _LabelWriter>(_labelWriter));
1151 edgeLabelWriter.reset(new _writer_bits::
1152 LabelWriter<Edge, _LabelWriter>(_labelWriter));
1155 /// \brief Destructor.
1157 /// Destructor for UEdgeWriter.
1158 virtual ~UEdgeWriter() {}
1160 UEdgeWriter(const UEdgeWriter&);
1161 void operator=(const UEdgeWriter&);
1165 /// \brief Add an edge writer command for the UEdgeWriter.
1167 /// Add an edge writer command for the UEdgeWriter.
1168 void writeEdge(const std::string& name, const Edge& item) {
1169 edgeWriters.push_back(make_pair(name, &item));
1172 /// \brief Add an undirected edge writer command for the UEdgeWriter.
1174 /// Add an undirected edge writer command for the UEdgeWriter.
1175 void writeUEdge(const std::string& name, const UEdge& item) {
1176 uEdgeWriters.push_back(make_pair(name, &item));
1181 /// \brief The header of the section.
1183 /// It gives back the header of the section.
1184 virtual std::string header() {
1185 return "@uedges " + name;
1188 /// \brief Writer function of the section.
1190 /// Write the content of the section.
1191 virtual void write(std::ostream& os) {
1192 if (!edgeLabelWriter->isLabelWriter()) {
1193 throw DataFormatError("Cannot find undirected edgeset or label map");
1195 if (!uEdgeLabelWriter->isLabelWriter()) {
1196 throw DataFormatError("Cannot find undirected edgeset or label map");
1198 for (int i = 0; i < (int)uEdgeWriters.size(); ++i) {
1199 os << uEdgeWriters[i].first << ' ';
1200 uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
1203 for (int i = 0; i < (int)edgeWriters.size(); ++i) {
1204 os << edgeWriters[i].first << ' ';
1205 edgeLabelWriter->write(os, *(edgeWriters[i].second));
1210 /// \brief Gives back true when the section should be written.
1212 /// Gives back true when the section should be written.
1213 virtual bool valid() {
1214 return !uEdgeWriters.empty() || !edgeWriters.empty();
1221 typedef std::vector<std::pair<std::string,
1222 const UEdge*> > UEdgeWriters;
1223 UEdgeWriters uEdgeWriters;
1224 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
1226 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1227 EdgeWriters edgeWriters;
1228 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
1232 /// \ingroup section_io
1233 /// \brief SectionWriter for attributes.
1235 /// The lemon format can store multiple attribute set. Each set has
1236 /// the header line \c \@attributes \c attributes_name, but the
1237 /// attributeset_name may be empty.
1239 /// The attributeset section contains several lines. Each of them starts
1240 /// with the name of attribute and then the value.
1242 /// \relates LemonWriter
1243 template <typename _Traits = DefaultWriterTraits>
1244 class AttributeWriter : public LemonWriter::SectionWriter {
1245 typedef LemonWriter::SectionWriter Parent;
1246 typedef _Traits Traits;
1248 /// \brief Constructor.
1250 /// Constructor for AttributeWriter. It creates the AttributeWriter and
1251 /// attach it into the given LemonWriter.
1252 AttributeWriter(LemonWriter& _writer,
1253 const std::string& _name = std::string())
1254 : Parent(_writer), name(_name) {}
1256 /// \brief Destructor.
1258 /// Destructor for AttributeWriter.
1259 virtual ~AttributeWriter() {
1260 typename Writers::iterator it;
1261 for (it = writers.begin(); it != writers.end(); ++it) {
1267 AttributeWriter(const AttributeWriter&);
1268 void operator=(AttributeWriter&);
1271 /// \brief Add an attribute writer command for the writer.
1273 /// Add an attribute writer command for the writer.
1274 template <typename Value>
1275 AttributeWriter& writeAttribute(const std::string& name,
1276 const Value& value) {
1278 writeAttribute<typename Traits::template Writer<Value> >(name, value);
1281 /// \brief Add an attribute writer command for the writer.
1283 /// Add an attribute writer command for the writer.
1284 template <typename Writer, typename Value>
1285 AttributeWriter& writeAttribute(const std::string& name,
1287 const Writer& writer = Writer()) {
1288 checkConcept<_writer_bits::ItemWriter<Value>, Writer>();
1289 writers.push_back(make_pair(name, new _writer_bits::
1290 ValueWriter<Value, Writer>(value, writer)));
1296 /// \brief The header of section.
1298 /// It gives back the header of the section.
1299 std::string header() {
1300 return "@attributes " + name;
1303 /// \brief Writer function of the section.
1305 /// Write the content of the section.
1306 void write(std::ostream& os) {
1307 typename Writers::iterator it;
1308 for (it = writers.begin(); it != writers.end(); ++it) {
1309 os << it->first << ' ';
1310 it->second->write(os);
1315 /// \brief Gives back true when the section should be written.
1317 /// Gives back true when the section should be written.
1318 virtual bool valid() { return !writers.empty(); }
1323 typedef std::vector<std::pair<std::string,
1324 _writer_bits::ValueWriterBase*> > Writers;