3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2007
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>
40 #include <lemon/dim2.h>
42 #include <lemon/concept_check.h>
43 #include <lemon/concepts/maps.h>
48 namespace _writer_bits {
51 bool operator<(T, T) {
52 throw DataFormatError("Label is not comparable");
57 bool operator()(const T& p, const T& q) const {
62 template <typename Map>
64 ComposeLess(const Map& _map) : map(_map), less() {}
66 bool operator()(const typename Map::Key& p,
67 const typename Map::Key& q) const {
68 return less(map[p], map[q]);
71 Less<typename Map::Value> less;
74 template <typename UGraph, typename Map>
75 struct UEdgeComposeLess {
76 UEdgeComposeLess(const UGraph& _ugraph, const Map& _map)
77 : ugraph(_ugraph), map(_map), less() {}
79 bool operator()(const typename UGraph::Edge& p,
80 const typename UGraph::Edge& q) const {
81 return p != q ? less(map[p], map[q]) :
82 (!ugraph.direction(p) && ugraph.direction(q));
87 Less<typename Map::Value> less;
90 template <typename Item>
91 class ItemLabelWriter {
94 bool isLabelWriter() { return true; }
96 void writeLabel(std::ostream&, const Item&) {}
98 template <class _ItemLabelWriter>
101 bool b = writer.isLabelWriter();
102 ignore_unused_variable_warning(b);
103 writer.writeLabel(os, item);
105 _ItemLabelWriter& writer;
112 template <typename Item>
116 void write(std::ostream&, const Item&) {}
118 template <class _ItemWriter>
121 writer.write(os, item);
130 template <typename Map>
131 struct Ref { typedef const Map& Type; };
133 template <typename Graph, typename Map>
134 class ForwardComposeMap {
136 typedef typename Graph::UEdge Key;
137 typedef typename Map::Value Value;
139 ForwardComposeMap(const Graph& _graph, const Map& _map)
140 : graph(_graph), map(_map) {}
142 Value operator[](const Key& key) const {
143 return map[graph.direct(key, true)];
147 typename Ref<Map>::Type map;
151 template <typename Graph, typename Map>
152 ForwardComposeMap<Graph, Map>
153 forwardComposeMap(const Graph& graph, const Map& map) {
154 return ForwardComposeMap<Graph, Map>(graph, map);
157 template <typename Graph, typename Map>
158 class BackwardComposeMap {
160 typedef typename Graph::UEdge Key;
161 typedef typename Map::Value Value;
163 BackwardComposeMap(const Graph& _graph, const Map& _map)
164 : graph(_graph), map(_map) {}
166 Value operator[](const Key& key) const {
167 return map[graph.direct(key, false)];
171 typename Ref<Map>::Type map;
175 template <typename Graph, typename Map>
176 BackwardComposeMap<Graph, Map>
177 backwardComposeMap(const Graph& graph, const Map& map) {
178 return BackwardComposeMap<Graph, Map>(graph, map);
181 template <typename Graph, typename Map>
182 struct Ref<ForwardComposeMap<Graph, Map> > {
183 typedef ForwardComposeMap<Graph, Map> Type;
186 template <typename Graph, typename Map>
187 struct Ref<BackwardComposeMap<Graph, Map> > {
188 typedef BackwardComposeMap<Graph, Map> Type;
191 template <typename Map>
192 struct Ref<dim2::XMap<Map> > {
193 typedef dim2::XMap<Map> Type;
195 template <typename Map>
196 struct Ref<dim2::ConstXMap<Map> > {
197 typedef dim2::ConstXMap<Map> Type;
200 template <typename Map>
201 struct Ref<dim2::YMap<Map> > {
202 typedef dim2::YMap<Map> Type;
204 template <typename Map>
205 struct Ref<dim2::ConstYMap<Map> > {
206 typedef dim2::ConstYMap<Map> Type;
210 template <typename _Item>
211 class MapWriterBase {
215 virtual ~MapWriterBase() {}
217 virtual void write(std::ostream& os, const Item& item) const = 0;
218 virtual void sort(std::vector<Item>&) const = 0;
222 template <typename _Item, typename _Map, typename _Writer>
223 class MapWriter : public MapWriterBase<_Item> {
226 typedef _Writer Writer;
227 typedef typename Writer::Value Value;
230 typename _writer_bits::Ref<Map>::Type map;
233 MapWriter(const Map& _map, const Writer& _writer)
234 : map(_map), writer(_writer) {}
236 virtual ~MapWriter() {}
238 virtual void write(std::ostream& os, const Item& item) const {
239 Value value = map[item];
240 writer.write(os, value);
243 virtual void sort(std::vector<Item>& items) const {
244 ComposeLess<Map> less(map);
245 std::sort(items.begin(), items.end(), less);
250 template <typename _UGraph>
251 class UEdgeMapWriterBase {
253 typedef typename _UGraph::Edge Edge;
254 typedef typename _UGraph::UEdge UEdge;
258 virtual ~UEdgeMapWriterBase() {}
260 virtual void write(std::ostream& os, const Item& item) const = 0;
261 virtual void sort(const _UGraph&, std::vector<Edge>&) const = 0;
262 virtual void sort(std::vector<UEdge>&) const = 0;
266 template <typename _UGraph, typename _Map, typename _Writer>
267 class UEdgeMapWriter : public UEdgeMapWriterBase<_UGraph> {
270 typedef _Writer Writer;
271 typedef typename Writer::Value Value;
273 typedef typename _UGraph::Edge Edge;
274 typedef typename _UGraph::UEdge UEdge;
277 typename _writer_bits::Ref<Map>::Type map;
280 UEdgeMapWriter(const Map& _map, const Writer& _writer)
281 : map(_map), writer(_writer) {}
283 virtual ~UEdgeMapWriter() {}
285 virtual void write(std::ostream& os, const Item& item) const {
286 Value value = map[item];
287 writer.write(os, value);
290 virtual void sort(const _UGraph& ugraph, std::vector<Edge>& items) const {
291 UEdgeComposeLess<_UGraph, Map> less(ugraph, map);
292 std::sort(items.begin(), items.end(), less);
295 virtual void sort(std::vector<UEdge>& items) const {
296 ComposeLess<Map> less(map);
297 std::sort(items.begin(), items.end(), less);
303 class ValueWriterBase {
305 virtual ~ValueWriterBase() {}
306 virtual void write(std::ostream&) = 0;
309 template <typename _Value, typename _Writer>
310 class ValueWriter : public ValueWriterBase {
312 typedef _Value Value;
313 typedef _Writer Writer;
315 ValueWriter(const Value& _value, const Writer& _writer)
316 : value(_value), writer(_writer) {}
318 virtual void write(std::ostream& os) {
319 writer.write(os, value);
327 template <typename _Item>
328 class LabelWriterBase {
331 virtual ~LabelWriterBase() {}
332 virtual void write(std::ostream&, const Item&) const = 0;
333 virtual void sort(std::vector<Item>&) const = 0;
334 virtual bool isLabelWriter() const = 0;
335 virtual LabelWriterBase* clone() const = 0;
338 template <typename _Item, typename _BoxedLabelWriter>
339 class LabelWriter : public LabelWriterBase<_Item> {
342 typedef _BoxedLabelWriter BoxedLabelWriter;
344 const BoxedLabelWriter& labelWriter;
346 LabelWriter(const BoxedLabelWriter& _labelWriter)
347 : labelWriter(_labelWriter) {}
349 virtual void write(std::ostream& os, const Item& item) const {
350 labelWriter.writeLabel(os, item);
352 virtual void sort(std::vector<Item>& items) const {
353 labelWriter.sortByLabel(items);
356 virtual bool isLabelWriter() const {
357 return labelWriter.isLabelWriter();
360 virtual LabelWriter* clone() const {
361 return new LabelWriter(labelWriter);
367 /// \ingroup lemon_io
368 /// \brief Lemon Format writer class.
370 /// The Lemon Format contains several sections. We do not want to
371 /// determine what sections are in a lemon file we give only a framework
372 /// to write a section oriented format.
374 /// In the Lemon Format each section starts with a line contains a \c \@
375 /// character on the first not white space position. This line is the
376 /// header line of the section. Each next lines belong to this section
377 /// while it does not starts with \c \@ character. This line can start a
378 /// new section or if it can close the file with the \c \@end line.
379 /// The file format ignore the empty lines and it may contain comments
380 /// started with a \c # character to the end of the line.
382 /// The framework provides an abstract LemonWriter::SectionWriter class
383 /// what defines the interface of a SectionWriter. The SectionWriter
384 /// has the \c header() member function what gives back the header of the
385 /// section. After that it will be called the \c write() member which
386 /// should write the content of the section.
388 /// \relates GraphWriter
389 /// \relates NodeSetWriter
390 /// \relates EdgeSetWriter
391 /// \relates NodesWriter
392 /// \relates EdgesWriter
393 /// \relates AttributeWriter
397 /// \brief Abstract base class for writing a section.
399 /// This class has an \c header() member function what gives back
400 /// the header line of the section. The \c write() member should
401 /// write the content of the section to the stream.
402 class SectionWriter {
403 friend class LemonWriter;
405 /// \brief Constructor for SectionWriter.
407 /// Constructor for SectionWriter. It attach this writer to
408 /// the given LemonWriter.
409 SectionWriter(LemonWriter& writer) {
410 writer.attach(*this);
413 virtual ~SectionWriter() {}
415 /// \brief The header of section.
417 /// It gives back the header of the section.
418 virtual std::string header() = 0;
420 /// \brief Writer function of the section.
422 /// Write the content of the section.
423 virtual void write(std::ostream& os) = 0;
425 /// \brief Gives back true when the section should be written.
427 /// Gives back true when the section should be written.
428 virtual bool valid() { return true; }
431 /// \brief Constructor for LemonWriter.
433 /// Constructor for LemonWriter which writes to the given stream.
434 LemonWriter(std::ostream& _os)
435 : os(&_os), own_os(false) {}
437 /// \brief Constructor for LemonWriter.
439 /// Constructor for LemonWriter which writes to the given file.
440 LemonWriter(const std::string& filename)
441 : os(0), own_os(true) {
442 os = new std::ofstream(filename.c_str());
445 /// \brief Desctructor for LemonWriter.
447 /// Desctructor for LemonWriter.
455 LemonWriter(const LemonWriter&);
456 void operator=(const LemonWriter&);
458 void attach(SectionWriter& writer) {
459 writers.push_back(&writer);
464 /// \brief Executes the LemonWriter.
466 /// It executes the LemonWriter.
468 SectionWriters::iterator it;
469 for (it = writers.begin(); it != writers.end(); ++it) {
470 if ((*it)->valid()) {
471 *os << (*it)->header() << std::endl;
475 *os << "@end" << std::endl;
484 typedef std::vector<SectionWriter*> SectionWriters;
485 SectionWriters writers;
489 /// \ingroup section_io
490 /// \brief SectionWriter for writing a graph's nodeset.
492 /// The lemon format can store multiple graph nodesets with several maps.
493 /// The nodeset section's header line is \c \@nodeset \c nodeset_name, but
494 /// the \c nodeset_name may be empty.
496 /// The first line of the section contains the names of the maps separated
497 /// with white spaces. Each next lines describes a node in the nodeset, and
498 /// contains the mapped values for each map.
500 /// If the nodeset contains an \c "label" named map then it will be regarded
501 /// as label map. This map should contain only unique values and when the
502 /// \c writeLabel() member will be called with a node it will write it's
503 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
504 /// then the label map will be the id in the graph. In addition if the
505 /// the \c _forceSort is true then the writer will write the edges
506 /// sorted by the labels.
508 /// \relates LemonWriter
509 template <typename _Graph, typename _Traits = DefaultWriterTraits>
510 class NodeSetWriter : public LemonWriter::SectionWriter {
511 typedef LemonWriter::SectionWriter Parent;
514 typedef _Graph Graph;
515 typedef _Traits Traits;
516 typedef typename Graph::Node Node;
518 /// \brief Constructor.
520 /// Constructor for NodeSetWriter. It creates the NodeSetWriter and
521 /// attach it into the given LemonWriter. If the \c _forceLabelMap
522 /// parameter is true then the writer will write own label map when
523 /// the user does not give "label" named map. In addition if the
524 /// the \c _forceSort is true then the writer will write the edges
525 /// sorted by the labels.
526 NodeSetWriter(LemonWriter& _writer, const Graph& _graph,
527 const std::string& _name = std::string(),
528 bool _forceLabelMap = true, bool _forceSort = true)
529 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
530 forceSort(_forceSort), graph(_graph), name(_name) {}
532 /// \brief Destructor.
534 /// Destructor for NodeSetWriter.
535 virtual ~NodeSetWriter() {
536 typename MapWriters::iterator it;
537 for (it = writers.begin(); it != writers.end(); ++it) {
543 NodeSetWriter(const NodeSetWriter&);
544 void operator=(const NodeSetWriter&);
548 /// \brief Add a new node map writer command for the writer.
550 /// Add a new node map writer command for the writer.
551 template <typename Map>
552 NodeSetWriter& writeNodeMap(std::string label, const Map& map) {
553 return writeNodeMap<typename Traits::
554 template Writer<typename Map::Value>, Map>(label, map);
557 /// \brief Add a new node map writer command for the writer.
559 /// Add a new node map writer command for the writer.
560 template <typename ItemWriter, typename Map>
561 NodeSetWriter& writeNodeMap(std::string label, const Map& map,
562 const ItemWriter& iw = ItemWriter()) {
563 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
564 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
566 make_pair(label, new _writer_bits::
567 MapWriter<Node, Map, ItemWriter>(map, iw)));
573 /// \brief The header of the section.
575 /// It gives back the header of the section.
576 virtual std::string header() {
577 return "@nodeset " + name;
580 /// \brief Writer function of the section.
582 /// Write the content of the section.
583 virtual void write(std::ostream& os) {
584 for (int i = 0; i < int(writers.size()); ++i) {
585 if (writers[i].first == "label") {
586 labelMap = writers[i].second;
587 forceLabelMap = false;
591 std::vector<Node> items;
592 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
597 labelMap->sort(items);
599 typedef IdMap<Graph, Node> Map;
601 _writer_bits::ComposeLess<Map> less(map);
602 std::sort(items.begin(), items.end(), less);
608 for (int i = 0; i < int(writers.size()); ++i) {
609 os << writers[i].first << '\t';
612 for (typename std::vector<Node>::iterator it = items.begin();
613 it != items.end(); ++it) {
615 os << graph.id(*it) << '\t';
617 for (int i = 0; i < int(writers.size()); ++i) {
618 writers[i].second->write(os, *it);
627 /// \brief Returns true if the nodeset can write the labels of the nodes.
629 /// Returns true if the nodeset can write the labels of the nodes.
630 /// It is possible only if a "label" named map was written or the
631 /// \c _forceLabelMap constructor parameter was true.
632 bool isLabelWriter() const {
633 return labelMap != 0 || forceLabelMap;
636 /// \brief Write the label of the given node.
638 /// It writes the label of the given node. If there was written a "label"
639 /// named map then it will write the map value belongs to the node.
640 /// Otherwise if the \c forceLabel parameter was true it will write
641 /// its label in the graph.
642 void writeLabel(std::ostream& os, const Node& item) const {
644 os << graph.id(item);
646 labelMap->write(os, item);
650 /// \brief Sorts the given node vector by label.
652 /// Sorts the given node vector by label. If there was written an
653 /// "label" named map then the vector will be sorted by the values
654 /// of this map. Otherwise if the \c forceLabel parameter was true
655 /// it will be sorted by its id in the graph.
656 void sortByLabel(std::vector<Node>& nodes) const {
658 labelMap->sort(nodes);
660 typedef IdMap<Graph, Node> Map;
662 _writer_bits::ComposeLess<Map> less(map);
663 std::sort(nodes.begin(), nodes.end(), less);
669 typedef std::vector<std::pair<std::string, _writer_bits::
670 MapWriterBase<Node>*> > MapWriters;
673 _writer_bits::MapWriterBase<Node>* labelMap;
682 /// \ingroup section_io
683 /// \brief SectionWriter for writing a graph's edgesets.
685 /// The lemon format can store multiple graph edgesets with several maps.
686 /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but
687 /// the \c edgeset_name may be empty.
689 /// The first line of the section contains the names of the maps separated
690 /// with white spaces. Each next lines describes a edge in the edgeset. The
691 /// line contains the source and the target nodes' label and the mapped
692 /// values for each map.
694 /// If the edgeset contains an \c "label" named map then it will be regarded
695 /// as label map. This map should contain only unique values and when the
696 /// \c writeLabel() member will be called with an edge it will write it's
697 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
698 /// then the label map will be the id in the graph. In addition if the
699 /// the \c _forceSort is true then the writer will write the edges
700 /// sorted by the labels.
702 /// The edgeset writer needs a node label writer to identify which nodes
703 /// have to be connected. If a NodeSetWriter can write the nodes' label,
704 /// it will be able to use with this class.
706 /// \relates LemonWriter
707 template <typename _Graph, typename _Traits = DefaultWriterTraits>
708 class EdgeSetWriter : public LemonWriter::SectionWriter {
709 typedef LemonWriter::SectionWriter Parent;
712 typedef _Graph Graph;
713 typedef _Traits Traits;
714 typedef typename Graph::Node Node;
715 typedef typename Graph::Edge Edge;
717 /// \brief Constructor.
719 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
720 /// and attach it into the given LemonWriter. It will write node
721 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
722 /// parameter is true then the writer will write own label map if
723 /// the user does not give "label" named map. In addition if the
724 /// the \c _forceSort is true then the writer will write the
725 /// edges sorted by the labels.
726 template <typename NodeLabelWriter>
727 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
728 const NodeLabelWriter& _nodeLabelWriter,
729 const std::string& _name = std::string(),
730 bool _forceLabelMap = true, bool _forceSort = true)
731 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
732 forceSort(_forceSort), graph(_graph), name(_name) {
733 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
734 nodeLabelWriter.reset(new _writer_bits::
735 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
738 /// \brief Destructor.
740 /// Destructor for EdgeSetWriter.
741 virtual ~EdgeSetWriter() {
742 typename MapWriters::iterator it;
743 for (it = writers.begin(); it != writers.end(); ++it) {
749 EdgeSetWriter(const EdgeSetWriter&);
750 void operator=(const EdgeSetWriter&);
754 /// \brief Add a new edge map writer command for the writer.
756 /// Add a new edge map writer command for the writer.
757 template <typename Map>
758 EdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
759 return writeEdgeMap<typename Traits::
760 template Writer<typename Map::Value>, Map>(label, map);
763 /// \brief Add a new edge map writer command for the writer.
765 /// Add a new edge map writer command for the writer.
766 template <typename ItemWriter, typename Map>
767 EdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
768 const ItemWriter& iw = ItemWriter()) {
769 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
770 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
772 make_pair(label, new _writer_bits::
773 MapWriter<Edge, Map, ItemWriter>(map, iw)));
779 /// \brief The header of the section.
781 /// It gives back the header of the section.
782 virtual std::string header() {
783 return "@edgeset " + name;
786 /// \brief Writer function of the section.
788 /// Write the content of the section.
789 virtual void write(std::ostream& os) {
790 if (!nodeLabelWriter->isLabelWriter()) {
791 throw DataFormatError("Cannot find nodeset or label map");
793 for (int i = 0; i < int(writers.size()); ++i) {
794 if (writers[i].first == "label") {
795 labelMap = writers[i].second;
796 forceLabelMap = false;
800 std::vector<Edge> items;
801 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
806 labelMap->sort(items);
808 typedef IdMap<Graph, Edge> Map;
810 _writer_bits::ComposeLess<Map> less(map);
811 std::sort(items.begin(), items.end(), less);
818 for (int i = 0; i < int(writers.size()); ++i) {
819 os << writers[i].first << '\t';
822 for (typename std::vector<Edge>::iterator it = items.begin();
823 it != items.end(); ++it) {
824 nodeLabelWriter->write(os, graph.source(*it));
826 nodeLabelWriter->write(os, graph.target(*it));
829 os << graph.id(*it) << '\t';
831 for (int i = 0; i < int(writers.size()); ++i) {
832 writers[i].second->write(os, *it);
841 /// \brief Returns true if the edgeset can write the labels of the edges.
843 /// Returns true if the edgeset can write the labels of the edges.
844 /// It is possible only if a "label" named map was written or the
845 /// \c _forceLabelMap constructor parameter was true.
846 bool isLabelWriter() const {
847 return forceLabelMap || labelMap != 0;
850 /// \brief Write the label of the given edge.
852 /// It writes the label of the given edge. If there was written a "label"
853 /// named map then it will write the map value belongs to the edge.
854 /// Otherwise if the \c forceLabel parameter was true it will write
855 /// its label in the graph.
856 void writeLabel(std::ostream& os, const Edge& item) const {
858 os << graph.id(item);
860 labelMap->write(os, item);
864 /// \brief Sorts the given edge vector by label.
866 /// Sorts the given edge vector by label. If there was written an
867 /// "label" named map then the vector will be sorted by the values
868 /// of this map. Otherwise if the \c forceLabel parameter was true
869 /// it will be sorted by its id in the graph.
870 void sortByLabel(std::vector<Edge>& edges) const {
872 labelMap->sort(edges);
874 typedef IdMap<Graph, Edge> Map;
876 _writer_bits::ComposeLess<Map> less(map);
877 std::sort(edges.begin(), edges.end(), less);
883 typedef std::vector<std::pair<std::string, _writer_bits::
884 MapWriterBase<Edge>*> > MapWriters;
887 _writer_bits::MapWriterBase<Edge>* labelMap;
894 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
897 /// \ingroup section_io
898 /// \brief SectionWriter for writing a undirected edgeset.
900 /// The lemon format can store multiple undirected edgesets with several
901 /// maps. The undirected edgeset section's header line is \c \@uedgeset
902 /// \c uedgeset_name, but the \c uedgeset_name may be empty.
904 /// The first line of the section contains the names of the maps separated
905 /// with white spaces. Each next lines describes an undirected edge in the
906 /// edgeset. The line contains the two connected nodes' label and the mapped
907 /// values for each undirected map.
909 /// The section can handle the directed as a syntactical sugar. Two
910 /// undirected edge map describes one directed edge map. This two maps
911 /// are the forward map and the backward map and the names of this map
912 /// is near the same just with a prefix \c '+' or \c '-' character
915 /// If the edgeset contains an \c "label" named map then it will be
916 /// regarded as label map. This map should contain only unique
917 /// values and when the \c writeLabel() member will be called with
918 /// an undirected edge it will write it's label. Otherwise if the \c
919 /// _forceLabelMap constructor parameter is true then the label map
920 /// will be the id in the graph. In addition if the the \c
921 /// _forceSort is true then the writer will write the edges sorted
924 /// The undirected edgeset writer needs a node label writer to identify
925 /// which nodes have to be connected. If a NodeSetWriter can write the
926 /// nodes' label, it will be able to use with this class.
928 /// \relates LemonWriter
929 template <typename _Graph, typename _Traits = DefaultWriterTraits>
930 class UEdgeSetWriter : public LemonWriter::SectionWriter {
931 typedef LemonWriter::SectionWriter Parent;
934 typedef _Graph Graph;
935 typedef _Traits Traits;
936 typedef typename Graph::Node Node;
937 typedef typename Graph::Edge Edge;
938 typedef typename Graph::UEdge UEdge;
940 /// \brief Constructor.
942 /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
943 /// and attach it into the given LemonWriter. It will write node
944 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
945 /// parameter is true then the writer will write own label map if
946 /// the user does not give "label" named map. In addition if the
947 /// the \c _forceSort is true then the writer will write the
948 /// edges sorted by the labels.
949 template <typename NodeLabelWriter>
950 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
951 const NodeLabelWriter& _nodeLabelWriter,
952 const std::string& _name = std::string(),
953 bool _forceLabelMap = true, bool _forceSort = true)
954 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
955 forceSort(_forceSort), graph(_graph), name(_name) {
956 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
957 nodeLabelWriter.reset(new _writer_bits::
958 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
961 /// \brief Destructor.
963 /// Destructor for UEdgeSetWriter.
964 virtual ~UEdgeSetWriter() {
965 typename MapWriters::iterator it;
966 for (it = writers.begin(); it != writers.end(); ++it) {
972 UEdgeSetWriter(const UEdgeSetWriter&);
973 void operator=(const UEdgeSetWriter&);
977 /// \brief Add a new undirected edge map writer command for the writer.
979 /// Add a new undirected map writer command for the writer.
980 template <typename Map>
981 UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map) {
982 return writeUEdgeMap<typename Traits::
983 template Writer<typename Map::Value>, Map>(label, map);
986 /// \brief Add a new undirected map writer command for the writer.
988 /// Add a new undirected map writer command for the writer.
989 template <typename ItemWriter, typename Map>
990 UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map,
991 const ItemWriter& iw = ItemWriter()) {
992 checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
993 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
995 make_pair(label, new _writer_bits::
996 UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
1000 /// \brief Add a new directed edge map writer command for the writer.
1002 /// Add a new directed map writer command for the writer.
1003 template <typename Map>
1004 UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
1005 return writeEdgeMap<typename Traits::
1006 template Writer<typename Map::Value>, Map>(label, map);
1009 /// \brief Add a new directed map writer command for the writer.
1011 /// Add a new directed map writer command for the writer.
1012 template <typename ItemWriter, typename Map>
1013 UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
1014 const ItemWriter& iw = ItemWriter()) {
1015 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1016 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1017 writeUEdgeMap("+" + label,
1018 _writer_bits::forwardComposeMap(graph, map), iw);
1019 writeUEdgeMap("-" + label,
1020 _writer_bits::backwardComposeMap(graph, map), iw);
1026 /// \brief The header of the section.
1028 /// It gives back the header of the section.
1029 virtual std::string header() {
1030 return "@uedgeset " + name;
1033 /// \brief Writer function of the section.
1035 /// Write the content of the section.
1036 virtual void write(std::ostream& os) {
1037 if (!nodeLabelWriter->isLabelWriter()) {
1038 throw DataFormatError("Cannot find nodeset or label map");
1040 for (int i = 0; i < int(writers.size()); ++i) {
1041 if (writers[i].first == "label") {
1042 labelMap = writers[i].second;
1043 forceLabelMap = false;
1047 std::vector<UEdge> items;
1048 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
1049 items.push_back(it);
1053 labelMap->sort(items);
1055 typedef IdMap<Graph, UEdge> Map;
1057 _writer_bits::ComposeLess<Map> less(map);
1058 std::sort(items.begin(), items.end(), less);
1062 if (forceLabelMap) {
1065 for (int i = 0; i < int(writers.size()); ++i) {
1066 os << writers[i].first << '\t';
1069 for (typename std::vector<UEdge>::iterator it = items.begin();
1070 it != items.end(); ++it) {
1071 nodeLabelWriter->write(os, graph.source(*it));
1073 nodeLabelWriter->write(os, graph.target(*it));
1075 if (forceLabelMap) {
1076 os << graph.id(*it) << '\t';
1078 for (int i = 0; i < int(writers.size()); ++i) {
1079 writers[i].second->write(os, *it);
1088 /// \brief Returns true if the undirected edgeset can write the labels of
1091 /// Returns true if the undirected edgeset can write the labels of the
1092 /// undirected edges. It is possible only if a "label" named map was
1093 /// written or the \c _forceLabelMap constructor parameter was true.
1094 bool isLabelWriter() const {
1095 return forceLabelMap || labelMap != 0;
1098 /// \brief Write the label of the given undirected edge.
1100 /// It writes the label of the given undirected edge. If there was written
1101 /// a "label" named map then it will write the map value belongs to the
1102 /// undirected edge. Otherwise if the \c forceLabel parameter was true it
1103 /// will write its id in the graph.
1104 void writeLabel(std::ostream& os, const UEdge& item) const {
1105 if (forceLabelMap) {
1106 os << graph.id(item);
1108 labelMap->write(os, item);
1112 /// \brief Write the label of the given edge.
1114 /// It writes the label of the given edge. If there was written
1115 /// a "label" named map then it will write the map value belongs to the
1116 /// edge. Otherwise if the \c forceLabel parameter was true it
1117 /// will write its id in the graph. If the edge is forward map
1118 /// then its prefix character is \c '+' elsewhere \c '-'.
1119 void writeLabel(std::ostream& os, const Edge& item) const {
1120 if (graph.direction(item)) {
1125 if (forceLabelMap) {
1126 os << graph.id(static_cast<const UEdge&>(item));
1128 labelMap->write(os, item);
1132 /// \brief Sorts the given undirected edge vector by label.
1134 /// Sorts the given undirected edge vector by label. If there was
1135 /// written a "label" named map then the vector will be sorted by
1136 /// the values of this map. Otherwise if the \c forceLabel
1137 /// parameter was true it will be sorted by its id in the graph.
1138 void sortByLabel(std::vector<UEdge>& uedges) const {
1140 labelMap->sort(uedges);
1142 typedef IdMap<Graph, UEdge> Map;
1144 _writer_bits::ComposeLess<Map> less(map);
1145 std::sort(uedges.begin(), uedges.end(), less);
1149 /// \brief Sorts the given edge vector by label.
1151 /// Sorts the given edge vector by label. If there was written a
1152 /// "label" named map then the vector will be sorted by the values
1153 /// of this map. Otherwise if the \c forceLabel parameter was true
1154 /// it will be sorted by its id in the graph.
1155 void sortByLabel(std::vector<Edge>& edges) const {
1157 labelMap->sort(graph, edges);
1159 typedef IdMap<Graph, Edge> Map;
1161 _writer_bits::ComposeLess<Map> less(map);
1162 std::sort(edges.begin(), edges.end(), less);
1168 typedef std::vector<std::pair<std::string, _writer_bits::
1169 UEdgeMapWriterBase<Graph>*> > MapWriters;
1172 _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
1179 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
1182 /// \ingroup section_io
1183 /// \brief SectionWriter for writing named nodes.
1185 /// The nodes section's header line is \c \@nodes \c nodes_name, but the
1186 /// \c nodes_name may be empty.
1188 /// Each line in the section contains the name of the node and
1189 /// then the node label.
1191 /// \relates LemonWriter
1192 template <typename _Graph>
1193 class NodeWriter : public LemonWriter::SectionWriter {
1194 typedef LemonWriter::SectionWriter Parent;
1195 typedef _Graph Graph;
1196 typedef typename Graph::Node Node;
1199 /// \brief Constructor.
1201 /// Constructor for NodeWriter. It creates the NodeWriter and
1202 /// attach it into the given LemonWriter. The given \c _LabelWriter
1203 /// will write the nodes' label what can be a nodeset writer.
1204 template <typename _LabelWriter>
1205 NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1206 const std::string& _name = std::string())
1207 : Parent(_writer), name(_name) {
1208 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1209 labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
1214 /// \brief Destructor.
1216 /// Destructor for NodeWriter.
1217 virtual ~NodeWriter() {}
1220 NodeWriter(const NodeWriter&);
1221 void operator=(const NodeWriter&);
1225 /// \brief Add a node writer command for the NodeWriter.
1227 /// Add a node writer command for the NodeWriter.
1228 void writeNode(std::string label, const Node& item) {
1229 writers.push_back(make_pair(label, &item));
1234 /// \brief The header of the section.
1236 /// It gives back the header of the section.
1237 virtual std::string header() {
1238 return "@nodes " + name;
1241 /// \brief Writer function of the section.
1243 /// Write the content of the section.
1244 virtual void write(std::ostream& os) {
1245 if (!labelWriter->isLabelWriter()) {
1246 throw DataFormatError("Cannot find nodeset or label map");
1248 for (int i = 0; i < int(writers.size()); ++i) {
1249 os << writers[i].first << ' ';
1250 labelWriter->write(os, *(writers[i].second));
1255 /// \brief Gives back true when the section should be written.
1257 /// Gives back true when the section should be written.
1258 virtual bool valid() { return !writers.empty(); }
1264 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1265 NodeWriters writers;
1266 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1269 /// \ingroup section_io
1270 /// \brief SectionWriter for writing named edges.
1272 /// The edges section's header line is \c \@edges \c edges_name, but the
1273 /// \c edges_name may be empty.
1275 /// Each line in the section contains the name of the edge and
1276 /// then the edge label.
1278 /// \relates LemonWriter
1279 template <typename _Graph>
1280 class EdgeWriter : public LemonWriter::SectionWriter {
1281 typedef LemonWriter::SectionWriter Parent;
1282 typedef _Graph Graph;
1283 typedef typename Graph::Edge Edge;
1286 /// \brief Constructor.
1288 /// Constructor for EdgeWriter. It creates the EdgeWriter and
1289 /// attach it into the given LemonWriter. The given \c _LabelWriter
1290 /// will write the edges' label what can be a edgeset writer.
1291 template <typename _LabelWriter>
1292 EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1293 const std::string& _name = std::string())
1294 : Parent(_writer), name(_name) {
1295 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1296 labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
1299 /// \brief Destructor.
1301 /// Destructor for EdgeWriter.
1302 virtual ~EdgeWriter() {}
1304 EdgeWriter(const EdgeWriter&);
1305 void operator=(const EdgeWriter&);
1309 /// \brief Add an edge writer command for the EdgeWriter.
1311 /// Add an edge writer command for the EdgeWriter.
1312 void writeEdge(std::string label, const Edge& item) {
1313 writers.push_back(make_pair(label, &item));
1318 /// \brief The header of the section.
1320 /// It gives back the header of the section.
1321 virtual std::string header() {
1322 return "@edges " + name;
1325 /// \brief Writer function of the section.
1327 /// Write the content of the section.
1328 virtual void write(std::ostream& os) {
1329 if (!labelWriter->isLabelWriter()) {
1330 throw DataFormatError("Cannot find edgeset or label map");
1332 for (int i = 0; i < int(writers.size()); ++i) {
1333 os << writers[i].first << ' ';
1334 labelWriter->write(os, *(writers[i].second));
1339 /// \brief Gives back true when the section should be written.
1341 /// Gives back true when the section should be written.
1342 virtual bool valid() { return !writers.empty(); }
1348 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1349 EdgeWriters writers;
1351 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1355 /// \ingroup section_io
1356 /// \brief SectionWriter for writing named undirected edges.
1358 /// The undirected edges section's header line is \c \@uedges
1359 /// \c uedges_name, but the \c uedges_name may be empty.
1361 /// Each line in the section contains the name of the undirected edge and
1362 /// then the undirected edge label.
1364 /// \relates LemonWriter
1365 template <typename _Graph>
1366 class UEdgeWriter : public LemonWriter::SectionWriter {
1367 typedef LemonWriter::SectionWriter Parent;
1368 typedef _Graph Graph;
1369 typedef typename Graph::Node Node;
1370 typedef typename Graph::Edge Edge;
1371 typedef typename Graph::UEdge UEdge;
1374 /// \brief Constructor.
1376 /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
1377 /// attach it into the given LemonWriter. The given \c _LabelWriter
1378 /// will write the undirected edges' label what can be an undirected
1380 template <typename _LabelWriter>
1381 UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1382 const std::string& _name = std::string())
1383 : Parent(_writer), name(_name) {
1384 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1385 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1386 uEdgeLabelWriter.reset(new _writer_bits::
1387 LabelWriter<UEdge, _LabelWriter>(_labelWriter));
1388 edgeLabelWriter.reset(new _writer_bits::
1389 LabelWriter<Edge, _LabelWriter>(_labelWriter));
1392 /// \brief Destructor.
1394 /// Destructor for UEdgeWriter.
1395 virtual ~UEdgeWriter() {}
1397 UEdgeWriter(const UEdgeWriter&);
1398 void operator=(const UEdgeWriter&);
1402 /// \brief Add an edge writer command for the UEdgeWriter.
1404 /// Add an edge writer command for the UEdgeWriter.
1405 void writeEdge(std::string label, const Edge& item) {
1406 edgeWriters.push_back(make_pair(label, &item));
1409 /// \brief Add an undirected edge writer command for the UEdgeWriter.
1411 /// Add an undirected edge writer command for the UEdgeWriter.
1412 void writeUEdge(std::string label, const UEdge& item) {
1413 uEdgeWriters.push_back(make_pair(label, &item));
1418 /// \brief The header of the section.
1420 /// It gives back the header of the section.
1421 virtual std::string header() {
1422 return "@uedges " + name;
1425 /// \brief Writer function of the section.
1427 /// Write the content of the section.
1428 virtual void write(std::ostream& os) {
1429 if (!edgeLabelWriter->isLabelWriter()) {
1430 throw DataFormatError("Cannot find undirected edgeset or label map");
1432 if (!uEdgeLabelWriter->isLabelWriter()) {
1433 throw DataFormatError("Cannot find undirected edgeset or label map");
1435 for (int i = 0; i < int(uEdgeWriters.size()); ++i) {
1436 os << uEdgeWriters[i].first << ' ';
1437 uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
1440 for (int i = 0; i < int(edgeWriters.size()); ++i) {
1441 os << edgeWriters[i].first << ' ';
1442 edgeLabelWriter->write(os, *(edgeWriters[i].second));
1447 /// \brief Gives back true when the section should be written.
1449 /// Gives back true when the section should be written.
1450 virtual bool valid() {
1451 return !uEdgeWriters.empty() || !edgeWriters.empty();
1458 typedef std::vector<std::pair<std::string,
1459 const UEdge*> > UEdgeWriters;
1460 UEdgeWriters uEdgeWriters;
1461 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
1463 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1464 EdgeWriters edgeWriters;
1465 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
1469 /// \ingroup section_io
1470 /// \brief SectionWriter for writing extra node maps.
1472 /// The lemon format can store maps in the nodeset. This class let
1473 /// you make distinict section to store maps. The main purpose of
1474 /// this class is a logical separation of some maps. The other
1475 /// useful application could be to store paths in node maps.
1477 /// The first line of the section contains the names of the maps
1478 /// separated with white spaces. Each next line describes an item
1479 /// in the itemset, and contains in the first column the label of
1480 /// the item and then the mapped values for each map.
1482 /// \relates LemonWriter
1483 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1484 class NodeMapWriter : public LemonWriter::SectionWriter {
1485 typedef LemonWriter::SectionWriter Parent;
1488 typedef _Graph Graph;
1489 typedef _Traits Traits;
1490 typedef typename Graph::Node Node;
1492 /// \brief Constructor.
1494 /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
1495 /// attach it into the given LemonWriter. If the the
1496 /// \c _forceSort is true then the writer will write the edges
1497 /// sorted by the labels.
1498 template <typename _LabelWriter>
1499 NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
1500 const _LabelWriter& _labelWriter,
1501 const std::string& _name = std::string(),
1502 bool _forceSort = true)
1503 : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1504 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1505 labelWriter.reset(new _writer_bits::LabelWriter<Node,
1506 _LabelWriter>(_labelWriter));
1509 /// \brief Destructor.
1511 /// Destructor for NodeMapWriter.
1512 virtual ~NodeMapWriter() {
1513 typename MapWriters::iterator it;
1514 for (it = writers.begin(); it != writers.end(); ++it) {
1520 NodeMapWriter(const NodeMapWriter&);
1521 void operator=(const NodeMapWriter&);
1525 /// \brief Add a new node map writer command for the writer.
1527 /// Add a new node map writer command for the writer.
1528 template <typename Map>
1529 NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
1530 return writeNodeMap<typename Traits::
1531 template Writer<typename Map::Value>, Map>(label, map);
1534 /// \brief Add a new node map writer command for the writer.
1536 /// Add a new node map writer command for the writer.
1537 template <typename ItemWriter, typename Map>
1538 NodeMapWriter& writeNodeMap(std::string label, const Map& map,
1539 const ItemWriter& iw = ItemWriter()) {
1540 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1541 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1543 make_pair(label, new _writer_bits::
1544 MapWriter<Node, Map, ItemWriter>(map, iw)));
1550 /// \brief The header of the section.
1552 /// It gives back the header of the section.
1553 virtual std::string header() {
1554 return "@nodemaps " + name;
1557 /// \brief Writer function of the section.
1559 /// Write the content of the section.
1560 virtual void write(std::ostream& os) {
1561 std::vector<Node> nodes;
1562 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
1563 nodes.push_back(it);
1566 labelWriter->sort(nodes);
1569 for (int i = 0; i < int(writers.size()); ++i) {
1570 os << writers[i].first << '\t';
1573 for (typename std::vector<Node>::iterator it = nodes.begin();
1574 it != nodes.end(); ++it) {
1576 labelWriter->write(os, *it); os << '\t';
1577 for (int i = 0; i < int(writers.size()); ++i) {
1578 writers[i].second->write(os, *it);
1588 typedef std::vector<std::pair<std::string, _writer_bits::
1589 MapWriterBase<Node>*> > MapWriters;
1592 _writer_bits::MapWriterBase<Node>* labelMap;
1598 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1601 /// \ingroup section_io
1602 /// \brief SectionWriter for writing extra edge maps.
1604 /// The lemon format can store maps in the edgeset. This class let
1605 /// you make distinict section to store maps. The main purpose of
1606 /// this class is a logical separation of some maps. The other
1607 /// useful application could be to store paths in edge maps.
1609 /// The first line of the section contains the names of the maps
1610 /// separated with white spaces. Each next line describes an item
1611 /// in the itemset, and contains in the first column the label of
1612 /// the item and then the mapped values for each map.
1614 /// \relates LemonWriter
1615 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1616 class EdgeMapWriter : public LemonWriter::SectionWriter {
1617 typedef LemonWriter::SectionWriter Parent;
1620 typedef _Graph Graph;
1621 typedef _Traits Traits;
1622 typedef typename Graph::Edge Edge;
1624 /// \brief Constructor.
1626 /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
1627 /// attach it into the given LemonWriter. If the the
1628 /// \c _forceSort is true then the writer will write the edges
1629 /// sorted by the labels.
1630 template <typename _LabelWriter>
1631 EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
1632 const _LabelWriter& _labelWriter,
1633 const std::string& _name = std::string(),
1634 bool _forceSort = true)
1635 : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1636 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1637 labelWriter.reset(new _writer_bits::LabelWriter<Edge,
1638 _LabelWriter>(_labelWriter));
1641 /// \brief Destructor.
1643 /// Destructor for EdgeMapWriter.
1644 virtual ~EdgeMapWriter() {
1645 typename MapWriters::iterator it;
1646 for (it = writers.begin(); it != writers.end(); ++it) {
1652 EdgeMapWriter(const EdgeMapWriter&);
1653 void operator=(const EdgeMapWriter&);
1657 /// \brief Add a new edge map writer command for the writer.
1659 /// Add a new edge map writer command for the writer.
1660 template <typename Map>
1661 EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
1662 return writeEdgeMap<typename Traits::
1663 template Writer<typename Map::Value>, Map>(label, map);
1666 /// \brief Add a new edge map writer command for the writer.
1668 /// Add a new edge map writer command for the writer.
1669 template <typename ItemWriter, typename Map>
1670 EdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
1671 const ItemWriter& iw = ItemWriter()) {
1672 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1673 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1675 make_pair(label, new _writer_bits::
1676 MapWriter<Edge, Map, ItemWriter>(map, iw)));
1682 /// \brief The header of the section.
1684 /// It gives back the header of the section.
1685 virtual std::string header() {
1686 return "@edgemaps " + name;
1689 /// \brief Writer function of the section.
1691 /// Write the content of the section.
1692 virtual void write(std::ostream& os) {
1693 std::vector<Edge> edges;
1694 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1695 edges.push_back(it);
1698 labelWriter->sort(edges);
1701 for (int i = 0; i < int(writers.size()); ++i) {
1702 os << writers[i].first << '\t';
1705 for (typename std::vector<Edge>::iterator it = edges.begin();
1706 it != edges.end(); ++it) {
1708 labelWriter->write(os, *it); os << '\t';
1709 for (int i = 0; i < int(writers.size()); ++i) {
1710 writers[i].second->write(os, *it);
1720 typedef std::vector<std::pair<std::string, _writer_bits::
1721 MapWriterBase<Edge>*> > MapWriters;
1724 _writer_bits::MapWriterBase<Edge>* labelMap;
1730 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1733 /// \ingroup section_io
1734 /// \brief SectionWriter for writing extra undirected edge maps.
1736 /// The lemon format can store maps in the uedgeset. This class let
1737 /// you make distinict section to store maps. The main purpose of
1738 /// this class is a logical separation of some maps. The other
1739 /// useful application could be to store paths in undirected edge
1742 /// The first line of the section contains the names of the maps
1743 /// separated with white spaces. Each next line describes an item
1744 /// in the itemset, and contains in the first column the label of
1745 /// the item and then the mapped values for each map.
1747 /// \relates LemonWriter
1748 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1749 class UEdgeMapWriter : public LemonWriter::SectionWriter {
1750 typedef LemonWriter::SectionWriter Parent;
1753 typedef _Graph Graph;
1754 typedef _Traits Traits;
1755 typedef typename Graph::UEdge UEdge;
1756 typedef typename Graph::Edge Edge;
1758 /// \brief Constructor.
1760 /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
1761 /// attach it into the given LemonWriter. If the the
1762 /// \c _forceSort is true then the writer will write the uedges
1763 /// sorted by the labels.
1764 template <typename _LabelWriter>
1765 UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
1766 const _LabelWriter& _labelWriter,
1767 const std::string& _name = std::string(),
1768 bool _forceSort = true)
1769 : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1770 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1771 labelWriter.reset(new _writer_bits::LabelWriter<UEdge,
1772 _LabelWriter>(_labelWriter));
1775 /// \brief Destructor.
1777 /// Destructor for UEdgeMapWriter.
1778 virtual ~UEdgeMapWriter() {
1779 typename MapWriters::iterator it;
1780 for (it = writers.begin(); it != writers.end(); ++it) {
1786 UEdgeMapWriter(const UEdgeMapWriter&);
1787 void operator=(const UEdgeMapWriter&);
1791 /// \brief Add a new undirected edge map writer command for the writer.
1793 /// Add a new undirected edge map writer command for the writer.
1794 template <typename Map>
1795 UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
1796 return writeUEdgeMap<typename Traits::
1797 template Writer<typename Map::Value>, Map>(label, map);
1800 /// \brief Add a new undirected edge map writer command for the writer.
1802 /// Add a new undirected edge map writer command for the writer.
1803 template <typename ItemWriter, typename Map>
1804 UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map,
1805 const ItemWriter& iw = ItemWriter()) {
1806 checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
1807 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1809 make_pair(label, new _writer_bits::
1810 MapWriter<UEdge, Map, ItemWriter>(map, iw)));
1814 /// \brief Add a new directed edge map writer command for the writer.
1816 /// Add a new directed map writer command for the writer.
1817 template <typename Map>
1818 UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
1819 return writeEdgeMap<typename Traits::
1820 template Writer<typename Map::Value>, Map>(label, map);
1823 /// \brief Add a new directed map writer command for the writer.
1825 /// Add a new directed map writer command for the writer.
1826 template <typename ItemWriter, typename Map>
1827 UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
1828 const ItemWriter& iw = ItemWriter()) {
1829 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1830 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1831 writeUEdgeMap("+" + label,
1832 _writer_bits::forwardComposeMap(graph, map), iw);
1833 writeUEdgeMap("-" + label,
1834 _writer_bits::backwardComposeMap(graph, map), iw);
1840 /// \brief The header of the section.
1842 /// It gives back the header of the section.
1843 virtual std::string header() {
1844 return "@uedgemaps " + name;
1847 /// \brief Writer function of the section.
1849 /// Write the content of the section.
1850 virtual void write(std::ostream& os) {
1851 std::vector<UEdge> uedges;
1852 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
1853 uedges.push_back(it);
1856 labelWriter->sort(uedges);
1859 for (int i = 0; i < int(writers.size()); ++i) {
1860 os << writers[i].first << '\t';
1863 for (typename std::vector<UEdge>::iterator it = uedges.begin();
1864 it != uedges.end(); ++it) {
1866 labelWriter->write(os, *it); os << '\t';
1867 for (int i = 0; i < int(writers.size()); ++i) {
1868 writers[i].second->write(os, *it);
1878 typedef std::vector<std::pair<std::string, _writer_bits::
1879 MapWriterBase<UEdge>*> > MapWriters;
1882 _writer_bits::MapWriterBase<UEdge>* labelMap;
1888 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
1892 /// \ingroup section_io
1893 /// \brief SectionWriter for attributes.
1895 /// The lemon format can store multiple attribute set. Each set has
1896 /// the header line \c \@attributes \c attributes_name, but the
1897 /// attributeset_name may be empty.
1899 /// The attributeset section contains several lines. Each of them starts
1900 /// with the name of attribute and then the value.
1902 /// \relates LemonWriter
1903 template <typename _Traits = DefaultWriterTraits>
1904 class AttributeWriter : public LemonWriter::SectionWriter {
1905 typedef LemonWriter::SectionWriter Parent;
1906 typedef _Traits Traits;
1908 /// \brief Constructor.
1910 /// Constructor for AttributeWriter. It creates the AttributeWriter and
1911 /// attach it into the given LemonWriter.
1912 AttributeWriter(LemonWriter& _writer,
1913 const std::string& _name = std::string())
1914 : Parent(_writer), name(_name) {}
1916 /// \brief Destructor.
1918 /// Destructor for AttributeWriter.
1919 virtual ~AttributeWriter() {
1920 typename Writers::iterator it;
1921 for (it = writers.begin(); it != writers.end(); ++it) {
1927 AttributeWriter(const AttributeWriter&);
1928 void operator=(AttributeWriter&);
1931 /// \brief Add an attribute writer command for the writer.
1933 /// Add an attribute writer command for the writer.
1934 template <typename Value>
1935 AttributeWriter& writeAttribute(std::string label,
1936 const Value& value) {
1938 writeAttribute<typename Traits::template Writer<Value> >(label, value);
1941 /// \brief Add an attribute writer command for the writer.
1943 /// Add an attribute writer command for the writer.
1944 template <typename ItemWriter, typename Value>
1945 AttributeWriter& writeAttribute(std::string label, const Value& value,
1946 const ItemWriter& iw = ItemWriter()) {
1947 checkConcept<_writer_bits::ItemWriter<Value>, ItemWriter>();
1948 writers.push_back(make_pair(label, new _writer_bits::
1949 ValueWriter<Value, ItemWriter>(value, iw)));
1955 /// \brief The header of section.
1957 /// It gives back the header of the section.
1958 std::string header() {
1959 return "@attributes " + name;
1962 /// \brief Writer function of the section.
1964 /// Write the content of the section.
1965 void write(std::ostream& os) {
1966 typename Writers::iterator it;
1967 for (it = writers.begin(); it != writers.end(); ++it) {
1968 os << it->first << ' ';
1969 it->second->write(os);
1974 /// \brief Gives back true when the section should be written.
1976 /// Gives back true when the section should be written.
1977 virtual bool valid() { return !writers.empty(); }
1982 typedef std::vector<std::pair<std::string,
1983 _writer_bits::ValueWriterBase*> > Writers;