The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.
The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.
The ResGraphAdaptor is based on this composition.
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;