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 \ref lgf-format "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 \ref lgf-format "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 \c std::string. If it
336 /// is set, it will determine how the value type of the map 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 writing rule
491 /// Add a node map writing 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 Section captions
592 /// \brief Add an additional caption to the \c \@nodes section
594 /// Add an additional caption to the \c \@nodes section.
595 DigraphWriter& nodes(const std::string& caption) {
596 _nodes_caption = caption;
600 /// \brief Add an additional caption to the \c \@arcs section
602 /// Add an additional caption to the \c \@arcs section.
603 DigraphWriter& arcs(const std::string& caption) {
604 _arcs_caption = caption;
608 /// \brief Add an additional caption to the \c \@attributes section
610 /// Add an additional caption to the \c \@attributes section.
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 not be 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 not be 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 Give back the stream of the writer
855 /// Give back the stream of the writer.
856 std::ostream& ostream() {
863 /// \brief Return a \ref DigraphWriter class
865 /// This function just returns a \ref DigraphWriter class.
866 /// \relates DigraphWriter
867 template <typename Digraph>
868 DigraphWriter<Digraph> digraphWriter(std::ostream& os,
869 const Digraph& digraph) {
870 DigraphWriter<Digraph> tmp(os, digraph);
874 /// \brief Return a \ref DigraphWriter class
876 /// This function just returns a \ref DigraphWriter class.
877 /// \relates DigraphWriter
878 template <typename Digraph>
879 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
880 const Digraph& digraph) {
881 DigraphWriter<Digraph> tmp(fn, digraph);
885 /// \brief Return a \ref DigraphWriter class
887 /// This function just returns a \ref DigraphWriter class.
888 /// \relates DigraphWriter
889 template <typename Digraph>
890 DigraphWriter<Digraph> digraphWriter(const char* fn,
891 const Digraph& digraph) {
892 DigraphWriter<Digraph> tmp(fn, digraph);
896 template <typename Graph>
899 template <typename Graph>
900 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);
902 template <typename Graph>
903 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);
905 template <typename Graph>
906 GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);
908 /// \ingroup lemon_io
910 /// \brief \ref lgf-format "LGF" writer for directed graphs
912 /// This utility writes an \ref lgf-format "LGF" file.
914 /// It can be used almost the same way as \c DigraphWriter.
915 /// The only difference is that this class can handle edges and
916 /// edge maps as well as arcs and arc maps.
917 template <typename _Graph>
921 typedef _Graph Graph;
922 TEMPLATE_GRAPH_TYPEDEFS(Graph);
932 std::string _nodes_caption;
933 std::string _edges_caption;
934 std::string _attributes_caption;
936 typedef std::map<Node, std::string> NodeIndex;
937 NodeIndex _node_index;
938 typedef std::map<Edge, std::string> EdgeIndex;
939 EdgeIndex _edge_index;
941 typedef std::vector<std::pair<std::string,
942 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
945 typedef std::vector<std::pair<std::string,
946 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
949 typedef std::vector<std::pair<std::string,
950 _writer_bits::ValueStorageBase*> > Attributes;
951 Attributes _attributes;
958 /// \brief Constructor
960 /// Construct a directed graph writer, which writes to the given
962 GraphWriter(std::ostream& is, const Graph& graph)
963 : _os(&is), local_os(false), _graph(graph),
964 _skip_nodes(false), _skip_edges(false) {}
966 /// \brief Constructor
968 /// Construct a directed graph writer, which writes to the given
970 GraphWriter(const std::string& fn, const Graph& graph)
971 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
972 _skip_nodes(false), _skip_edges(false) {}
974 /// \brief Constructor
976 /// Construct a directed graph writer, which writes to the given
978 GraphWriter(const char* fn, const Graph& graph)
979 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
980 _skip_nodes(false), _skip_edges(false) {}
982 /// \brief Destructor
984 for (typename NodeMaps::iterator it = _node_maps.begin();
985 it != _node_maps.end(); ++it) {
989 for (typename EdgeMaps::iterator it = _edge_maps.begin();
990 it != _edge_maps.end(); ++it) {
994 for (typename Attributes::iterator it = _attributes.begin();
995 it != _attributes.end(); ++it) {
1006 friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
1007 const Graph& graph);
1008 friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
1009 const Graph& graph);
1010 friend GraphWriter<Graph> graphWriter<>(const char *fn,
1011 const Graph& graph);
1013 GraphWriter(GraphWriter& other)
1014 : _os(other._os), local_os(other.local_os), _graph(other._graph),
1015 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1018 other.local_os = false;
1020 _node_index.swap(other._node_index);
1021 _edge_index.swap(other._edge_index);
1023 _node_maps.swap(other._node_maps);
1024 _edge_maps.swap(other._edge_maps);
1025 _attributes.swap(other._attributes);
1027 _nodes_caption = other._nodes_caption;
1028 _edges_caption = other._edges_caption;
1029 _attributes_caption = other._attributes_caption;
1032 GraphWriter& operator=(const GraphWriter&);
1036 /// \name Writing rules
1039 /// \brief Node map writing rule
1041 /// Add a node map writing rule to the writer.
1042 template <typename Map>
1043 GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1044 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1045 _writer_bits::MapStorageBase<Node>* storage =
1046 new _writer_bits::MapStorage<Node, Map>(map);
1047 _node_maps.push_back(std::make_pair(caption, storage));
1051 /// \brief Node map writing rule
1053 /// Add a node map writing rule with specialized converter to the
1055 template <typename Map, typename Converter>
1056 GraphWriter& nodeMap(const std::string& caption, const Map& map,
1057 const Converter& converter = Converter()) {
1058 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1059 _writer_bits::MapStorageBase<Node>* storage =
1060 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1061 _node_maps.push_back(std::make_pair(caption, storage));
1065 /// \brief Edge map writing rule
1067 /// Add an edge map writing rule to the writer.
1068 template <typename Map>
1069 GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1070 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1071 _writer_bits::MapStorageBase<Edge>* storage =
1072 new _writer_bits::MapStorage<Edge, Map>(map);
1073 _edge_maps.push_back(std::make_pair(caption, storage));
1077 /// \brief Edge map writing rule
1079 /// Add an edge map writing rule with specialized converter to the
1081 template <typename Map, typename Converter>
1082 GraphWriter& edgeMap(const std::string& caption, const Map& map,
1083 const Converter& converter = Converter()) {
1084 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1085 _writer_bits::MapStorageBase<Edge>* storage =
1086 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1087 _edge_maps.push_back(std::make_pair(caption, storage));
1091 /// \brief Arc map writing rule
1093 /// Add an arc map writing rule to the writer.
1094 template <typename Map>
1095 GraphWriter& arcMap(const std::string& caption, const Map& map) {
1096 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1097 _writer_bits::MapStorageBase<Edge>* forward_storage =
1098 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1099 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1100 _writer_bits::MapStorageBase<Edge>* backward_storage =
1101 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1102 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1106 /// \brief Arc map writing rule
1108 /// Add an arc map writing rule with specialized converter to the
1110 template <typename Map, typename Converter>
1111 GraphWriter& arcMap(const std::string& caption, const Map& map,
1112 const Converter& converter = Converter()) {
1113 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1114 _writer_bits::MapStorageBase<Edge>* forward_storage =
1115 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1116 (_graph, map, converter);
1117 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1118 _writer_bits::MapStorageBase<Edge>* backward_storage =
1119 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1120 (_graph, map, converter);
1121 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1125 /// \brief Attribute writing rule
1127 /// Add an attribute writing rule to the writer.
1128 template <typename Value>
1129 GraphWriter& attribute(const std::string& caption, const Value& value) {
1130 _writer_bits::ValueStorageBase* storage =
1131 new _writer_bits::ValueStorage<Value>(value);
1132 _attributes.push_back(std::make_pair(caption, storage));
1136 /// \brief Attribute writing rule
1138 /// Add an attribute writing rule with specialized converter to the
1140 template <typename Value, typename Converter>
1141 GraphWriter& attribute(const std::string& caption, const Value& value,
1142 const Converter& converter = Converter()) {
1143 _writer_bits::ValueStorageBase* storage =
1144 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1145 _attributes.push_back(std::make_pair(caption, storage));
1149 /// \brief Node writing rule
1151 /// Add a node writing rule to the writer.
1152 GraphWriter& node(const std::string& caption, const Node& node) {
1153 typedef _writer_bits::MapLookUpConverter<Node> Converter;
1154 Converter converter(_node_index);
1155 _writer_bits::ValueStorageBase* storage =
1156 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1157 _attributes.push_back(std::make_pair(caption, storage));
1161 /// \brief Edge writing rule
1163 /// Add an edge writing rule to writer.
1164 GraphWriter& edge(const std::string& caption, const Edge& edge) {
1165 typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1166 Converter converter(_edge_index);
1167 _writer_bits::ValueStorageBase* storage =
1168 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1169 _attributes.push_back(std::make_pair(caption, storage));
1173 /// \brief Arc writing rule
1175 /// Add an arc writing rule to writer.
1176 GraphWriter& arc(const std::string& caption, const Arc& arc) {
1177 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1178 Converter converter(_graph, _edge_index);
1179 _writer_bits::ValueStorageBase* storage =
1180 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1181 _attributes.push_back(std::make_pair(caption, storage));
1185 /// \name Section captions
1188 /// \brief Add an additional caption to the \c \@nodes section
1190 /// Add an additional caption to the \c \@nodes section.
1191 GraphWriter& nodes(const std::string& caption) {
1192 _nodes_caption = caption;
1196 /// \brief Add an additional caption to the \c \@arcs section
1198 /// Add an additional caption to the \c \@arcs section.
1199 GraphWriter& edges(const std::string& caption) {
1200 _edges_caption = caption;
1204 /// \brief Add an additional caption to the \c \@attributes section
1206 /// Add an additional caption to the \c \@attributes section.
1207 GraphWriter& attributes(const std::string& caption) {
1208 _attributes_caption = caption;
1212 /// \name Skipping section
1215 /// \brief Skip writing the node set
1217 /// The \c \@nodes section will not be written to the stream.
1218 GraphWriter& skipNodes() {
1219 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1224 /// \brief Skip writing edge set
1226 /// The \c \@edges section will not be written to the stream.
1227 GraphWriter& skipEdges() {
1228 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1238 _writer_bits::MapStorageBase<Node>* label = 0;
1239 for (typename NodeMaps::iterator it = _node_maps.begin();
1240 it != _node_maps.end(); ++it) {
1241 if (it->first == "label") {
1248 if (!_nodes_caption.empty()) {
1249 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1254 *_os << "label" << '\t';
1256 for (typename NodeMaps::iterator it = _node_maps.begin();
1257 it != _node_maps.end(); ++it) {
1258 _writer_bits::writeToken(*_os, it->first) << '\t';
1262 std::vector<Node> nodes;
1263 for (NodeIt n(_graph); n != INVALID; ++n) {
1268 IdMap<Graph, Node> id_map(_graph);
1269 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1270 std::sort(nodes.begin(), nodes.end(), id_less);
1275 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1278 std::ostringstream os;
1280 _writer_bits::writeToken(*_os, os.str());
1282 _node_index.insert(std::make_pair(n, os.str()));
1284 for (typename NodeMaps::iterator it = _node_maps.begin();
1285 it != _node_maps.end(); ++it) {
1286 std::string value = it->second->get(n);
1287 _writer_bits::writeToken(*_os, value);
1288 if (it->first == "label") {
1289 _node_index.insert(std::make_pair(n, value));
1297 void createNodeIndex() {
1298 _writer_bits::MapStorageBase<Node>* label = 0;
1299 for (typename NodeMaps::iterator it = _node_maps.begin();
1300 it != _node_maps.end(); ++it) {
1301 if (it->first == "label") {
1308 for (NodeIt n(_graph); n != INVALID; ++n) {
1309 std::ostringstream os;
1311 _node_index.insert(std::make_pair(n, os.str()));
1314 for (NodeIt n(_graph); n != INVALID; ++n) {
1315 std::string value = label->get(n);
1316 _node_index.insert(std::make_pair(n, value));
1322 _writer_bits::MapStorageBase<Edge>* label = 0;
1323 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1324 it != _edge_maps.end(); ++it) {
1325 if (it->first == "label") {
1332 if (!_edges_caption.empty()) {
1333 _writer_bits::writeToken(*_os << ' ', _edges_caption);
1337 *_os << '\t' << '\t';
1339 *_os << "label" << '\t';
1341 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1342 it != _edge_maps.end(); ++it) {
1343 _writer_bits::writeToken(*_os, it->first) << '\t';
1347 std::vector<Edge> edges;
1348 for (EdgeIt n(_graph); n != INVALID; ++n) {
1353 IdMap<Graph, Edge> id_map(_graph);
1354 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1355 std::sort(edges.begin(), edges.end(), id_less);
1360 for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1362 _writer_bits::writeToken(*_os, _node_index.
1363 find(_graph.u(e))->second);
1365 _writer_bits::writeToken(*_os, _node_index.
1366 find(_graph.v(e))->second);
1369 std::ostringstream os;
1371 _writer_bits::writeToken(*_os, os.str());
1373 _edge_index.insert(std::make_pair(e, os.str()));
1375 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1376 it != _edge_maps.end(); ++it) {
1377 std::string value = it->second->get(e);
1378 _writer_bits::writeToken(*_os, value);
1379 if (it->first == "label") {
1380 _edge_index.insert(std::make_pair(e, value));
1388 void createEdgeIndex() {
1389 _writer_bits::MapStorageBase<Edge>* label = 0;
1390 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1391 it != _edge_maps.end(); ++it) {
1392 if (it->first == "label") {
1399 for (EdgeIt e(_graph); e != INVALID; ++e) {
1400 std::ostringstream os;
1402 _edge_index.insert(std::make_pair(e, os.str()));
1405 for (EdgeIt e(_graph); e != INVALID; ++e) {
1406 std::string value = label->get(e);
1407 _edge_index.insert(std::make_pair(e, value));
1412 void writeAttributes() {
1413 if (_attributes.empty()) return;
1414 *_os << "@attributes";
1415 if (!_attributes_caption.empty()) {
1416 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1419 for (typename Attributes::iterator it = _attributes.begin();
1420 it != _attributes.end(); ++it) {
1421 _writer_bits::writeToken(*_os, it->first) << ' ';
1422 _writer_bits::writeToken(*_os, it->second->get());
1429 /// \name Execution of the writer
1432 /// \brief Start the batch processing
1434 /// This function starts the batch processing.
1449 /// \brief Give back the stream of the writer
1451 /// Give back the stream of the writer
1452 std::ostream& ostream() {
1459 /// \brief Return a \ref GraphWriter class
1461 /// This function just returns a \ref GraphWriter class.
1462 /// \relates GraphWriter
1463 template <typename Graph>
1464 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1465 GraphWriter<Graph> tmp(os, graph);
1469 /// \brief Return a \ref GraphWriter class
1471 /// This function just returns a \ref GraphWriter class.
1472 /// \relates GraphWriter
1473 template <typename Graph>
1474 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1475 GraphWriter<Graph> tmp(fn, graph);
1479 /// \brief Return a \ref GraphWriter class
1481 /// This function just returns a \ref GraphWriter class.
1482 /// \relates GraphWriter
1483 template <typename Graph>
1484 GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1485 GraphWriter<Graph> tmp(fn, graph);