1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
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 inline bool isWhiteSpace(char c) {
229 return c == ' ' || c == '\t' || c == '\v' ||
230 c == '\n' || c == '\r' || c == '\f';
233 inline bool isEscaped(char c) {
234 return c == '\\' || c == '\"' || c == '\'' ||
235 c == '\a' || c == '\b';
238 inline static void writeEscape(std::ostream& os, char c) {
269 std::ios::fmtflags flags = os.flags();
270 os << '\\' << std::oct << static_cast<int>(c);
279 inline 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 inline 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.
918 /// The arc maps are written into the file as two columns, the
919 /// caption of the columns are the name of the map prefixed with \c
920 /// '+' and \c '-'. The arcs are written into the \c \@attributes
921 /// section as a \c '+' or a \c '-' prefix (depends on the direction
922 /// of the arc) and the label of corresponding edge.
923 template <typename _Graph>
927 typedef _Graph Graph;
928 TEMPLATE_GRAPH_TYPEDEFS(Graph);
938 std::string _nodes_caption;
939 std::string _edges_caption;
940 std::string _attributes_caption;
942 typedef std::map<Node, std::string> NodeIndex;
943 NodeIndex _node_index;
944 typedef std::map<Edge, std::string> EdgeIndex;
945 EdgeIndex _edge_index;
947 typedef std::vector<std::pair<std::string,
948 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
951 typedef std::vector<std::pair<std::string,
952 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
955 typedef std::vector<std::pair<std::string,
956 _writer_bits::ValueStorageBase*> > Attributes;
957 Attributes _attributes;
964 /// \brief Constructor
966 /// Construct a directed graph writer, which writes to the given
968 GraphWriter(std::ostream& is, const Graph& graph)
969 : _os(&is), local_os(false), _graph(graph),
970 _skip_nodes(false), _skip_edges(false) {}
972 /// \brief Constructor
974 /// Construct a directed graph writer, which writes to the given
976 GraphWriter(const std::string& fn, const Graph& graph)
977 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
978 _skip_nodes(false), _skip_edges(false) {}
980 /// \brief Constructor
982 /// Construct a directed graph writer, which writes to the given
984 GraphWriter(const char* fn, const Graph& graph)
985 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
986 _skip_nodes(false), _skip_edges(false) {}
988 /// \brief Destructor
990 for (typename NodeMaps::iterator it = _node_maps.begin();
991 it != _node_maps.end(); ++it) {
995 for (typename EdgeMaps::iterator it = _edge_maps.begin();
996 it != _edge_maps.end(); ++it) {
1000 for (typename Attributes::iterator it = _attributes.begin();
1001 it != _attributes.end(); ++it) {
1012 friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
1013 const Graph& graph);
1014 friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
1015 const Graph& graph);
1016 friend GraphWriter<Graph> graphWriter<>(const char *fn,
1017 const Graph& graph);
1019 GraphWriter(GraphWriter& other)
1020 : _os(other._os), local_os(other.local_os), _graph(other._graph),
1021 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1024 other.local_os = false;
1026 _node_index.swap(other._node_index);
1027 _edge_index.swap(other._edge_index);
1029 _node_maps.swap(other._node_maps);
1030 _edge_maps.swap(other._edge_maps);
1031 _attributes.swap(other._attributes);
1033 _nodes_caption = other._nodes_caption;
1034 _edges_caption = other._edges_caption;
1035 _attributes_caption = other._attributes_caption;
1038 GraphWriter& operator=(const GraphWriter&);
1042 /// \name Writing rules
1045 /// \brief Node map writing rule
1047 /// Add a node map writing rule to the writer.
1048 template <typename Map>
1049 GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1050 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1051 _writer_bits::MapStorageBase<Node>* storage =
1052 new _writer_bits::MapStorage<Node, Map>(map);
1053 _node_maps.push_back(std::make_pair(caption, storage));
1057 /// \brief Node map writing rule
1059 /// Add a node map writing rule with specialized converter to the
1061 template <typename Map, typename Converter>
1062 GraphWriter& nodeMap(const std::string& caption, const Map& map,
1063 const Converter& converter = Converter()) {
1064 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1065 _writer_bits::MapStorageBase<Node>* storage =
1066 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1067 _node_maps.push_back(std::make_pair(caption, storage));
1071 /// \brief Edge map writing rule
1073 /// Add an edge map writing rule to the writer.
1074 template <typename Map>
1075 GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1076 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1077 _writer_bits::MapStorageBase<Edge>* storage =
1078 new _writer_bits::MapStorage<Edge, Map>(map);
1079 _edge_maps.push_back(std::make_pair(caption, storage));
1083 /// \brief Edge map writing rule
1085 /// Add an edge map writing rule with specialized converter to the
1087 template <typename Map, typename Converter>
1088 GraphWriter& edgeMap(const std::string& caption, const Map& map,
1089 const Converter& converter = Converter()) {
1090 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1091 _writer_bits::MapStorageBase<Edge>* storage =
1092 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1093 _edge_maps.push_back(std::make_pair(caption, storage));
1097 /// \brief Arc map writing rule
1099 /// Add an arc map writing rule to the writer.
1100 template <typename Map>
1101 GraphWriter& arcMap(const std::string& caption, const Map& map) {
1102 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1103 _writer_bits::MapStorageBase<Edge>* forward_storage =
1104 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1105 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1106 _writer_bits::MapStorageBase<Edge>* backward_storage =
1107 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1108 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1112 /// \brief Arc map writing rule
1114 /// Add an arc map writing rule with specialized converter to the
1116 template <typename Map, typename Converter>
1117 GraphWriter& arcMap(const std::string& caption, const Map& map,
1118 const Converter& converter = Converter()) {
1119 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1120 _writer_bits::MapStorageBase<Edge>* forward_storage =
1121 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1122 (_graph, map, converter);
1123 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1124 _writer_bits::MapStorageBase<Edge>* backward_storage =
1125 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1126 (_graph, map, converter);
1127 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1131 /// \brief Attribute writing rule
1133 /// Add an attribute writing rule to the writer.
1134 template <typename Value>
1135 GraphWriter& attribute(const std::string& caption, const Value& value) {
1136 _writer_bits::ValueStorageBase* storage =
1137 new _writer_bits::ValueStorage<Value>(value);
1138 _attributes.push_back(std::make_pair(caption, storage));
1142 /// \brief Attribute writing rule
1144 /// Add an attribute writing rule with specialized converter to the
1146 template <typename Value, typename Converter>
1147 GraphWriter& attribute(const std::string& caption, const Value& value,
1148 const Converter& converter = Converter()) {
1149 _writer_bits::ValueStorageBase* storage =
1150 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1151 _attributes.push_back(std::make_pair(caption, storage));
1155 /// \brief Node writing rule
1157 /// Add a node writing rule to the writer.
1158 GraphWriter& node(const std::string& caption, const Node& node) {
1159 typedef _writer_bits::MapLookUpConverter<Node> Converter;
1160 Converter converter(_node_index);
1161 _writer_bits::ValueStorageBase* storage =
1162 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1163 _attributes.push_back(std::make_pair(caption, storage));
1167 /// \brief Edge writing rule
1169 /// Add an edge writing rule to writer.
1170 GraphWriter& edge(const std::string& caption, const Edge& edge) {
1171 typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1172 Converter converter(_edge_index);
1173 _writer_bits::ValueStorageBase* storage =
1174 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1175 _attributes.push_back(std::make_pair(caption, storage));
1179 /// \brief Arc writing rule
1181 /// Add an arc writing rule to writer.
1182 GraphWriter& arc(const std::string& caption, const Arc& arc) {
1183 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1184 Converter converter(_graph, _edge_index);
1185 _writer_bits::ValueStorageBase* storage =
1186 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1187 _attributes.push_back(std::make_pair(caption, storage));
1191 /// \name Section captions
1194 /// \brief Add an additional caption to the \c \@nodes section
1196 /// Add an additional caption to the \c \@nodes section.
1197 GraphWriter& nodes(const std::string& caption) {
1198 _nodes_caption = caption;
1202 /// \brief Add an additional caption to the \c \@arcs section
1204 /// Add an additional caption to the \c \@arcs section.
1205 GraphWriter& edges(const std::string& caption) {
1206 _edges_caption = caption;
1210 /// \brief Add an additional caption to the \c \@attributes section
1212 /// Add an additional caption to the \c \@attributes section.
1213 GraphWriter& attributes(const std::string& caption) {
1214 _attributes_caption = caption;
1218 /// \name Skipping section
1221 /// \brief Skip writing the node set
1223 /// The \c \@nodes section will not be written to the stream.
1224 GraphWriter& skipNodes() {
1225 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1230 /// \brief Skip writing edge set
1232 /// The \c \@edges section will not be written to the stream.
1233 GraphWriter& skipEdges() {
1234 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1244 _writer_bits::MapStorageBase<Node>* label = 0;
1245 for (typename NodeMaps::iterator it = _node_maps.begin();
1246 it != _node_maps.end(); ++it) {
1247 if (it->first == "label") {
1254 if (!_nodes_caption.empty()) {
1255 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1260 *_os << "label" << '\t';
1262 for (typename NodeMaps::iterator it = _node_maps.begin();
1263 it != _node_maps.end(); ++it) {
1264 _writer_bits::writeToken(*_os, it->first) << '\t';
1268 std::vector<Node> nodes;
1269 for (NodeIt n(_graph); n != INVALID; ++n) {
1274 IdMap<Graph, Node> id_map(_graph);
1275 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1276 std::sort(nodes.begin(), nodes.end(), id_less);
1281 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1284 std::ostringstream os;
1286 _writer_bits::writeToken(*_os, os.str());
1288 _node_index.insert(std::make_pair(n, os.str()));
1290 for (typename NodeMaps::iterator it = _node_maps.begin();
1291 it != _node_maps.end(); ++it) {
1292 std::string value = it->second->get(n);
1293 _writer_bits::writeToken(*_os, value);
1294 if (it->first == "label") {
1295 _node_index.insert(std::make_pair(n, value));
1303 void createNodeIndex() {
1304 _writer_bits::MapStorageBase<Node>* label = 0;
1305 for (typename NodeMaps::iterator it = _node_maps.begin();
1306 it != _node_maps.end(); ++it) {
1307 if (it->first == "label") {
1314 for (NodeIt n(_graph); n != INVALID; ++n) {
1315 std::ostringstream os;
1317 _node_index.insert(std::make_pair(n, os.str()));
1320 for (NodeIt n(_graph); n != INVALID; ++n) {
1321 std::string value = label->get(n);
1322 _node_index.insert(std::make_pair(n, value));
1328 _writer_bits::MapStorageBase<Edge>* label = 0;
1329 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1330 it != _edge_maps.end(); ++it) {
1331 if (it->first == "label") {
1338 if (!_edges_caption.empty()) {
1339 _writer_bits::writeToken(*_os << ' ', _edges_caption);
1343 *_os << '\t' << '\t';
1345 *_os << "label" << '\t';
1347 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1348 it != _edge_maps.end(); ++it) {
1349 _writer_bits::writeToken(*_os, it->first) << '\t';
1353 std::vector<Edge> edges;
1354 for (EdgeIt n(_graph); n != INVALID; ++n) {
1359 IdMap<Graph, Edge> id_map(_graph);
1360 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1361 std::sort(edges.begin(), edges.end(), id_less);
1366 for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1368 _writer_bits::writeToken(*_os, _node_index.
1369 find(_graph.u(e))->second);
1371 _writer_bits::writeToken(*_os, _node_index.
1372 find(_graph.v(e))->second);
1375 std::ostringstream os;
1377 _writer_bits::writeToken(*_os, os.str());
1379 _edge_index.insert(std::make_pair(e, os.str()));
1381 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1382 it != _edge_maps.end(); ++it) {
1383 std::string value = it->second->get(e);
1384 _writer_bits::writeToken(*_os, value);
1385 if (it->first == "label") {
1386 _edge_index.insert(std::make_pair(e, value));
1394 void createEdgeIndex() {
1395 _writer_bits::MapStorageBase<Edge>* label = 0;
1396 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1397 it != _edge_maps.end(); ++it) {
1398 if (it->first == "label") {
1405 for (EdgeIt e(_graph); e != INVALID; ++e) {
1406 std::ostringstream os;
1408 _edge_index.insert(std::make_pair(e, os.str()));
1411 for (EdgeIt e(_graph); e != INVALID; ++e) {
1412 std::string value = label->get(e);
1413 _edge_index.insert(std::make_pair(e, value));
1418 void writeAttributes() {
1419 if (_attributes.empty()) return;
1420 *_os << "@attributes";
1421 if (!_attributes_caption.empty()) {
1422 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1425 for (typename Attributes::iterator it = _attributes.begin();
1426 it != _attributes.end(); ++it) {
1427 _writer_bits::writeToken(*_os, it->first) << ' ';
1428 _writer_bits::writeToken(*_os, it->second->get());
1435 /// \name Execution of the writer
1438 /// \brief Start the batch processing
1440 /// This function starts the batch processing.
1455 /// \brief Give back the stream of the writer
1457 /// Give back the stream of the writer
1458 std::ostream& ostream() {
1465 /// \brief Return a \ref GraphWriter class
1467 /// This function just returns a \ref GraphWriter class.
1468 /// \relates GraphWriter
1469 template <typename Graph>
1470 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1471 GraphWriter<Graph> tmp(os, graph);
1475 /// \brief Return a \ref GraphWriter class
1477 /// This function just returns a \ref GraphWriter class.
1478 /// \relates GraphWriter
1479 template <typename Graph>
1480 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1481 GraphWriter<Graph> tmp(fn, graph);
1485 /// \brief Return a \ref GraphWriter class
1487 /// This function just returns a \ref GraphWriter class.
1488 /// \relates GraphWriter
1489 template <typename Graph>
1490 GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1491 GraphWriter<Graph> tmp(fn, graph);