3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
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 Graph Format writer.
24 #ifndef LEMON_LGF_WRITER_H
25 #define LEMON_LGF_WRITER_H
36 #include <lemon/assert.h>
37 #include <lemon/graph_utils.h>
41 namespace _writer_bits {
43 template <typename Value>
44 struct DefaultConverter {
45 std::string operator()(const Value& value) {
46 std::ostringstream os;
53 bool operator<(const T&, const T&) {
54 throw DataFormatError("Label map is not comparable");
57 template <typename _Map>
61 typedef typename Map::Key Item;
67 MapLess(const Map& map) : _map(map) {}
69 bool operator()(const Item& left, const Item& right) {
70 return _map[left] < _map[right];
74 template <typename _Graph, bool _dir, typename _Map>
75 class GraphArcMapLess {
79 typedef typename Graph::Edge Item;
86 GraphArcMapLess(const Graph& graph, const Map& map)
87 : _graph(graph), _map(map) {}
89 bool operator()(const Item& left, const Item& right) {
90 return _map[_graph.direct(left, _dir)] <
91 _map[_graph.direct(right, _dir)];
95 template <typename _Item>
96 class MapStorageBase {
102 virtual ~MapStorageBase() {}
104 virtual std::string get(const Item& item) = 0;
105 virtual void sort(std::vector<Item>&) = 0;
108 template <typename _Item, typename _Map,
109 typename _Converter = DefaultConverter<typename _Map::Value> >
110 class MapStorage : public MapStorageBase<_Item> {
113 typedef _Converter Converter;
118 Converter _converter;
121 MapStorage(const Map& map, const Converter& converter = Converter())
122 : _map(map), _converter(converter) {}
123 virtual ~MapStorage() {}
125 virtual std::string get(const Item& item) {
126 return _converter(_map[item]);
128 virtual void sort(std::vector<Item>& items) {
129 MapLess<Map> less(_map);
130 std::sort(items.begin(), items.end(), less);
134 template <typename _Graph, bool _dir, typename _Map,
135 typename _Converter = DefaultConverter<typename _Map::Value> >
136 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
139 typedef _Converter Converter;
140 typedef _Graph Graph;
141 typedef typename Graph::Edge Item;
142 static const bool dir = _dir;
147 Converter _converter;
150 GraphArcMapStorage(const Graph& graph, const Map& map,
151 const Converter& converter = Converter())
152 : _graph(graph), _map(map), _converter(converter) {}
153 virtual ~GraphArcMapStorage() {}
155 virtual std::string get(const Item& item) {
156 return _converter(_map[_graph.direct(item, dir)]);
158 virtual void sort(std::vector<Item>& items) {
159 GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
160 std::sort(items.begin(), items.end(), less);
164 class ValueStorageBase {
166 ValueStorageBase() {}
167 virtual ~ValueStorageBase() {}
169 virtual std::string get() = 0;
172 template <typename _Value, typename _Converter = DefaultConverter<_Value> >
173 class ValueStorage : public ValueStorageBase {
175 typedef _Value Value;
176 typedef _Converter Converter;
180 Converter _converter;
183 ValueStorage(const Value& value, const Converter& converter = Converter())
184 : _value(value), _converter(converter) {}
186 virtual std::string get() {
187 return _converter(_value);
191 template <typename Value>
192 struct MapLookUpConverter {
193 const std::map<Value, std::string>& _map;
195 MapLookUpConverter(const std::map<Value, std::string>& map)
198 std::string operator()(const Value& str) {
199 typename std::map<Value, std::string>::const_iterator it =
201 if (it == _map.end()) {
202 throw DataFormatError("Item not found");
208 template <typename Graph>
209 struct GraphArcLookUpConverter {
211 const std::map<typename Graph::Edge, std::string>& _map;
213 GraphArcLookUpConverter(const Graph& graph,
214 const std::map<typename Graph::Edge,
216 : _graph(graph), _map(map) {}
218 std::string operator()(const typename Graph::Arc& val) {
219 typename std::map<typename Graph::Edge, std::string>
220 ::const_iterator it = _map.find(val);
221 if (it == _map.end()) {
222 throw DataFormatError("Item not found");
224 return (_graph.direction(val) ? '+' : '-') + it->second;
228 bool isWhiteSpace(char c) {
229 return c == ' ' || c == '\t' || c == '\v' ||
230 c == '\n' || c == '\r' || c == '\f';
233 bool isEscaped(char c) {
234 return c == '\\' || c == '\"' || c == '\'' ||
235 c == '\a' || c == '\b';
238 static void writeEscape(std::ostream& os, char c) {
269 std::ios::fmtflags flags = os.flags();
270 os << '\\' << std::oct << static_cast<int>(c);
279 bool requireEscape(const std::string& str) {
280 if (str.empty() || str[0] == '@') return true;
281 std::istringstream is(str);
284 if (isWhiteSpace(c) || isEscaped(c)) {
291 std::ostream& writeToken(std::ostream& os, const std::string& str) {
293 if (requireEscape(str)) {
295 for (std::string::const_iterator it = str.begin();
296 it != str.end(); ++it) {
297 writeEscape(os, *it);
308 template <typename Digraph>
311 template <typename Digraph>
312 DigraphWriter<Digraph> digraphWriter(std::ostream& os,
313 const Digraph& digraph);
315 template <typename Digraph>
316 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
317 const Digraph& digraph);
319 template <typename Digraph>
320 DigraphWriter<Digraph> digraphWriter(const char *fn,
321 const Digraph& digraph);
323 /// \ingroup lemon_io
325 /// \brief LGF writer for directed graphs
327 /// This utility writes an \ref lgf-format "LGF" file.
329 /// The writing method does a batch processing. The user creates a
330 /// writer object, then various writing rules can be added to the
331 /// writer, and eventually the writing is executed with the \c run()
332 /// member function. A map writing rule can be added to the writer
333 /// with the \c nodeMap() or \c arcMap() members. An optional
334 /// converter parameter can also be added as a standard functor
335 /// converting from the value type of the map to std::string. If it
336 /// is set, it will determine how the map's value type is written to
337 /// the output stream. If the functor is not set, then a default
338 /// conversion will be used. The \c attribute(), \c node() and \c
339 /// arc() functions are used to add attribute writing rules.
342 /// DigraphWriter<Digraph>(std::cout, digraph).
343 /// nodeMap("coordinates", coord_map).
344 /// nodeMap("size", size).
345 /// nodeMap("title", title).
346 /// arcMap("capacity", cap_map).
347 /// node("source", src).
348 /// node("target", trg).
349 /// attribute("caption", caption).
354 /// By default, the writer does not write additional captions to the
355 /// sections, but they can be give as an optional parameter of
356 /// the \c nodes(), \c arcs() or \c
357 /// attributes() functions.
359 /// The \c skipNodes() and \c skipArcs() functions forbid the
360 /// writing of the sections. If two arc sections should be written
361 /// to the output, it can be done in two passes, the first pass
362 /// writes the node section and the first arc section, then the
363 /// second pass skips the node section and writes just the arc
364 /// section to the stream. The output stream can be retrieved with
365 /// the \c ostream() function, hence the second pass can append its
366 /// output to the output of the first pass.
367 template <typename _Digraph>
368 class DigraphWriter {
371 typedef _Digraph Digraph;
372 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
380 const Digraph& _digraph;
382 std::string _nodes_caption;
383 std::string _arcs_caption;
384 std::string _attributes_caption;
386 typedef std::map<Node, std::string> NodeIndex;
387 NodeIndex _node_index;
388 typedef std::map<Arc, std::string> ArcIndex;
391 typedef std::vector<std::pair<std::string,
392 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
395 typedef std::vector<std::pair<std::string,
396 _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
399 typedef std::vector<std::pair<std::string,
400 _writer_bits::ValueStorageBase*> > Attributes;
401 Attributes _attributes;
408 /// \brief Constructor
410 /// Construct a directed graph writer, which writes to the given
412 DigraphWriter(std::ostream& is, const Digraph& digraph)
413 : _os(&is), local_os(false), _digraph(digraph),
414 _skip_nodes(false), _skip_arcs(false) {}
416 /// \brief Constructor
418 /// Construct a directed graph writer, which writes to the given
420 DigraphWriter(const std::string& fn, const Digraph& digraph)
421 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
422 _skip_nodes(false), _skip_arcs(false) {}
424 /// \brief Constructor
426 /// Construct a directed graph writer, which writes to the given
428 DigraphWriter(const char* fn, const Digraph& digraph)
429 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
430 _skip_nodes(false), _skip_arcs(false) {}
432 /// \brief Destructor
434 for (typename NodeMaps::iterator it = _node_maps.begin();
435 it != _node_maps.end(); ++it) {
439 for (typename ArcMaps::iterator it = _arc_maps.begin();
440 it != _arc_maps.end(); ++it) {
444 for (typename Attributes::iterator it = _attributes.begin();
445 it != _attributes.end(); ++it) {
456 friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os,
457 const Digraph& digraph);
458 friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn,
459 const Digraph& digraph);
460 friend DigraphWriter<Digraph> digraphWriter<>(const char *fn,
461 const Digraph& digraph);
463 DigraphWriter(DigraphWriter& other)
464 : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
465 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
468 other.local_os = false;
470 _node_index.swap(other._node_index);
471 _arc_index.swap(other._arc_index);
473 _node_maps.swap(other._node_maps);
474 _arc_maps.swap(other._arc_maps);
475 _attributes.swap(other._attributes);
477 _nodes_caption = other._nodes_caption;
478 _arcs_caption = other._arcs_caption;
479 _attributes_caption = other._attributes_caption;
482 DigraphWriter& operator=(const DigraphWriter&);
486 /// \name Writing rules
489 /// \brief Node map reading rule
491 /// Add a node map reading rule to the writer.
492 template <typename Map>
493 DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
494 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
495 _writer_bits::MapStorageBase<Node>* storage =
496 new _writer_bits::MapStorage<Node, Map>(map);
497 _node_maps.push_back(std::make_pair(caption, storage));
501 /// \brief Node map writing rule
503 /// Add a node map writing rule with specialized converter to the
505 template <typename Map, typename Converter>
506 DigraphWriter& nodeMap(const std::string& caption, const Map& map,
507 const Converter& converter = Converter()) {
508 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
509 _writer_bits::MapStorageBase<Node>* storage =
510 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
511 _node_maps.push_back(std::make_pair(caption, storage));
515 /// \brief Arc map writing rule
517 /// Add an arc map writing rule to the writer.
518 template <typename Map>
519 DigraphWriter& arcMap(const std::string& caption, const Map& map) {
520 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
521 _writer_bits::MapStorageBase<Arc>* storage =
522 new _writer_bits::MapStorage<Arc, Map>(map);
523 _arc_maps.push_back(std::make_pair(caption, storage));
527 /// \brief Arc map writing rule
529 /// Add an arc map writing rule with specialized converter to the
531 template <typename Map, typename Converter>
532 DigraphWriter& arcMap(const std::string& caption, const Map& map,
533 const Converter& converter = Converter()) {
534 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
535 _writer_bits::MapStorageBase<Arc>* storage =
536 new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
537 _arc_maps.push_back(std::make_pair(caption, storage));
541 /// \brief Attribute writing rule
543 /// Add an attribute writing rule to the writer.
544 template <typename Value>
545 DigraphWriter& attribute(const std::string& caption, const Value& value) {
546 _writer_bits::ValueStorageBase* storage =
547 new _writer_bits::ValueStorage<Value>(value);
548 _attributes.push_back(std::make_pair(caption, storage));
552 /// \brief Attribute writing rule
554 /// Add an attribute writing rule with specialized converter to the
556 template <typename Value, typename Converter>
557 DigraphWriter& attribute(const std::string& caption, const Value& value,
558 const Converter& converter = Converter()) {
559 _writer_bits::ValueStorageBase* storage =
560 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
561 _attributes.push_back(std::make_pair(caption, storage));
565 /// \brief Node writing rule
567 /// Add a node writing rule to the writer.
568 DigraphWriter& node(const std::string& caption, const Node& node) {
569 typedef _writer_bits::MapLookUpConverter<Node> Converter;
570 Converter converter(_node_index);
571 _writer_bits::ValueStorageBase* storage =
572 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
573 _attributes.push_back(std::make_pair(caption, storage));
577 /// \brief Arc writing rule
579 /// Add an arc writing rule to writer.
580 DigraphWriter& arc(const std::string& caption, const Arc& arc) {
581 typedef _writer_bits::MapLookUpConverter<Arc> Converter;
582 Converter converter(_arc_index);
583 _writer_bits::ValueStorageBase* storage =
584 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
585 _attributes.push_back(std::make_pair(caption, storage));
589 /// \name Select section by name
592 /// \brief Set \c \@nodes section to be read
594 /// Set \c \@nodes section to be read
595 DigraphWriter& nodes(const std::string& caption) {
596 _nodes_caption = caption;
600 /// \brief Set \c \@arcs section to be read
602 /// Set \c \@arcs section to be read
603 DigraphWriter& arcs(const std::string& caption) {
604 _arcs_caption = caption;
608 /// \brief Set \c \@attributes section to be read
610 /// Set \c \@attributes section to be read
611 DigraphWriter& attributes(const std::string& caption) {
612 _attributes_caption = caption;
616 /// \name Skipping section
619 /// \brief Skip writing the node set
621 /// The \c \@nodes section will be not written to the stream.
622 DigraphWriter& skipNodes() {
623 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
628 /// \brief Skip writing arc set
630 /// The \c \@arcs section will be not written to the stream.
631 DigraphWriter& skipArcs() {
632 LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
642 _writer_bits::MapStorageBase<Node>* label = 0;
643 for (typename NodeMaps::iterator it = _node_maps.begin();
644 it != _node_maps.end(); ++it) {
645 if (it->first == "label") {
652 if (!_nodes_caption.empty()) {
653 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
658 *_os << "label" << '\t';
660 for (typename NodeMaps::iterator it = _node_maps.begin();
661 it != _node_maps.end(); ++it) {
662 _writer_bits::writeToken(*_os, it->first) << '\t';
666 std::vector<Node> nodes;
667 for (NodeIt n(_digraph); n != INVALID; ++n) {
672 IdMap<Digraph, Node> id_map(_digraph);
673 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
674 std::sort(nodes.begin(), nodes.end(), id_less);
679 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
682 std::ostringstream os;
683 os << _digraph.id(n);
684 _writer_bits::writeToken(*_os, os.str());
686 _node_index.insert(std::make_pair(n, os.str()));
688 for (typename NodeMaps::iterator it = _node_maps.begin();
689 it != _node_maps.end(); ++it) {
690 std::string value = it->second->get(n);
691 _writer_bits::writeToken(*_os, value);
692 if (it->first == "label") {
693 _node_index.insert(std::make_pair(n, value));
701 void createNodeIndex() {
702 _writer_bits::MapStorageBase<Node>* label = 0;
703 for (typename NodeMaps::iterator it = _node_maps.begin();
704 it != _node_maps.end(); ++it) {
705 if (it->first == "label") {
712 for (NodeIt n(_digraph); n != INVALID; ++n) {
713 std::ostringstream os;
714 os << _digraph.id(n);
715 _node_index.insert(std::make_pair(n, os.str()));
718 for (NodeIt n(_digraph); n != INVALID; ++n) {
719 std::string value = label->get(n);
720 _node_index.insert(std::make_pair(n, value));
726 _writer_bits::MapStorageBase<Arc>* label = 0;
727 for (typename ArcMaps::iterator it = _arc_maps.begin();
728 it != _arc_maps.end(); ++it) {
729 if (it->first == "label") {
736 if (!_arcs_caption.empty()) {
737 _writer_bits::writeToken(*_os << ' ', _arcs_caption);
741 *_os << '\t' << '\t';
743 *_os << "label" << '\t';
745 for (typename ArcMaps::iterator it = _arc_maps.begin();
746 it != _arc_maps.end(); ++it) {
747 _writer_bits::writeToken(*_os, it->first) << '\t';
751 std::vector<Arc> arcs;
752 for (ArcIt n(_digraph); n != INVALID; ++n) {
757 IdMap<Digraph, Arc> id_map(_digraph);
758 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
759 std::sort(arcs.begin(), arcs.end(), id_less);
764 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
766 _writer_bits::writeToken(*_os, _node_index.
767 find(_digraph.source(a))->second);
769 _writer_bits::writeToken(*_os, _node_index.
770 find(_digraph.target(a))->second);
773 std::ostringstream os;
774 os << _digraph.id(a);
775 _writer_bits::writeToken(*_os, os.str());
777 _arc_index.insert(std::make_pair(a, os.str()));
779 for (typename ArcMaps::iterator it = _arc_maps.begin();
780 it != _arc_maps.end(); ++it) {
781 std::string value = it->second->get(a);
782 _writer_bits::writeToken(*_os, value);
783 if (it->first == "label") {
784 _arc_index.insert(std::make_pair(a, value));
792 void createArcIndex() {
793 _writer_bits::MapStorageBase<Arc>* label = 0;
794 for (typename ArcMaps::iterator it = _arc_maps.begin();
795 it != _arc_maps.end(); ++it) {
796 if (it->first == "label") {
803 for (ArcIt a(_digraph); a != INVALID; ++a) {
804 std::ostringstream os;
805 os << _digraph.id(a);
806 _arc_index.insert(std::make_pair(a, os.str()));
809 for (ArcIt a(_digraph); a != INVALID; ++a) {
810 std::string value = label->get(a);
811 _arc_index.insert(std::make_pair(a, value));
816 void writeAttributes() {
817 if (_attributes.empty()) return;
818 *_os << "@attributes";
819 if (!_attributes_caption.empty()) {
820 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
823 for (typename Attributes::iterator it = _attributes.begin();
824 it != _attributes.end(); ++it) {
825 _writer_bits::writeToken(*_os, it->first) << ' ';
826 _writer_bits::writeToken(*_os, it->second->get());
833 /// \name Execution of the writer
836 /// \brief Start the batch processing
838 /// This function starts the batch processing
853 /// \brief Gives back the stream of the writer
855 /// Gives back the stream of the writer
856 std::ostream& ostream() {
863 /// \relates DigraphWriter
864 template <typename Digraph>
865 DigraphWriter<Digraph> digraphWriter(std::ostream& os,
866 const Digraph& digraph) {
867 DigraphWriter<Digraph> tmp(os, digraph);
871 /// \relates DigraphWriter
872 template <typename Digraph>
873 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
874 const Digraph& digraph) {
875 DigraphWriter<Digraph> tmp(fn, digraph);
879 /// \relates DigraphWriter
880 template <typename Digraph>
881 DigraphWriter<Digraph> digraphWriter(const char* fn,
882 const Digraph& digraph) {
883 DigraphWriter<Digraph> tmp(fn, digraph);
887 template <typename Graph>
890 template <typename Graph>
891 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);
893 template <typename Graph>
894 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);
896 template <typename Graph>
897 GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);
899 /// \ingroup lemon_io
901 /// \brief LGF writer for directed graphs
903 /// This utility writes an \ref lgf-format "LGF" file.
904 template <typename _Graph>
908 typedef _Graph Graph;
909 TEMPLATE_GRAPH_TYPEDEFS(Graph);
919 std::string _nodes_caption;
920 std::string _edges_caption;
921 std::string _attributes_caption;
923 typedef std::map<Node, std::string> NodeIndex;
924 NodeIndex _node_index;
925 typedef std::map<Edge, std::string> EdgeIndex;
926 EdgeIndex _edge_index;
928 typedef std::vector<std::pair<std::string,
929 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
932 typedef std::vector<std::pair<std::string,
933 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
936 typedef std::vector<std::pair<std::string,
937 _writer_bits::ValueStorageBase*> > Attributes;
938 Attributes _attributes;
945 /// \brief Constructor
947 /// Construct a directed graph writer, which writes to the given
949 GraphWriter(std::ostream& is, const Graph& graph)
950 : _os(&is), local_os(false), _graph(graph),
951 _skip_nodes(false), _skip_edges(false) {}
953 /// \brief Constructor
955 /// Construct a directed graph writer, which writes to the given
957 GraphWriter(const std::string& fn, const Graph& graph)
958 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
959 _skip_nodes(false), _skip_edges(false) {}
961 /// \brief Constructor
963 /// Construct a directed graph writer, which writes to the given
965 GraphWriter(const char* fn, const Graph& graph)
966 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
967 _skip_nodes(false), _skip_edges(false) {}
969 /// \brief Destructor
971 for (typename NodeMaps::iterator it = _node_maps.begin();
972 it != _node_maps.end(); ++it) {
976 for (typename EdgeMaps::iterator it = _edge_maps.begin();
977 it != _edge_maps.end(); ++it) {
981 for (typename Attributes::iterator it = _attributes.begin();
982 it != _attributes.end(); ++it) {
993 friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
995 friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
997 friend GraphWriter<Graph> graphWriter<>(const char *fn,
1000 GraphWriter(GraphWriter& other)
1001 : _os(other._os), local_os(other.local_os), _graph(other._graph),
1002 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1005 other.local_os = false;
1007 _node_index.swap(other._node_index);
1008 _edge_index.swap(other._edge_index);
1010 _node_maps.swap(other._node_maps);
1011 _edge_maps.swap(other._edge_maps);
1012 _attributes.swap(other._attributes);
1014 _nodes_caption = other._nodes_caption;
1015 _edges_caption = other._edges_caption;
1016 _attributes_caption = other._attributes_caption;
1019 GraphWriter& operator=(const GraphWriter&);
1023 /// \name Writing rules
1026 /// \brief Node map reading rule
1028 /// Add a node map reading rule to the writer.
1029 template <typename Map>
1030 GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1031 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1032 _writer_bits::MapStorageBase<Node>* storage =
1033 new _writer_bits::MapStorage<Node, Map>(map);
1034 _node_maps.push_back(std::make_pair(caption, storage));
1038 /// \brief Node map writing rule
1040 /// Add a node map writing rule with specialized converter to the
1042 template <typename Map, typename Converter>
1043 GraphWriter& nodeMap(const std::string& caption, const Map& map,
1044 const Converter& converter = Converter()) {
1045 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1046 _writer_bits::MapStorageBase<Node>* storage =
1047 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1048 _node_maps.push_back(std::make_pair(caption, storage));
1052 /// \brief Edge map writing rule
1054 /// Add an edge map writing rule to the writer.
1055 template <typename Map>
1056 GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1057 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1058 _writer_bits::MapStorageBase<Edge>* storage =
1059 new _writer_bits::MapStorage<Edge, Map>(map);
1060 _edge_maps.push_back(std::make_pair(caption, storage));
1064 /// \brief Edge map writing rule
1066 /// Add an edge map writing rule with specialized converter to the
1068 template <typename Map, typename Converter>
1069 GraphWriter& edgeMap(const std::string& caption, const Map& map,
1070 const Converter& converter = Converter()) {
1071 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1072 _writer_bits::MapStorageBase<Edge>* storage =
1073 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1074 _edge_maps.push_back(std::make_pair(caption, storage));
1078 /// \brief Arc map writing rule
1080 /// Add an arc map writing rule to the writer.
1081 template <typename Map>
1082 GraphWriter& arcMap(const std::string& caption, const Map& map) {
1083 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1084 _writer_bits::MapStorageBase<Edge>* forward_storage =
1085 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1086 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1087 _writer_bits::MapStorageBase<Edge>* backward_storage =
1088 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1089 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1093 /// \brief Arc map writing rule
1095 /// Add an arc map writing rule with specialized converter to the
1097 template <typename Map, typename Converter>
1098 GraphWriter& arcMap(const std::string& caption, const Map& map,
1099 const Converter& converter = Converter()) {
1100 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1101 _writer_bits::MapStorageBase<Edge>* forward_storage =
1102 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1103 (_graph, map, converter);
1104 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1105 _writer_bits::MapStorageBase<Edge>* backward_storage =
1106 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1107 (_graph, map, converter);
1108 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1112 /// \brief Attribute writing rule
1114 /// Add an attribute writing rule to the writer.
1115 template <typename Value>
1116 GraphWriter& attribute(const std::string& caption, const Value& value) {
1117 _writer_bits::ValueStorageBase* storage =
1118 new _writer_bits::ValueStorage<Value>(value);
1119 _attributes.push_back(std::make_pair(caption, storage));
1123 /// \brief Attribute writing rule
1125 /// Add an attribute writing rule with specialized converter to the
1127 template <typename Value, typename Converter>
1128 GraphWriter& attribute(const std::string& caption, const Value& value,
1129 const Converter& converter = Converter()) {
1130 _writer_bits::ValueStorageBase* storage =
1131 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1132 _attributes.push_back(std::make_pair(caption, storage));
1136 /// \brief Node writing rule
1138 /// Add a node writing rule to the writer.
1139 GraphWriter& node(const std::string& caption, const Node& node) {
1140 typedef _writer_bits::MapLookUpConverter<Node> Converter;
1141 Converter converter(_node_index);
1142 _writer_bits::ValueStorageBase* storage =
1143 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1144 _attributes.push_back(std::make_pair(caption, storage));
1148 /// \brief Edge writing rule
1150 /// Add an edge writing rule to writer.
1151 GraphWriter& edge(const std::string& caption, const Edge& edge) {
1152 typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1153 Converter converter(_edge_index);
1154 _writer_bits::ValueStorageBase* storage =
1155 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1156 _attributes.push_back(std::make_pair(caption, storage));
1160 /// \brief Arc writing rule
1162 /// Add an arc writing rule to writer.
1163 GraphWriter& arc(const std::string& caption, const Arc& arc) {
1164 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1165 Converter converter(_graph, _edge_index);
1166 _writer_bits::ValueStorageBase* storage =
1167 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1168 _attributes.push_back(std::make_pair(caption, storage));
1172 /// \name Select section by name
1175 /// \brief Set \c \@nodes section to be read
1177 /// Set \c \@nodes section to be read
1178 GraphWriter& nodes(const std::string& caption) {
1179 _nodes_caption = caption;
1183 /// \brief Set \c \@edges section to be read
1185 /// Set \c \@edges section to be read
1186 GraphWriter& edges(const std::string& caption) {
1187 _edges_caption = caption;
1191 /// \brief Set \c \@attributes section to be read
1193 /// Set \c \@attributes section to be read
1194 GraphWriter& attributes(const std::string& caption) {
1195 _attributes_caption = caption;
1199 /// \name Skipping section
1202 /// \brief Skip writing the node set
1204 /// The \c \@nodes section will be not written to the stream.
1205 GraphWriter& skipNodes() {
1206 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1211 /// \brief Skip writing edge set
1213 /// The \c \@edges section will be not written to the stream.
1214 GraphWriter& skipEdges() {
1215 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1225 _writer_bits::MapStorageBase<Node>* label = 0;
1226 for (typename NodeMaps::iterator it = _node_maps.begin();
1227 it != _node_maps.end(); ++it) {
1228 if (it->first == "label") {
1235 if (!_nodes_caption.empty()) {
1236 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1241 *_os << "label" << '\t';
1243 for (typename NodeMaps::iterator it = _node_maps.begin();
1244 it != _node_maps.end(); ++it) {
1245 _writer_bits::writeToken(*_os, it->first) << '\t';
1249 std::vector<Node> nodes;
1250 for (NodeIt n(_graph); n != INVALID; ++n) {
1255 IdMap<Graph, Node> id_map(_graph);
1256 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1257 std::sort(nodes.begin(), nodes.end(), id_less);
1262 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1265 std::ostringstream os;
1267 _writer_bits::writeToken(*_os, os.str());
1269 _node_index.insert(std::make_pair(n, os.str()));
1271 for (typename NodeMaps::iterator it = _node_maps.begin();
1272 it != _node_maps.end(); ++it) {
1273 std::string value = it->second->get(n);
1274 _writer_bits::writeToken(*_os, value);
1275 if (it->first == "label") {
1276 _node_index.insert(std::make_pair(n, value));
1284 void createNodeIndex() {
1285 _writer_bits::MapStorageBase<Node>* label = 0;
1286 for (typename NodeMaps::iterator it = _node_maps.begin();
1287 it != _node_maps.end(); ++it) {
1288 if (it->first == "label") {
1295 for (NodeIt n(_graph); n != INVALID; ++n) {
1296 std::ostringstream os;
1298 _node_index.insert(std::make_pair(n, os.str()));
1301 for (NodeIt n(_graph); n != INVALID; ++n) {
1302 std::string value = label->get(n);
1303 _node_index.insert(std::make_pair(n, value));
1309 _writer_bits::MapStorageBase<Edge>* label = 0;
1310 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1311 it != _edge_maps.end(); ++it) {
1312 if (it->first == "label") {
1319 if (!_edges_caption.empty()) {
1320 _writer_bits::writeToken(*_os << ' ', _edges_caption);
1324 *_os << '\t' << '\t';
1326 *_os << "label" << '\t';
1328 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1329 it != _edge_maps.end(); ++it) {
1330 _writer_bits::writeToken(*_os, it->first) << '\t';
1334 std::vector<Edge> edges;
1335 for (EdgeIt n(_graph); n != INVALID; ++n) {
1340 IdMap<Graph, Edge> id_map(_graph);
1341 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1342 std::sort(edges.begin(), edges.end(), id_less);
1347 for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1349 _writer_bits::writeToken(*_os, _node_index.
1350 find(_graph.u(e))->second);
1352 _writer_bits::writeToken(*_os, _node_index.
1353 find(_graph.v(e))->second);
1356 std::ostringstream os;
1358 _writer_bits::writeToken(*_os, os.str());
1360 _edge_index.insert(std::make_pair(e, os.str()));
1362 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1363 it != _edge_maps.end(); ++it) {
1364 std::string value = it->second->get(e);
1365 _writer_bits::writeToken(*_os, value);
1366 if (it->first == "label") {
1367 _edge_index.insert(std::make_pair(e, value));
1375 void createEdgeIndex() {
1376 _writer_bits::MapStorageBase<Edge>* label = 0;
1377 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1378 it != _edge_maps.end(); ++it) {
1379 if (it->first == "label") {
1386 for (EdgeIt e(_graph); e != INVALID; ++e) {
1387 std::ostringstream os;
1389 _edge_index.insert(std::make_pair(e, os.str()));
1392 for (EdgeIt e(_graph); e != INVALID; ++e) {
1393 std::string value = label->get(e);
1394 _edge_index.insert(std::make_pair(e, value));
1399 void writeAttributes() {
1400 if (_attributes.empty()) return;
1401 *_os << "@attributes";
1402 if (!_attributes_caption.empty()) {
1403 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1406 for (typename Attributes::iterator it = _attributes.begin();
1407 it != _attributes.end(); ++it) {
1408 _writer_bits::writeToken(*_os, it->first) << ' ';
1409 _writer_bits::writeToken(*_os, it->second->get());
1416 /// \name Execution of the writer
1419 /// \brief Start the batch processing
1421 /// This function starts the batch processing
1436 /// \brief Gives back the stream of the writer
1438 /// Gives back the stream of the writer
1439 std::ostream& ostream() {
1446 /// \relates GraphWriter
1447 template <typename Graph>
1448 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1449 GraphWriter<Graph> tmp(os, graph);
1453 /// \relates GraphWriter
1454 template <typename Graph>
1455 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1456 GraphWriter<Graph> tmp(fn, graph);
1460 /// \relates GraphWriter
1461 template <typename Graph>
1462 GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1463 GraphWriter<Graph> tmp(fn, graph);