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)];
148 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)];
172 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 nodes
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 bipartite graph's nodeset.
685 /// The lemon format can store multiple bipartite graph nodesets
686 /// with several maps. The nodeset section's header line is \c
687 /// \@bpnodeset \c bpnodeset_name, but the \c bpnodeset_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 node in the nodeset, and
691 /// contains the mapped values for each map.
693 /// If the nodeset contains an \c "label" named map then it will be regarded
694 /// as label map. This map should contain only unique values and when the
695 /// \c writeLabel() member will be called with a node it will write it's
696 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
697 /// then the label map will be the id in the graph. In addition if the
698 /// the \c _forceSort is true then the writer will write the edges
699 /// sorted by the labels.
701 /// \relates LemonWriter
702 template <typename _Graph, typename _Traits = DefaultWriterTraits>
703 class BpNodeSetWriter : public LemonWriter::SectionWriter {
704 typedef LemonWriter::SectionWriter Parent;
707 typedef _Graph Graph;
708 typedef _Traits Traits;
709 typedef typename Graph::Node Node;
711 /// \brief Constructor.
713 /// Constructor for BpNodeSetWriter. It creates the BpNodeSetWriter and
714 /// attach it into the given LemonWriter. If the \c _forceLabelMap
715 /// parameter is true then the writer will write own label map when
716 /// the user does not give "label" named map. In addition if the
717 /// the \c _forceSort is true then the writer will write the nodes
718 /// sorted by the labels.
719 BpNodeSetWriter(LemonWriter& _writer, const Graph& _graph,
720 const std::string& _name = std::string(),
721 bool _forceLabelMap = true, bool _forceSort = true)
722 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
723 forceSort(_forceSort), graph(_graph), name(_name) {}
725 /// \brief Destructor.
727 /// Destructor for BpNodeSetWriter.
728 virtual ~BpNodeSetWriter() {
729 typename MapWriters::iterator it;
730 for (it = writers.begin(); it != writers.end(); ++it) {
736 BpNodeSetWriter(const BpNodeSetWriter&);
737 void operator=(const BpNodeSetWriter&);
741 /// \brief Add a new A-node map writer command for the writer.
743 /// Add a new A-node map writer command for the writer.
744 template <typename Map>
745 BpNodeSetWriter& writeANodeMap(std::string label, const Map& map) {
746 return writeANodeMap<typename Traits::
747 template Writer<typename Map::Value>, Map>(label, map);
750 /// \brief Add a new A-node map writer command for the writer.
752 /// Add a new A-node map writer command for the writer.
753 template <typename ItemWriter, typename Map>
754 BpNodeSetWriter& writeANodeMap(std::string label, const Map& map,
755 const ItemWriter& iw = ItemWriter()) {
756 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
757 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
758 if (label == "label") {
759 throw IoParameterError("Label cannot be A-node map");
761 awriters.push_back(make_pair(label, new _writer_bits::
762 MapWriter<Node, Map, ItemWriter>(map, iw)));
766 /// \brief Add a new B-node map writer command for the writer.
768 /// Add a new B-node map writer command for the writer.
769 template <typename Map>
770 BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map) {
771 return writeBNodeMap<typename Traits::
772 template Writer<typename Map::Value>, Map>(label, map);
775 /// \brief Add a new B-node map writer command for the writer.
777 /// Add a new B-node map writer command for the writer.
778 template <typename ItemWriter, typename Map>
779 BpNodeSetWriter& writeBNodeMap(std::string label, const Map& map,
780 const ItemWriter& iw = ItemWriter()) {
781 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
782 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
783 if (label == "label") {
784 throw IoParameterError("Label cannot be B-node map");
786 bwriters.push_back(make_pair(label, new _writer_bits::
787 MapWriter<Node, Map, ItemWriter>(map, iw)));
791 /// \brief Add a new node map writer command for the writer.
793 /// Add a new node map writer command for the writer.
794 template <typename Map>
795 BpNodeSetWriter& writeNodeMap(std::string label, const Map& map) {
796 return writeNodeMap<typename Traits::
797 template Writer<typename Map::Value>, Map>(label, map);
800 /// \brief Add a new node map writer command for the writer.
802 /// Add a new node map writer command for the writer.
803 template <typename ItemWriter, typename Map>
804 BpNodeSetWriter& writeNodeMap(std::string label, const Map& map,
805 const ItemWriter& iw = ItemWriter()) {
806 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
807 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
808 writers.push_back(make_pair(label, new _writer_bits::
809 MapWriter<Node, Map, ItemWriter>(map, iw)));
815 /// \brief The header of the section.
817 /// It gives back the header of the section.
818 virtual std::string header() {
819 return "@bpnodeset " + name;
822 /// \brief Writer function of the section.
824 /// Write the content of the section.
825 virtual void write(std::ostream& os) {
826 for (int i = 0; i < int(writers.size()); ++i) {
827 if (writers[i].first == "label") {
828 labelMap = writers[i].second;
829 forceLabelMap = false;
835 std::vector<Node> items;
836 for (typename Graph::ANodeIt it(graph); it != INVALID; ++it) {
841 labelMap->sort(items);
843 typedef IdMap<Graph, Node> Map;
845 _writer_bits::ComposeLess<Map> less(map);
846 std::sort(items.begin(), items.end(), less);
852 for (int i = 0; i < int(writers.size()); ++i) {
853 os << writers[i].first << '\t';
855 for (int i = 0; i < int(awriters.size()); ++i) {
856 os << awriters[i].first << '\t';
859 for (typename std::vector<Node>::iterator it = items.begin();
860 it != items.end(); ++it) {
862 os << graph.id(*it) << '\t';
864 for (int i = 0; i < int(writers.size()); ++i) {
865 writers[i].second->write(os, *it);
868 for (int i = 0; i < int(awriters.size()); ++i) {
869 awriters[i].second->write(os, *it);
877 std::vector<Node> items;
878 for (typename Graph::BNodeIt it(graph); it != INVALID; ++it) {
883 labelMap->sort(items);
885 typedef IdMap<Graph, Node> Map;
887 _writer_bits::ComposeLess<Map> less(map);
888 std::sort(items.begin(), items.end(), less);
894 for (int i = 0; i < int(writers.size()); ++i) {
895 os << writers[i].first << '\t';
897 for (int i = 0; i < int(bwriters.size()); ++i) {
898 os << bwriters[i].first << '\t';
901 for (typename std::vector<Node>::iterator it = items.begin();
902 it != items.end(); ++it) {
904 os << graph.id(*it) << '\t';
906 for (int i = 0; i < int(writers.size()); ++i) {
907 writers[i].second->write(os, *it);
910 for (int i = 0; i < int(bwriters.size()); ++i) {
911 bwriters[i].second->write(os, *it);
921 /// \brief Returns true if the nodeset can write the labels of the nodes.
923 /// Returns true if the nodeset can write the labels of the nodes.
924 /// It is possible only if a "label" named map was written or the
925 /// \c _forceLabelMap constructor parameter was true.
926 bool isLabelWriter() const {
927 return labelMap != 0 || forceLabelMap;
930 /// \brief Write the label of the given node.
932 /// It writes the label of the given node. If there was written a "label"
933 /// named map then it will write the map value belongs to the node.
934 /// Otherwise if the \c forceLabel parameter was true it will write
935 /// its label in the graph.
936 void writeLabel(std::ostream& os, const Node& item) const {
938 os << graph.id(item);
940 labelMap->write(os, item);
944 /// \brief Sorts the given node vector by label.
946 /// Sorts the given node vector by label. If there was written an
947 /// "label" named map then the vector will be sorted by the values
948 /// of this map. Otherwise if the \c forceLabel parameter was true
949 /// it will be sorted by its id in the graph.
950 void sortByLabel(std::vector<Node>& nodes) const {
952 labelMap->sort(nodes);
954 typedef IdMap<Graph, Node> Map;
956 _writer_bits::ComposeLess<Map> less(map);
957 std::sort(nodes.begin(), nodes.end(), less);
963 typedef std::vector<std::pair<std::string, _writer_bits::
964 MapWriterBase<Node>*> > MapWriters;
965 MapWriters awriters, bwriters, writers;
967 _writer_bits::MapWriterBase<Node>* labelMap;
976 /// \ingroup section_io
977 /// \brief SectionWriter for writing a graph's edgesets.
979 /// The lemon format can store multiple graph edgesets with several maps.
980 /// The edgeset section's header line is \c \@edgeset \c edgeset_name, but
981 /// the \c edgeset_name may be empty.
983 /// The first line of the section contains the names of the maps separated
984 /// with white spaces. Each next lines describes a edge in the edgeset. The
985 /// line contains the source and the target nodes' label and the mapped
986 /// values for each map.
988 /// If the edgeset contains an \c "label" named map then it will be regarded
989 /// as label map. This map should contain only unique values and when the
990 /// \c writeLabel() member will be called with an edge it will write it's
991 /// label. Otherwise if the \c _forceLabelMap constructor parameter is true
992 /// then the label map will be the id in the graph. In addition if the
993 /// the \c _forceSort is true then the writer will write the edges
994 /// sorted by the labels.
996 /// The edgeset writer needs a node label writer to identify which nodes
997 /// have to be connected. If a NodeSetWriter can write the nodes' label,
998 /// it will be able to use with this class.
1000 /// \relates LemonWriter
1001 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1002 class EdgeSetWriter : public LemonWriter::SectionWriter {
1003 typedef LemonWriter::SectionWriter Parent;
1006 typedef _Graph Graph;
1007 typedef _Traits Traits;
1008 typedef typename Graph::Node Node;
1009 typedef typename Graph::Edge Edge;
1011 /// \brief Constructor.
1013 /// Constructor for EdgeSetWriter. It creates the EdgeSetWriter
1014 /// and attach it into the given LemonWriter. It will write node
1015 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
1016 /// parameter is true then the writer will write own label map if
1017 /// the user does not give "label" named map. In addition if the
1018 /// the \c _forceSort is true then the writer will write the
1019 /// edges sorted by the labels.
1020 template <typename NodeLabelWriter>
1021 EdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1022 const NodeLabelWriter& _nodeLabelWriter,
1023 const std::string& _name = std::string(),
1024 bool _forceLabelMap = true, bool _forceSort = true)
1025 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
1026 forceSort(_forceSort), graph(_graph), name(_name) {
1027 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
1028 nodeLabelWriter.reset(new _writer_bits::
1029 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
1032 /// \brief Destructor.
1034 /// Destructor for EdgeSetWriter.
1035 virtual ~EdgeSetWriter() {
1036 typename MapWriters::iterator it;
1037 for (it = writers.begin(); it != writers.end(); ++it) {
1043 EdgeSetWriter(const EdgeSetWriter&);
1044 void operator=(const EdgeSetWriter&);
1048 /// \brief Add a new edge map writer command for the writer.
1050 /// Add a new edge map writer command for the writer.
1051 template <typename Map>
1052 EdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
1053 return writeEdgeMap<typename Traits::
1054 template Writer<typename Map::Value>, Map>(label, map);
1057 /// \brief Add a new edge map writer command for the writer.
1059 /// Add a new edge map writer command for the writer.
1060 template <typename ItemWriter, typename Map>
1061 EdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
1062 const ItemWriter& iw = ItemWriter()) {
1063 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1064 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1066 make_pair(label, new _writer_bits::
1067 MapWriter<Edge, Map, ItemWriter>(map, iw)));
1073 /// \brief The header of the section.
1075 /// It gives back the header of the section.
1076 virtual std::string header() {
1077 return "@edgeset " + name;
1080 /// \brief Writer function of the section.
1082 /// Write the content of the section.
1083 virtual void write(std::ostream& os) {
1084 if (!nodeLabelWriter->isLabelWriter()) {
1085 throw DataFormatError("Cannot find nodeset or label map");
1087 for (int i = 0; i < int(writers.size()); ++i) {
1088 if (writers[i].first == "label") {
1089 labelMap = writers[i].second;
1090 forceLabelMap = false;
1094 std::vector<Edge> items;
1095 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1096 items.push_back(it);
1100 labelMap->sort(items);
1102 typedef IdMap<Graph, Edge> Map;
1104 _writer_bits::ComposeLess<Map> less(map);
1105 std::sort(items.begin(), items.end(), less);
1109 if (forceLabelMap) {
1112 for (int i = 0; i < int(writers.size()); ++i) {
1113 os << writers[i].first << '\t';
1116 for (typename std::vector<Edge>::iterator it = items.begin();
1117 it != items.end(); ++it) {
1118 nodeLabelWriter->write(os, graph.source(*it));
1120 nodeLabelWriter->write(os, graph.target(*it));
1122 if (forceLabelMap) {
1123 os << graph.id(*it) << '\t';
1125 for (int i = 0; i < int(writers.size()); ++i) {
1126 writers[i].second->write(os, *it);
1135 /// \brief Returns true if the edgeset can write the labels of the edges.
1137 /// Returns true if the edgeset can write the labels of the edges.
1138 /// It is possible only if a "label" named map was written or the
1139 /// \c _forceLabelMap constructor parameter was true.
1140 bool isLabelWriter() const {
1141 return forceLabelMap || labelMap != 0;
1144 /// \brief Write the label of the given edge.
1146 /// It writes the label of the given edge. If there was written a "label"
1147 /// named map then it will write the map value belongs to the edge.
1148 /// Otherwise if the \c forceLabel parameter was true it will write
1149 /// its label in the graph.
1150 void writeLabel(std::ostream& os, const Edge& item) const {
1151 if (forceLabelMap) {
1152 os << graph.id(item);
1154 labelMap->write(os, item);
1158 /// \brief Sorts the given edge vector by label.
1160 /// Sorts the given edge vector by label. If there was written an
1161 /// "label" named map then the vector will be sorted by the values
1162 /// of this map. Otherwise if the \c forceLabel parameter was true
1163 /// it will be sorted by its id in the graph.
1164 void sortByLabel(std::vector<Edge>& edges) const {
1166 labelMap->sort(edges);
1168 typedef IdMap<Graph, Edge> Map;
1170 _writer_bits::ComposeLess<Map> less(map);
1171 std::sort(edges.begin(), edges.end(), less);
1177 typedef std::vector<std::pair<std::string, _writer_bits::
1178 MapWriterBase<Edge>*> > MapWriters;
1181 _writer_bits::MapWriterBase<Edge>* labelMap;
1188 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
1191 /// \ingroup section_io
1192 /// \brief SectionWriter for writing a undirected edgeset.
1194 /// The lemon format can store multiple undirected edgesets with several
1195 /// maps. The undirected edgeset section's header line is \c \@uedgeset
1196 /// \c uedgeset_name, but the \c uedgeset_name may be empty.
1198 /// The first line of the section contains the names of the maps separated
1199 /// with white spaces. Each next lines describes an undirected edge in the
1200 /// edgeset. The line contains the two connected nodes' label and the mapped
1201 /// values for each undirected map.
1203 /// The section can handle the directed as a syntactical sugar. Two
1204 /// undirected edge map describes one directed edge map. This two maps
1205 /// are the forward map and the backward map and the names of this map
1206 /// is near the same just with a prefix \c '+' or \c '-' character
1209 /// If the edgeset contains an \c "label" named map then it will be
1210 /// regarded as label map. This map should contain only unique
1211 /// values and when the \c writeLabel() member will be called with
1212 /// an undirected edge it will write it's label. Otherwise if the \c
1213 /// _forceLabelMap constructor parameter is true then the label map
1214 /// will be the id in the graph. In addition if the the \c
1215 /// _forceSort is true then the writer will write the edges sorted
1218 /// The undirected edgeset writer needs a node label writer to identify
1219 /// which nodes have to be connected. If a NodeSetWriter can write the
1220 /// nodes' label, it will be able to use with this class.
1222 /// \relates LemonWriter
1223 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1224 class UEdgeSetWriter : public LemonWriter::SectionWriter {
1225 typedef LemonWriter::SectionWriter Parent;
1228 typedef _Graph Graph;
1229 typedef _Traits Traits;
1230 typedef typename Graph::Node Node;
1231 typedef typename Graph::Edge Edge;
1232 typedef typename Graph::UEdge UEdge;
1234 /// \brief Constructor.
1236 /// Constructor for UEdgeSetWriter. It creates the UEdgeSetWriter
1237 /// and attach it into the given LemonWriter. It will write node
1238 /// labels by the \c _nodeLabelWriter. If the \c _forceLabelMap
1239 /// parameter is true then the writer will write own label map if
1240 /// the user does not give "label" named map. In addition if the
1241 /// the \c _forceSort is true then the writer will write the
1242 /// edges sorted by the labels.
1243 template <typename NodeLabelWriter>
1244 UEdgeSetWriter(LemonWriter& _writer, const Graph& _graph,
1245 const NodeLabelWriter& _nodeLabelWriter,
1246 const std::string& _name = std::string(),
1247 bool _forceLabelMap = true, bool _forceSort = true)
1248 : Parent(_writer), labelMap(0), forceLabelMap(_forceLabelMap),
1249 forceSort(_forceSort), graph(_graph), name(_name) {
1250 checkConcept<_writer_bits::ItemLabelWriter<Node>, NodeLabelWriter>();
1251 nodeLabelWriter.reset(new _writer_bits::
1252 LabelWriter<Node, NodeLabelWriter>(_nodeLabelWriter));
1255 /// \brief Destructor.
1257 /// Destructor for UEdgeSetWriter.
1258 virtual ~UEdgeSetWriter() {
1259 typename MapWriters::iterator it;
1260 for (it = writers.begin(); it != writers.end(); ++it) {
1266 UEdgeSetWriter(const UEdgeSetWriter&);
1267 void operator=(const UEdgeSetWriter&);
1271 /// \brief Add a new undirected edge map writer command for the writer.
1273 /// Add a new undirected map writer command for the writer.
1274 template <typename Map>
1275 UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map) {
1276 return writeUEdgeMap<typename Traits::
1277 template Writer<typename Map::Value>, Map>(label, map);
1280 /// \brief Add a new undirected map writer command for the writer.
1282 /// Add a new undirected map writer command for the writer.
1283 template <typename ItemWriter, typename Map>
1284 UEdgeSetWriter& writeUEdgeMap(std::string label, const Map& map,
1285 const ItemWriter& iw = ItemWriter()) {
1286 checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
1287 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1289 make_pair(label, new _writer_bits::
1290 UEdgeMapWriter<Graph, Map, ItemWriter>(map, iw)));
1294 /// \brief Add a new directed edge map writer command for the writer.
1296 /// Add a new directed map writer command for the writer.
1297 template <typename Map>
1298 UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map) {
1299 return writeEdgeMap<typename Traits::
1300 template Writer<typename Map::Value>, Map>(label, map);
1303 /// \brief Add a new directed map writer command for the writer.
1305 /// Add a new directed map writer command for the writer.
1306 template <typename ItemWriter, typename Map>
1307 UEdgeSetWriter& writeEdgeMap(std::string label, const Map& map,
1308 const ItemWriter& iw = ItemWriter()) {
1309 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1310 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
1311 writeUEdgeMap("+" + label,
1312 _writer_bits::forwardComposeMap(graph, map), iw);
1313 writeUEdgeMap("-" + label,
1314 _writer_bits::backwardComposeMap(graph, map), iw);
1320 /// \brief The header of the section.
1322 /// It gives back the header of the section.
1323 virtual std::string header() {
1324 return "@uedgeset " + name;
1327 /// \brief Writer function of the section.
1329 /// Write the content of the section.
1330 virtual void write(std::ostream& os) {
1331 if (!nodeLabelWriter->isLabelWriter()) {
1332 throw DataFormatError("Cannot find nodeset or label map");
1334 for (int i = 0; i < int(writers.size()); ++i) {
1335 if (writers[i].first == "label") {
1336 labelMap = writers[i].second;
1337 forceLabelMap = false;
1341 std::vector<UEdge> items;
1342 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
1343 items.push_back(it);
1347 labelMap->sort(items);
1349 typedef IdMap<Graph, UEdge> Map;
1351 _writer_bits::ComposeLess<Map> less(map);
1352 std::sort(items.begin(), items.end(), less);
1356 if (forceLabelMap) {
1359 for (int i = 0; i < int(writers.size()); ++i) {
1360 os << writers[i].first << '\t';
1363 for (typename std::vector<UEdge>::iterator it = items.begin();
1364 it != items.end(); ++it) {
1365 nodeLabelWriter->write(os, graph.source(*it));
1367 nodeLabelWriter->write(os, graph.target(*it));
1369 if (forceLabelMap) {
1370 os << graph.id(*it) << '\t';
1372 for (int i = 0; i < int(writers.size()); ++i) {
1373 writers[i].second->write(os, *it);
1382 /// \brief Returns true if the undirected edgeset can write the labels of
1385 /// Returns true if the undirected edgeset can write the labels of the
1386 /// undirected edges. It is possible only if a "label" named map was
1387 /// written or the \c _forceLabelMap constructor parameter was true.
1388 bool isLabelWriter() const {
1389 return forceLabelMap || labelMap != 0;
1392 /// \brief Write the label of the given undirected edge.
1394 /// It writes the label of the given undirected edge. If there was written
1395 /// a "label" named map then it will write the map value belongs to the
1396 /// undirected edge. Otherwise if the \c forceLabel parameter was true it
1397 /// will write its id in the graph.
1398 void writeLabel(std::ostream& os, const UEdge& item) const {
1399 if (forceLabelMap) {
1400 os << graph.id(item);
1402 labelMap->write(os, item);
1406 /// \brief Write the label of the given edge.
1408 /// It writes the label of the given edge. If there was written
1409 /// a "label" named map then it will write the map value belongs to the
1410 /// edge. Otherwise if the \c forceLabel parameter was true it
1411 /// will write its id in the graph. If the edge is forward map
1412 /// then its prefix character is \c '+' elsewhere \c '-'.
1413 void writeLabel(std::ostream& os, const Edge& item) const {
1414 if (graph.direction(item)) {
1419 if (forceLabelMap) {
1420 os << graph.id(static_cast<const UEdge&>(item));
1422 labelMap->write(os, item);
1426 /// \brief Sorts the given undirected edge vector by label.
1428 /// Sorts the given undirected edge vector by label. If there was
1429 /// written a "label" named map then the vector will be sorted by
1430 /// the values of this map. Otherwise if the \c forceLabel
1431 /// parameter was true it will be sorted by its id in the graph.
1432 void sortByLabel(std::vector<UEdge>& uedges) const {
1434 labelMap->sort(uedges);
1436 typedef IdMap<Graph, UEdge> Map;
1438 _writer_bits::ComposeLess<Map> less(map);
1439 std::sort(uedges.begin(), uedges.end(), less);
1443 /// \brief Sorts the given edge vector by label.
1445 /// Sorts the given edge vector by label. If there was written a
1446 /// "label" named map then the vector will be sorted by the values
1447 /// of this map. Otherwise if the \c forceLabel parameter was true
1448 /// it will be sorted by its id in the graph.
1449 void sortByLabel(std::vector<Edge>& edges) const {
1451 labelMap->sort(graph, edges);
1453 typedef IdMap<Graph, Edge> Map;
1455 _writer_bits::ComposeLess<Map> less(map);
1456 std::sort(edges.begin(), edges.end(), less);
1462 typedef std::vector<std::pair<std::string, _writer_bits::
1463 UEdgeMapWriterBase<Graph>*> > MapWriters;
1466 _writer_bits::UEdgeMapWriterBase<Graph>* labelMap;
1473 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > nodeLabelWriter;
1476 /// \ingroup section_io
1477 /// \brief SectionWriter for writing named nodes.
1479 /// The nodes section's header line is \c \@nodes \c nodes_name, but the
1480 /// \c nodes_name may be empty.
1482 /// Each line in the section contains the name of the node and
1483 /// then the node label.
1485 /// \relates LemonWriter
1486 template <typename _Graph>
1487 class NodeWriter : public LemonWriter::SectionWriter {
1488 typedef LemonWriter::SectionWriter Parent;
1489 typedef _Graph Graph;
1490 typedef typename Graph::Node Node;
1493 /// \brief Constructor.
1495 /// Constructor for NodeWriter. It creates the NodeWriter and
1496 /// attach it into the given LemonWriter. The given \c _LabelWriter
1497 /// will write the nodes' label what can be a nodeset writer.
1498 template <typename _LabelWriter>
1499 NodeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1500 const std::string& _name = std::string())
1501 : Parent(_writer), name(_name) {
1502 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1503 labelWriter.reset(new _writer_bits::LabelWriter<Node, _LabelWriter>
1508 /// \brief Destructor.
1510 /// Destructor for NodeWriter.
1511 virtual ~NodeWriter() {}
1514 NodeWriter(const NodeWriter&);
1515 void operator=(const NodeWriter&);
1519 /// \brief Add a node writer command for the NodeWriter.
1521 /// Add a node writer command for the NodeWriter.
1522 void writeNode(std::string label, const Node& item) {
1523 writers.push_back(make_pair(label, &item));
1528 /// \brief The header of the section.
1530 /// It gives back the header of the section.
1531 virtual std::string header() {
1532 return "@nodes " + name;
1535 /// \brief Writer function of the section.
1537 /// Write the content of the section.
1538 virtual void write(std::ostream& os) {
1539 if (!labelWriter->isLabelWriter()) {
1540 throw DataFormatError("Cannot find nodeset or label map");
1542 for (int i = 0; i < int(writers.size()); ++i) {
1543 os << writers[i].first << ' ';
1544 labelWriter->write(os, *(writers[i].second));
1549 /// \brief Gives back true when the section should be written.
1551 /// Gives back true when the section should be written.
1552 virtual bool valid() { return !writers.empty(); }
1558 typedef std::vector<std::pair<std::string, const Node*> > NodeWriters;
1559 NodeWriters writers;
1560 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1563 /// \ingroup section_io
1564 /// \brief SectionWriter for writing named edges.
1566 /// The edges section's header line is \c \@edges \c edges_name, but the
1567 /// \c edges_name may be empty.
1569 /// Each line in the section contains the name of the edge and
1570 /// then the edge label.
1572 /// \relates LemonWriter
1573 template <typename _Graph>
1574 class EdgeWriter : public LemonWriter::SectionWriter {
1575 typedef LemonWriter::SectionWriter Parent;
1576 typedef _Graph Graph;
1577 typedef typename Graph::Edge Edge;
1580 /// \brief Constructor.
1582 /// Constructor for EdgeWriter. It creates the EdgeWriter and
1583 /// attach it into the given LemonWriter. The given \c _LabelWriter
1584 /// will write the edges' label what can be a edgeset writer.
1585 template <typename _LabelWriter>
1586 EdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1587 const std::string& _name = std::string())
1588 : Parent(_writer), name(_name) {
1589 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1590 labelWriter.reset(new _writer_bits::LabelWriter<Edge, _LabelWriter>(_labelWriter));
1593 /// \brief Destructor.
1595 /// Destructor for EdgeWriter.
1596 virtual ~EdgeWriter() {}
1598 EdgeWriter(const EdgeWriter&);
1599 void operator=(const EdgeWriter&);
1603 /// \brief Add an edge writer command for the EdgeWriter.
1605 /// Add an edge writer command for the EdgeWriter.
1606 void writeEdge(std::string label, const Edge& item) {
1607 writers.push_back(make_pair(label, &item));
1612 /// \brief The header of the section.
1614 /// It gives back the header of the section.
1615 virtual std::string header() {
1616 return "@edges " + name;
1619 /// \brief Writer function of the section.
1621 /// Write the content of the section.
1622 virtual void write(std::ostream& os) {
1623 if (!labelWriter->isLabelWriter()) {
1624 throw DataFormatError("Cannot find edgeset or label map");
1626 for (int i = 0; i < int(writers.size()); ++i) {
1627 os << writers[i].first << ' ';
1628 labelWriter->write(os, *(writers[i].second));
1633 /// \brief Gives back true when the section should be written.
1635 /// Gives back true when the section should be written.
1636 virtual bool valid() { return !writers.empty(); }
1642 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1643 EdgeWriters writers;
1645 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
1649 /// \ingroup section_io
1650 /// \brief SectionWriter for writing named undirected edges.
1652 /// The undirected edges section's header line is \c \@uedges
1653 /// \c uedges_name, but the \c uedges_name may be empty.
1655 /// Each line in the section contains the name of the undirected edge and
1656 /// then the undirected edge label.
1658 /// \relates LemonWriter
1659 template <typename _Graph>
1660 class UEdgeWriter : public LemonWriter::SectionWriter {
1661 typedef LemonWriter::SectionWriter Parent;
1662 typedef _Graph Graph;
1663 typedef typename Graph::Node Node;
1664 typedef typename Graph::Edge Edge;
1665 typedef typename Graph::UEdge UEdge;
1668 /// \brief Constructor.
1670 /// Constructor for UEdgeWriter. It creates the UEdgeWriter and
1671 /// attach it into the given LemonWriter. The given \c _LabelWriter
1672 /// will write the undirected edges' label what can be an undirected
1674 template <typename _LabelWriter>
1675 UEdgeWriter(LemonWriter& _writer, const _LabelWriter& _labelWriter,
1676 const std::string& _name = std::string())
1677 : Parent(_writer), name(_name) {
1678 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1679 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
1680 uEdgeLabelWriter.reset(new _writer_bits::
1681 LabelWriter<UEdge, _LabelWriter>(_labelWriter));
1682 edgeLabelWriter.reset(new _writer_bits::
1683 LabelWriter<Edge, _LabelWriter>(_labelWriter));
1686 /// \brief Destructor.
1688 /// Destructor for UEdgeWriter.
1689 virtual ~UEdgeWriter() {}
1691 UEdgeWriter(const UEdgeWriter&);
1692 void operator=(const UEdgeWriter&);
1696 /// \brief Add an edge writer command for the UEdgeWriter.
1698 /// Add an edge writer command for the UEdgeWriter.
1699 void writeEdge(std::string label, const Edge& item) {
1700 edgeWriters.push_back(make_pair(label, &item));
1703 /// \brief Add an undirected edge writer command for the UEdgeWriter.
1705 /// Add an undirected edge writer command for the UEdgeWriter.
1706 void writeUEdge(std::string label, const UEdge& item) {
1707 uEdgeWriters.push_back(make_pair(label, &item));
1712 /// \brief The header of the section.
1714 /// It gives back the header of the section.
1715 virtual std::string header() {
1716 return "@uedges " + name;
1719 /// \brief Writer function of the section.
1721 /// Write the content of the section.
1722 virtual void write(std::ostream& os) {
1723 if (!edgeLabelWriter->isLabelWriter()) {
1724 throw DataFormatError("Cannot find undirected edgeset or label map");
1726 if (!uEdgeLabelWriter->isLabelWriter()) {
1727 throw DataFormatError("Cannot find undirected edgeset or label map");
1729 for (int i = 0; i < int(uEdgeWriters.size()); ++i) {
1730 os << uEdgeWriters[i].first << ' ';
1731 uEdgeLabelWriter->write(os, *(uEdgeWriters[i].second));
1734 for (int i = 0; i < int(edgeWriters.size()); ++i) {
1735 os << edgeWriters[i].first << ' ';
1736 edgeLabelWriter->write(os, *(edgeWriters[i].second));
1741 /// \brief Gives back true when the section should be written.
1743 /// Gives back true when the section should be written.
1744 virtual bool valid() {
1745 return !uEdgeWriters.empty() || !edgeWriters.empty();
1752 typedef std::vector<std::pair<std::string,
1753 const UEdge*> > UEdgeWriters;
1754 UEdgeWriters uEdgeWriters;
1755 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > uEdgeLabelWriter;
1757 typedef std::vector<std::pair<std::string, const Edge*> > EdgeWriters;
1758 EdgeWriters edgeWriters;
1759 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > edgeLabelWriter;
1763 /// \ingroup section_io
1764 /// \brief SectionWriter for writing extra node maps.
1766 /// The lemon format can store maps in the nodeset. This class let
1767 /// you make distinict section to store maps. The main purpose of
1768 /// this class is a logical separation of some maps. The other
1769 /// useful application could be to store paths in node maps.
1771 /// The first line of the section contains the names of the maps
1772 /// separated with white spaces. Each next line describes an item
1773 /// in the itemset, and contains in the first column the label of
1774 /// the item and then the mapped values for each map.
1776 /// \relates LemonWriter
1777 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1778 class NodeMapWriter : public LemonWriter::SectionWriter {
1779 typedef LemonWriter::SectionWriter Parent;
1782 typedef _Graph Graph;
1783 typedef _Traits Traits;
1784 typedef typename Graph::Node Node;
1786 /// \brief Constructor.
1788 /// Constructor for NodeMapWriter. It creates the NodeMapWriter and
1789 /// attach it into the given LemonWriter. If the the
1790 /// \c _forceSort is true then the writer will write the edges
1791 /// sorted by the labels.
1792 template <typename _LabelWriter>
1793 NodeMapWriter(LemonWriter& _writer, const Graph& _graph,
1794 const _LabelWriter& _labelWriter,
1795 const std::string& _name = std::string(),
1796 bool _forceSort = true)
1797 : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1798 checkConcept<_writer_bits::ItemLabelWriter<Node>, _LabelWriter>();
1799 labelWriter.reset(new _writer_bits::LabelWriter<Node,
1800 _LabelWriter>(_labelWriter));
1803 /// \brief Destructor.
1805 /// Destructor for NodeMapWriter.
1806 virtual ~NodeMapWriter() {
1807 typename MapWriters::iterator it;
1808 for (it = writers.begin(); it != writers.end(); ++it) {
1814 NodeMapWriter(const NodeMapWriter&);
1815 void operator=(const NodeMapWriter&);
1819 /// \brief Add a new node map writer command for the writer.
1821 /// Add a new node map writer command for the writer.
1822 template <typename Map>
1823 NodeMapWriter& writeNodeMap(std::string label, const Map& map) {
1824 return writeNodeMap<typename Traits::
1825 template Writer<typename Map::Value>, Map>(label, map);
1828 /// \brief Add a new node map writer command for the writer.
1830 /// Add a new node map writer command for the writer.
1831 template <typename ItemWriter, typename Map>
1832 NodeMapWriter& writeNodeMap(std::string label, const Map& map,
1833 const ItemWriter& iw = ItemWriter()) {
1834 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1835 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1837 make_pair(label, new _writer_bits::
1838 MapWriter<Node, Map, ItemWriter>(map, iw)));
1844 /// \brief The header of the section.
1846 /// It gives back the header of the section.
1847 virtual std::string header() {
1848 return "@nodemaps " + name;
1851 /// \brief Writer function of the section.
1853 /// Write the content of the section.
1854 virtual void write(std::ostream& os) {
1855 std::vector<Node> nodes;
1856 for (typename Graph::NodeIt it(graph); it != INVALID; ++it) {
1857 nodes.push_back(it);
1860 labelWriter->sort(nodes);
1863 for (int i = 0; i < int(writers.size()); ++i) {
1864 os << writers[i].first << '\t';
1867 for (typename std::vector<Node>::iterator it = nodes.begin();
1868 it != nodes.end(); ++it) {
1870 labelWriter->write(os, *it); os << '\t';
1871 for (int i = 0; i < int(writers.size()); ++i) {
1872 writers[i].second->write(os, *it);
1882 typedef std::vector<std::pair<std::string, _writer_bits::
1883 MapWriterBase<Node>*> > MapWriters;
1886 _writer_bits::MapWriterBase<Node>* labelMap;
1892 std::auto_ptr<_writer_bits::LabelWriterBase<Node> > labelWriter;
1895 /// \ingroup section_io
1896 /// \brief SectionWriter for writing extra edge maps.
1898 /// The lemon format can store maps in the edgeset. This class let
1899 /// you make distinict section to store maps. The main purpose of
1900 /// this class is a logical separation of some maps. The other
1901 /// useful application could be to store paths in edge maps.
1903 /// The first line of the section contains the names of the maps
1904 /// separated with white spaces. Each next line describes an item
1905 /// in the itemset, and contains in the first column the label of
1906 /// the item and then the mapped values for each map.
1908 /// \relates LemonWriter
1909 template <typename _Graph, typename _Traits = DefaultWriterTraits>
1910 class EdgeMapWriter : public LemonWriter::SectionWriter {
1911 typedef LemonWriter::SectionWriter Parent;
1914 typedef _Graph Graph;
1915 typedef _Traits Traits;
1916 typedef typename Graph::Edge Edge;
1918 /// \brief Constructor.
1920 /// Constructor for EdgeMapWriter. It creates the EdgeMapWriter and
1921 /// attach it into the given LemonWriter. If the the
1922 /// \c _forceSort is true then the writer will write the edges
1923 /// sorted by the labels.
1924 template <typename _LabelWriter>
1925 EdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
1926 const _LabelWriter& _labelWriter,
1927 const std::string& _name = std::string(),
1928 bool _forceSort = true)
1929 : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
1930 checkConcept<_writer_bits::ItemLabelWriter<Edge>, _LabelWriter>();
1931 labelWriter.reset(new _writer_bits::LabelWriter<Edge,
1932 _LabelWriter>(_labelWriter));
1935 /// \brief Destructor.
1937 /// Destructor for EdgeMapWriter.
1938 virtual ~EdgeMapWriter() {
1939 typename MapWriters::iterator it;
1940 for (it = writers.begin(); it != writers.end(); ++it) {
1946 EdgeMapWriter(const EdgeMapWriter&);
1947 void operator=(const EdgeMapWriter&);
1951 /// \brief Add a new edge map writer command for the writer.
1953 /// Add a new edge map writer command for the writer.
1954 template <typename Map>
1955 EdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
1956 return writeEdgeMap<typename Traits::
1957 template Writer<typename Map::Value>, Map>(label, map);
1960 /// \brief Add a new edge map writer command for the writer.
1962 /// Add a new edge map writer command for the writer.
1963 template <typename ItemWriter, typename Map>
1964 EdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
1965 const ItemWriter& iw = ItemWriter()) {
1966 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1967 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
1969 make_pair(label, new _writer_bits::
1970 MapWriter<Edge, Map, ItemWriter>(map, iw)));
1976 /// \brief The header of the section.
1978 /// It gives back the header of the section.
1979 virtual std::string header() {
1980 return "@edgemaps " + name;
1983 /// \brief Writer function of the section.
1985 /// Write the content of the section.
1986 virtual void write(std::ostream& os) {
1987 std::vector<Edge> edges;
1988 for (typename Graph::EdgeIt it(graph); it != INVALID; ++it) {
1989 edges.push_back(it);
1992 labelWriter->sort(edges);
1995 for (int i = 0; i < int(writers.size()); ++i) {
1996 os << writers[i].first << '\t';
1999 for (typename std::vector<Edge>::iterator it = edges.begin();
2000 it != edges.end(); ++it) {
2002 labelWriter->write(os, *it); os << '\t';
2003 for (int i = 0; i < int(writers.size()); ++i) {
2004 writers[i].second->write(os, *it);
2014 typedef std::vector<std::pair<std::string, _writer_bits::
2015 MapWriterBase<Edge>*> > MapWriters;
2018 _writer_bits::MapWriterBase<Edge>* labelMap;
2024 std::auto_ptr<_writer_bits::LabelWriterBase<Edge> > labelWriter;
2027 /// \ingroup section_io
2028 /// \brief SectionWriter for writing extra undirected edge maps.
2030 /// The lemon format can store maps in the uedgeset. This class let
2031 /// you make distinict section to store maps. The main purpose of
2032 /// this class is a logical separation of some maps. The other
2033 /// useful application could be to store paths in undirected edge
2036 /// The first line of the section contains the names of the maps
2037 /// separated with white spaces. Each next line describes an item
2038 /// in the itemset, and contains in the first column the label of
2039 /// the item and then the mapped values for each map.
2041 /// \relates LemonWriter
2042 template <typename _Graph, typename _Traits = DefaultWriterTraits>
2043 class UEdgeMapWriter : public LemonWriter::SectionWriter {
2044 typedef LemonWriter::SectionWriter Parent;
2047 typedef _Graph Graph;
2048 typedef _Traits Traits;
2049 typedef typename Graph::UEdge UEdge;
2050 typedef typename Graph::Edge Edge;
2052 /// \brief Constructor.
2054 /// Constructor for UEdgeMapWriter. It creates the UEdgeMapWriter and
2055 /// attach it into the given LemonWriter. If the the
2056 /// \c _forceSort is true then the writer will write the uedges
2057 /// sorted by the labels.
2058 template <typename _LabelWriter>
2059 UEdgeMapWriter(LemonWriter& _writer, const Graph& _graph,
2060 const _LabelWriter& _labelWriter,
2061 const std::string& _name = std::string(),
2062 bool _forceSort = true)
2063 : Parent(_writer), graph(_graph), name(_name), forceSort(_forceSort) {
2064 checkConcept<_writer_bits::ItemLabelWriter<UEdge>, _LabelWriter>();
2065 labelWriter.reset(new _writer_bits::LabelWriter<UEdge,
2066 _LabelWriter>(_labelWriter));
2069 /// \brief Destructor.
2071 /// Destructor for UEdgeMapWriter.
2072 virtual ~UEdgeMapWriter() {
2073 typename MapWriters::iterator it;
2074 for (it = writers.begin(); it != writers.end(); ++it) {
2080 UEdgeMapWriter(const UEdgeMapWriter&);
2081 void operator=(const UEdgeMapWriter&);
2085 /// \brief Add a new undirected edge map writer command for the writer.
2087 /// Add a new undirected edge map writer command for the writer.
2088 template <typename Map>
2089 UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map) {
2090 return writeUEdgeMap<typename Traits::
2091 template Writer<typename Map::Value>, Map>(label, map);
2094 /// \brief Add a new undirected edge map writer command for the writer.
2096 /// Add a new undirected edge map writer command for the writer.
2097 template <typename ItemWriter, typename Map>
2098 UEdgeMapWriter& writeUEdgeMap(std::string label, const Map& map,
2099 const ItemWriter& iw = ItemWriter()) {
2100 checkConcept<concepts::ReadMap<UEdge, typename Map::Value>, Map>();
2101 checkConcept<_writer_bits::ItemWriter<typename Map::Value>,ItemWriter>();
2103 make_pair(label, new _writer_bits::
2104 MapWriter<UEdge, Map, ItemWriter>(map, iw)));
2108 /// \brief Add a new directed edge map writer command for the writer.
2110 /// Add a new directed map writer command for the writer.
2111 template <typename Map>
2112 UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map) {
2113 return writeEdgeMap<typename Traits::
2114 template Writer<typename Map::Value>, Map>(label, map);
2117 /// \brief Add a new directed map writer command for the writer.
2119 /// Add a new directed map writer command for the writer.
2120 template <typename ItemWriter, typename Map>
2121 UEdgeMapWriter& writeEdgeMap(std::string label, const Map& map,
2122 const ItemWriter& iw = ItemWriter()) {
2123 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
2124 checkConcept<_writer_bits::ItemWriter<typename Map::Value>, ItemWriter>();
2125 writeUEdgeMap("+" + label,
2126 _writer_bits::forwardComposeMap(graph, map), iw);
2127 writeUEdgeMap("-" + label,
2128 _writer_bits::backwardComposeMap(graph, map), iw);
2134 /// \brief The header of the section.
2136 /// It gives back the header of the section.
2137 virtual std::string header() {
2138 return "@uedgemaps " + name;
2141 /// \brief Writer function of the section.
2143 /// Write the content of the section.
2144 virtual void write(std::ostream& os) {
2145 std::vector<UEdge> uedges;
2146 for (typename Graph::UEdgeIt it(graph); it != INVALID; ++it) {
2147 uedges.push_back(it);
2150 labelWriter->sort(uedges);
2153 for (int i = 0; i < int(writers.size()); ++i) {
2154 os << writers[i].first << '\t';
2157 for (typename std::vector<UEdge>::iterator it = uedges.begin();
2158 it != uedges.end(); ++it) {
2160 labelWriter->write(os, *it); os << '\t';
2161 for (int i = 0; i < int(writers.size()); ++i) {
2162 writers[i].second->write(os, *it);
2172 typedef std::vector<std::pair<std::string, _writer_bits::
2173 MapWriterBase<UEdge>*> > MapWriters;
2176 _writer_bits::MapWriterBase<UEdge>* labelMap;
2182 std::auto_ptr<_writer_bits::LabelWriterBase<UEdge> > labelWriter;
2186 /// \ingroup section_io
2187 /// \brief SectionWriter for attributes.
2189 /// The lemon format can store multiple attribute set. Each set has
2190 /// the header line \c \@attributes \c attributes_name, but the
2191 /// attributeset_name may be empty.
2193 /// The attributeset section contains several lines. Each of them starts
2194 /// with the name of attribute and then the value.
2196 /// \relates LemonWriter
2197 template <typename _Traits = DefaultWriterTraits>
2198 class AttributeWriter : public LemonWriter::SectionWriter {
2199 typedef LemonWriter::SectionWriter Parent;
2200 typedef _Traits Traits;
2202 /// \brief Constructor.
2204 /// Constructor for AttributeWriter. It creates the AttributeWriter and
2205 /// attach it into the given LemonWriter.
2206 AttributeWriter(LemonWriter& _writer,
2207 const std::string& _name = std::string())
2208 : Parent(_writer), name(_name) {}
2210 /// \brief Destructor.
2212 /// Destructor for AttributeWriter.
2213 virtual ~AttributeWriter() {
2214 typename Writers::iterator it;
2215 for (it = writers.begin(); it != writers.end(); ++it) {
2221 AttributeWriter(const AttributeWriter&);
2222 void operator=(AttributeWriter&);
2225 /// \brief Add an attribute writer command for the writer.
2227 /// Add an attribute writer command for the writer.
2228 template <typename Value>
2229 AttributeWriter& writeAttribute(std::string label,
2230 const Value& value) {
2232 writeAttribute<typename Traits::template Writer<Value> >(label, value);
2235 /// \brief Add an attribute writer command for the writer.
2237 /// Add an attribute writer command for the writer.
2238 template <typename ItemWriter, typename Value>
2239 AttributeWriter& writeAttribute(std::string label, const Value& value,
2240 const ItemWriter& iw = ItemWriter()) {
2241 checkConcept<_writer_bits::ItemWriter<Value>, ItemWriter>();
2242 writers.push_back(make_pair(label, new _writer_bits::
2243 ValueWriter<Value, ItemWriter>(value, iw)));
2249 /// \brief The header of section.
2251 /// It gives back the header of the section.
2252 std::string header() {
2253 return "@attributes " + name;
2256 /// \brief Writer function of the section.
2258 /// Write the content of the section.
2259 void write(std::ostream& os) {
2260 typename Writers::iterator it;
2261 for (it = writers.begin(); it != writers.end(); ++it) {
2262 os << it->first << ' ';
2263 it->second->write(os);
2268 /// \brief Gives back true when the section should be written.
2270 /// Gives back true when the section should be written.
2271 virtual bool valid() { return !writers.empty(); }
2276 typedef std::vector<std::pair<std::string,
2277 _writer_bits::ValueWriterBase*> > Writers;