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/core.h>
38 #include <lemon/maps.h>
42 namespace _writer_bits {
44 template <typename Value>
45 struct DefaultConverter {
46 std::string operator()(const Value& value) {
47 std::ostringstream os;
54 bool operator<(const T&, const T&) {
55 throw DataFormatError("Label map is not comparable");
58 template <typename _Map>
62 typedef typename Map::Key Item;
68 MapLess(const Map& map) : _map(map) {}
70 bool operator()(const Item& left, const Item& right) {
71 return _map[left] < _map[right];
75 template <typename _Graph, bool _dir, typename _Map>
76 class GraphArcMapLess {
80 typedef typename Graph::Edge Item;
87 GraphArcMapLess(const Graph& graph, const Map& map)
88 : _graph(graph), _map(map) {}
90 bool operator()(const Item& left, const Item& right) {
91 return _map[_graph.direct(left, _dir)] <
92 _map[_graph.direct(right, _dir)];
96 template <typename _Item>
97 class MapStorageBase {
103 virtual ~MapStorageBase() {}
105 virtual std::string get(const Item& item) = 0;
106 virtual void sort(std::vector<Item>&) = 0;
109 template <typename _Item, typename _Map,
110 typename _Converter = DefaultConverter<typename _Map::Value> >
111 class MapStorage : public MapStorageBase<_Item> {
114 typedef _Converter Converter;
119 Converter _converter;
122 MapStorage(const Map& map, const Converter& converter = Converter())
123 : _map(map), _converter(converter) {}
124 virtual ~MapStorage() {}
126 virtual std::string get(const Item& item) {
127 return _converter(_map[item]);
129 virtual void sort(std::vector<Item>& items) {
130 MapLess<Map> less(_map);
131 std::sort(items.begin(), items.end(), less);
135 template <typename _Graph, bool _dir, typename _Map,
136 typename _Converter = DefaultConverter<typename _Map::Value> >
137 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
140 typedef _Converter Converter;
141 typedef _Graph Graph;
142 typedef typename Graph::Edge Item;
143 static const bool dir = _dir;
148 Converter _converter;
151 GraphArcMapStorage(const Graph& graph, const Map& map,
152 const Converter& converter = Converter())
153 : _graph(graph), _map(map), _converter(converter) {}
154 virtual ~GraphArcMapStorage() {}
156 virtual std::string get(const Item& item) {
157 return _converter(_map[_graph.direct(item, dir)]);
159 virtual void sort(std::vector<Item>& items) {
160 GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
161 std::sort(items.begin(), items.end(), less);
165 class ValueStorageBase {
167 ValueStorageBase() {}
168 virtual ~ValueStorageBase() {}
170 virtual std::string get() = 0;
173 template <typename _Value, typename _Converter = DefaultConverter<_Value> >
174 class ValueStorage : public ValueStorageBase {
176 typedef _Value Value;
177 typedef _Converter Converter;
181 Converter _converter;
184 ValueStorage(const Value& value, const Converter& converter = Converter())
185 : _value(value), _converter(converter) {}
187 virtual std::string get() {
188 return _converter(_value);
192 template <typename Value>
193 struct MapLookUpConverter {
194 const std::map<Value, std::string>& _map;
196 MapLookUpConverter(const std::map<Value, std::string>& map)
199 std::string operator()(const Value& str) {
200 typename std::map<Value, std::string>::const_iterator it =
202 if (it == _map.end()) {
203 throw DataFormatError("Item not found");
209 template <typename Graph>
210 struct GraphArcLookUpConverter {
212 const std::map<typename Graph::Edge, std::string>& _map;
214 GraphArcLookUpConverter(const Graph& graph,
215 const std::map<typename Graph::Edge,
217 : _graph(graph), _map(map) {}
219 std::string operator()(const typename Graph::Arc& val) {
220 typename std::map<typename Graph::Edge, std::string>
221 ::const_iterator it = _map.find(val);
222 if (it == _map.end()) {
223 throw DataFormatError("Item not found");
225 return (_graph.direction(val) ? '+' : '-') + it->second;
229 inline bool isWhiteSpace(char c) {
230 return c == ' ' || c == '\t' || c == '\v' ||
231 c == '\n' || c == '\r' || c == '\f';
234 inline bool isEscaped(char c) {
235 return c == '\\' || c == '\"' || c == '\'' ||
236 c == '\a' || c == '\b';
239 inline static void writeEscape(std::ostream& os, char c) {
270 std::ios::fmtflags flags = os.flags();
271 os << '\\' << std::oct << static_cast<int>(c);
280 inline bool requireEscape(const std::string& str) {
281 if (str.empty() || str[0] == '@') return true;
282 std::istringstream is(str);
285 if (isWhiteSpace(c) || isEscaped(c)) {
292 inline std::ostream& writeToken(std::ostream& os, const std::string& str) {
294 if (requireEscape(str)) {
296 for (std::string::const_iterator it = str.begin();
297 it != str.end(); ++it) {
298 writeEscape(os, *it);
309 template <typename Digraph>
312 template <typename Digraph>
313 DigraphWriter<Digraph> digraphWriter(std::ostream& os,
314 const Digraph& digraph);
316 template <typename Digraph>
317 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
318 const Digraph& digraph);
320 template <typename Digraph>
321 DigraphWriter<Digraph> digraphWriter(const char *fn,
322 const Digraph& digraph);
324 /// \ingroup lemon_io
326 /// \brief \ref lgf-format "LGF" writer for directed graphs
328 /// This utility writes an \ref lgf-format "LGF" file.
330 /// The writing method does a batch processing. The user creates a
331 /// writer object, then various writing rules can be added to the
332 /// writer, and eventually the writing is executed with the \c run()
333 /// member function. A map writing rule can be added to the writer
334 /// with the \c nodeMap() or \c arcMap() members. An optional
335 /// converter parameter can also be added as a standard functor
336 /// converting from the value type of the map to \c std::string. If it
337 /// is set, it will determine how the value type of the map is written to
338 /// the output stream. If the functor is not set, then a default
339 /// conversion will be used. The \c attribute(), \c node() and \c
340 /// arc() functions are used to add attribute writing rules.
343 /// DigraphWriter<Digraph>(std::cout, digraph).
344 /// nodeMap("coordinates", coord_map).
345 /// nodeMap("size", size).
346 /// nodeMap("title", title).
347 /// arcMap("capacity", cap_map).
348 /// node("source", src).
349 /// node("target", trg).
350 /// attribute("caption", caption).
355 /// By default, the writer does not write additional captions to the
356 /// sections, but they can be give as an optional parameter of
357 /// the \c nodes(), \c arcs() or \c
358 /// attributes() functions.
360 /// The \c skipNodes() and \c skipArcs() functions forbid the
361 /// writing of the sections. If two arc sections should be written
362 /// to the output, it can be done in two passes, the first pass
363 /// writes the node section and the first arc section, then the
364 /// second pass skips the node section and writes just the arc
365 /// section to the stream. The output stream can be retrieved with
366 /// the \c ostream() function, hence the second pass can append its
367 /// output to the output of the first pass.
368 template <typename _Digraph>
369 class DigraphWriter {
372 typedef _Digraph Digraph;
373 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
381 const Digraph& _digraph;
383 std::string _nodes_caption;
384 std::string _arcs_caption;
385 std::string _attributes_caption;
387 typedef std::map<Node, std::string> NodeIndex;
388 NodeIndex _node_index;
389 typedef std::map<Arc, std::string> ArcIndex;
392 typedef std::vector<std::pair<std::string,
393 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
396 typedef std::vector<std::pair<std::string,
397 _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
400 typedef std::vector<std::pair<std::string,
401 _writer_bits::ValueStorageBase*> > Attributes;
402 Attributes _attributes;
409 /// \brief Constructor
411 /// Construct a directed graph writer, which writes to the given
413 DigraphWriter(std::ostream& is, const Digraph& digraph)
414 : _os(&is), local_os(false), _digraph(digraph),
415 _skip_nodes(false), _skip_arcs(false) {}
417 /// \brief Constructor
419 /// Construct a directed graph writer, which writes to the given
421 DigraphWriter(const std::string& fn, const Digraph& digraph)
422 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
423 _skip_nodes(false), _skip_arcs(false) {}
425 /// \brief Constructor
427 /// Construct a directed graph writer, which writes to the given
429 DigraphWriter(const char* fn, const Digraph& digraph)
430 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
431 _skip_nodes(false), _skip_arcs(false) {}
433 /// \brief Destructor
435 for (typename NodeMaps::iterator it = _node_maps.begin();
436 it != _node_maps.end(); ++it) {
440 for (typename ArcMaps::iterator it = _arc_maps.begin();
441 it != _arc_maps.end(); ++it) {
445 for (typename Attributes::iterator it = _attributes.begin();
446 it != _attributes.end(); ++it) {
457 friend DigraphWriter<Digraph> digraphWriter<>(std::ostream& os,
458 const Digraph& digraph);
459 friend DigraphWriter<Digraph> digraphWriter<>(const std::string& fn,
460 const Digraph& digraph);
461 friend DigraphWriter<Digraph> digraphWriter<>(const char *fn,
462 const Digraph& digraph);
464 DigraphWriter(DigraphWriter& other)
465 : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
466 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
469 other.local_os = false;
471 _node_index.swap(other._node_index);
472 _arc_index.swap(other._arc_index);
474 _node_maps.swap(other._node_maps);
475 _arc_maps.swap(other._arc_maps);
476 _attributes.swap(other._attributes);
478 _nodes_caption = other._nodes_caption;
479 _arcs_caption = other._arcs_caption;
480 _attributes_caption = other._attributes_caption;
483 DigraphWriter& operator=(const DigraphWriter&);
487 /// \name Writing rules
490 /// \brief Node map writing rule
492 /// Add a node map writing rule to the writer.
493 template <typename Map>
494 DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
495 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
496 _writer_bits::MapStorageBase<Node>* storage =
497 new _writer_bits::MapStorage<Node, Map>(map);
498 _node_maps.push_back(std::make_pair(caption, storage));
502 /// \brief Node map writing rule
504 /// Add a node map writing rule with specialized converter to the
506 template <typename Map, typename Converter>
507 DigraphWriter& nodeMap(const std::string& caption, const Map& map,
508 const Converter& converter = Converter()) {
509 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
510 _writer_bits::MapStorageBase<Node>* storage =
511 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
512 _node_maps.push_back(std::make_pair(caption, storage));
516 /// \brief Arc map writing rule
518 /// Add an arc map writing rule to the writer.
519 template <typename Map>
520 DigraphWriter& arcMap(const std::string& caption, const Map& map) {
521 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
522 _writer_bits::MapStorageBase<Arc>* storage =
523 new _writer_bits::MapStorage<Arc, Map>(map);
524 _arc_maps.push_back(std::make_pair(caption, storage));
528 /// \brief Arc map writing rule
530 /// Add an arc map writing rule with specialized converter to the
532 template <typename Map, typename Converter>
533 DigraphWriter& arcMap(const std::string& caption, const Map& map,
534 const Converter& converter = Converter()) {
535 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
536 _writer_bits::MapStorageBase<Arc>* storage =
537 new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
538 _arc_maps.push_back(std::make_pair(caption, storage));
542 /// \brief Attribute writing rule
544 /// Add an attribute writing rule to the writer.
545 template <typename Value>
546 DigraphWriter& attribute(const std::string& caption, const Value& value) {
547 _writer_bits::ValueStorageBase* storage =
548 new _writer_bits::ValueStorage<Value>(value);
549 _attributes.push_back(std::make_pair(caption, storage));
553 /// \brief Attribute writing rule
555 /// Add an attribute writing rule with specialized converter to the
557 template <typename Value, typename Converter>
558 DigraphWriter& attribute(const std::string& caption, const Value& value,
559 const Converter& converter = Converter()) {
560 _writer_bits::ValueStorageBase* storage =
561 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
562 _attributes.push_back(std::make_pair(caption, storage));
566 /// \brief Node writing rule
568 /// Add a node writing rule to the writer.
569 DigraphWriter& node(const std::string& caption, const Node& node) {
570 typedef _writer_bits::MapLookUpConverter<Node> Converter;
571 Converter converter(_node_index);
572 _writer_bits::ValueStorageBase* storage =
573 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
574 _attributes.push_back(std::make_pair(caption, storage));
578 /// \brief Arc writing rule
580 /// Add an arc writing rule to writer.
581 DigraphWriter& arc(const std::string& caption, const Arc& arc) {
582 typedef _writer_bits::MapLookUpConverter<Arc> Converter;
583 Converter converter(_arc_index);
584 _writer_bits::ValueStorageBase* storage =
585 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
586 _attributes.push_back(std::make_pair(caption, storage));
590 /// \name Section captions
593 /// \brief Add an additional caption to the \c \@nodes section
595 /// Add an additional caption to the \c \@nodes section.
596 DigraphWriter& nodes(const std::string& caption) {
597 _nodes_caption = caption;
601 /// \brief Add an additional caption to the \c \@arcs section
603 /// Add an additional caption to the \c \@arcs section.
604 DigraphWriter& arcs(const std::string& caption) {
605 _arcs_caption = caption;
609 /// \brief Add an additional caption to the \c \@attributes section
611 /// Add an additional caption to the \c \@attributes section.
612 DigraphWriter& attributes(const std::string& caption) {
613 _attributes_caption = caption;
617 /// \name Skipping section
620 /// \brief Skip writing the node set
622 /// The \c \@nodes section will not be written to the stream.
623 DigraphWriter& skipNodes() {
624 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
629 /// \brief Skip writing arc set
631 /// The \c \@arcs section will not be written to the stream.
632 DigraphWriter& skipArcs() {
633 LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
643 _writer_bits::MapStorageBase<Node>* label = 0;
644 for (typename NodeMaps::iterator it = _node_maps.begin();
645 it != _node_maps.end(); ++it) {
646 if (it->first == "label") {
653 if (!_nodes_caption.empty()) {
654 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
659 *_os << "label" << '\t';
661 for (typename NodeMaps::iterator it = _node_maps.begin();
662 it != _node_maps.end(); ++it) {
663 _writer_bits::writeToken(*_os, it->first) << '\t';
667 std::vector<Node> nodes;
668 for (NodeIt n(_digraph); n != INVALID; ++n) {
673 IdMap<Digraph, Node> id_map(_digraph);
674 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
675 std::sort(nodes.begin(), nodes.end(), id_less);
680 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
683 std::ostringstream os;
684 os << _digraph.id(n);
685 _writer_bits::writeToken(*_os, os.str());
687 _node_index.insert(std::make_pair(n, os.str()));
689 for (typename NodeMaps::iterator it = _node_maps.begin();
690 it != _node_maps.end(); ++it) {
691 std::string value = it->second->get(n);
692 _writer_bits::writeToken(*_os, value);
693 if (it->first == "label") {
694 _node_index.insert(std::make_pair(n, value));
702 void createNodeIndex() {
703 _writer_bits::MapStorageBase<Node>* label = 0;
704 for (typename NodeMaps::iterator it = _node_maps.begin();
705 it != _node_maps.end(); ++it) {
706 if (it->first == "label") {
713 for (NodeIt n(_digraph); n != INVALID; ++n) {
714 std::ostringstream os;
715 os << _digraph.id(n);
716 _node_index.insert(std::make_pair(n, os.str()));
719 for (NodeIt n(_digraph); n != INVALID; ++n) {
720 std::string value = label->get(n);
721 _node_index.insert(std::make_pair(n, value));
727 _writer_bits::MapStorageBase<Arc>* label = 0;
728 for (typename ArcMaps::iterator it = _arc_maps.begin();
729 it != _arc_maps.end(); ++it) {
730 if (it->first == "label") {
737 if (!_arcs_caption.empty()) {
738 _writer_bits::writeToken(*_os << ' ', _arcs_caption);
742 *_os << '\t' << '\t';
744 *_os << "label" << '\t';
746 for (typename ArcMaps::iterator it = _arc_maps.begin();
747 it != _arc_maps.end(); ++it) {
748 _writer_bits::writeToken(*_os, it->first) << '\t';
752 std::vector<Arc> arcs;
753 for (ArcIt n(_digraph); n != INVALID; ++n) {
758 IdMap<Digraph, Arc> id_map(_digraph);
759 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
760 std::sort(arcs.begin(), arcs.end(), id_less);
765 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
767 _writer_bits::writeToken(*_os, _node_index.
768 find(_digraph.source(a))->second);
770 _writer_bits::writeToken(*_os, _node_index.
771 find(_digraph.target(a))->second);
774 std::ostringstream os;
775 os << _digraph.id(a);
776 _writer_bits::writeToken(*_os, os.str());
778 _arc_index.insert(std::make_pair(a, os.str()));
780 for (typename ArcMaps::iterator it = _arc_maps.begin();
781 it != _arc_maps.end(); ++it) {
782 std::string value = it->second->get(a);
783 _writer_bits::writeToken(*_os, value);
784 if (it->first == "label") {
785 _arc_index.insert(std::make_pair(a, value));
793 void createArcIndex() {
794 _writer_bits::MapStorageBase<Arc>* label = 0;
795 for (typename ArcMaps::iterator it = _arc_maps.begin();
796 it != _arc_maps.end(); ++it) {
797 if (it->first == "label") {
804 for (ArcIt a(_digraph); a != INVALID; ++a) {
805 std::ostringstream os;
806 os << _digraph.id(a);
807 _arc_index.insert(std::make_pair(a, os.str()));
810 for (ArcIt a(_digraph); a != INVALID; ++a) {
811 std::string value = label->get(a);
812 _arc_index.insert(std::make_pair(a, value));
817 void writeAttributes() {
818 if (_attributes.empty()) return;
819 *_os << "@attributes";
820 if (!_attributes_caption.empty()) {
821 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
824 for (typename Attributes::iterator it = _attributes.begin();
825 it != _attributes.end(); ++it) {
826 _writer_bits::writeToken(*_os, it->first) << ' ';
827 _writer_bits::writeToken(*_os, it->second->get());
834 /// \name Execution of the writer
837 /// \brief Start the batch processing
839 /// This function starts the batch processing.
854 /// \brief Give back the stream of the writer
856 /// Give back the stream of the writer.
857 std::ostream& ostream() {
864 /// \brief Return a \ref DigraphWriter class
866 /// This function just returns a \ref DigraphWriter class.
867 /// \relates DigraphWriter
868 template <typename Digraph>
869 DigraphWriter<Digraph> digraphWriter(std::ostream& os,
870 const Digraph& digraph) {
871 DigraphWriter<Digraph> tmp(os, digraph);
875 /// \brief Return a \ref DigraphWriter class
877 /// This function just returns a \ref DigraphWriter class.
878 /// \relates DigraphWriter
879 template <typename Digraph>
880 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
881 const Digraph& digraph) {
882 DigraphWriter<Digraph> tmp(fn, digraph);
886 /// \brief Return a \ref DigraphWriter class
888 /// This function just returns a \ref DigraphWriter class.
889 /// \relates DigraphWriter
890 template <typename Digraph>
891 DigraphWriter<Digraph> digraphWriter(const char* fn,
892 const Digraph& digraph) {
893 DigraphWriter<Digraph> tmp(fn, digraph);
897 template <typename Graph>
900 template <typename Graph>
901 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph);
903 template <typename Graph>
904 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph);
906 template <typename Graph>
907 GraphWriter<Graph> graphWriter(const char *fn, const Graph& graph);
909 /// \ingroup lemon_io
911 /// \brief \ref lgf-format "LGF" writer for directed graphs
913 /// This utility writes an \ref lgf-format "LGF" file.
915 /// It can be used almost the same way as \c DigraphWriter.
916 /// The only difference is that this class can handle edges and
917 /// edge maps as well as arcs and arc maps.
919 /// The arc maps are written into the file as two columns, the
920 /// caption of the columns are the name of the map prefixed with \c
921 /// '+' and \c '-'. The arcs are written into the \c \@attributes
922 /// section as a \c '+' or a \c '-' prefix (depends on the direction
923 /// of the arc) and the label of corresponding edge.
924 template <typename _Graph>
928 typedef _Graph Graph;
929 TEMPLATE_GRAPH_TYPEDEFS(Graph);
939 std::string _nodes_caption;
940 std::string _edges_caption;
941 std::string _attributes_caption;
943 typedef std::map<Node, std::string> NodeIndex;
944 NodeIndex _node_index;
945 typedef std::map<Edge, std::string> EdgeIndex;
946 EdgeIndex _edge_index;
948 typedef std::vector<std::pair<std::string,
949 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
952 typedef std::vector<std::pair<std::string,
953 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
956 typedef std::vector<std::pair<std::string,
957 _writer_bits::ValueStorageBase*> > Attributes;
958 Attributes _attributes;
965 /// \brief Constructor
967 /// Construct a directed graph writer, which writes to the given
969 GraphWriter(std::ostream& is, const Graph& graph)
970 : _os(&is), local_os(false), _graph(graph),
971 _skip_nodes(false), _skip_edges(false) {}
973 /// \brief Constructor
975 /// Construct a directed graph writer, which writes to the given
977 GraphWriter(const std::string& fn, const Graph& graph)
978 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
979 _skip_nodes(false), _skip_edges(false) {}
981 /// \brief Constructor
983 /// Construct a directed graph writer, which writes to the given
985 GraphWriter(const char* fn, const Graph& graph)
986 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
987 _skip_nodes(false), _skip_edges(false) {}
989 /// \brief Destructor
991 for (typename NodeMaps::iterator it = _node_maps.begin();
992 it != _node_maps.end(); ++it) {
996 for (typename EdgeMaps::iterator it = _edge_maps.begin();
997 it != _edge_maps.end(); ++it) {
1001 for (typename Attributes::iterator it = _attributes.begin();
1002 it != _attributes.end(); ++it) {
1013 friend GraphWriter<Graph> graphWriter<>(std::ostream& os,
1014 const Graph& graph);
1015 friend GraphWriter<Graph> graphWriter<>(const std::string& fn,
1016 const Graph& graph);
1017 friend GraphWriter<Graph> graphWriter<>(const char *fn,
1018 const Graph& graph);
1020 GraphWriter(GraphWriter& other)
1021 : _os(other._os), local_os(other.local_os), _graph(other._graph),
1022 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
1025 other.local_os = false;
1027 _node_index.swap(other._node_index);
1028 _edge_index.swap(other._edge_index);
1030 _node_maps.swap(other._node_maps);
1031 _edge_maps.swap(other._edge_maps);
1032 _attributes.swap(other._attributes);
1034 _nodes_caption = other._nodes_caption;
1035 _edges_caption = other._edges_caption;
1036 _attributes_caption = other._attributes_caption;
1039 GraphWriter& operator=(const GraphWriter&);
1043 /// \name Writing rules
1046 /// \brief Node map writing rule
1048 /// Add a node map writing rule to the writer.
1049 template <typename Map>
1050 GraphWriter& nodeMap(const std::string& caption, const Map& map) {
1051 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1052 _writer_bits::MapStorageBase<Node>* storage =
1053 new _writer_bits::MapStorage<Node, Map>(map);
1054 _node_maps.push_back(std::make_pair(caption, storage));
1058 /// \brief Node map writing rule
1060 /// Add a node map writing rule with specialized converter to the
1062 template <typename Map, typename Converter>
1063 GraphWriter& nodeMap(const std::string& caption, const Map& map,
1064 const Converter& converter = Converter()) {
1065 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1066 _writer_bits::MapStorageBase<Node>* storage =
1067 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1068 _node_maps.push_back(std::make_pair(caption, storage));
1072 /// \brief Edge map writing rule
1074 /// Add an edge map writing rule to the writer.
1075 template <typename Map>
1076 GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1077 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1078 _writer_bits::MapStorageBase<Edge>* storage =
1079 new _writer_bits::MapStorage<Edge, Map>(map);
1080 _edge_maps.push_back(std::make_pair(caption, storage));
1084 /// \brief Edge map writing rule
1086 /// Add an edge map writing rule with specialized converter to the
1088 template <typename Map, typename Converter>
1089 GraphWriter& edgeMap(const std::string& caption, const Map& map,
1090 const Converter& converter = Converter()) {
1091 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1092 _writer_bits::MapStorageBase<Edge>* storage =
1093 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1094 _edge_maps.push_back(std::make_pair(caption, storage));
1098 /// \brief Arc map writing rule
1100 /// Add an arc map writing rule to the writer.
1101 template <typename Map>
1102 GraphWriter& arcMap(const std::string& caption, const Map& map) {
1103 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1104 _writer_bits::MapStorageBase<Edge>* forward_storage =
1105 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1106 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1107 _writer_bits::MapStorageBase<Edge>* backward_storage =
1108 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1109 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1113 /// \brief Arc map writing rule
1115 /// Add an arc map writing rule with specialized converter to the
1117 template <typename Map, typename Converter>
1118 GraphWriter& arcMap(const std::string& caption, const Map& map,
1119 const Converter& converter = Converter()) {
1120 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1121 _writer_bits::MapStorageBase<Edge>* forward_storage =
1122 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1123 (_graph, map, converter);
1124 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1125 _writer_bits::MapStorageBase<Edge>* backward_storage =
1126 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1127 (_graph, map, converter);
1128 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1132 /// \brief Attribute writing rule
1134 /// Add an attribute writing rule to the writer.
1135 template <typename Value>
1136 GraphWriter& attribute(const std::string& caption, const Value& value) {
1137 _writer_bits::ValueStorageBase* storage =
1138 new _writer_bits::ValueStorage<Value>(value);
1139 _attributes.push_back(std::make_pair(caption, storage));
1143 /// \brief Attribute writing rule
1145 /// Add an attribute writing rule with specialized converter to the
1147 template <typename Value, typename Converter>
1148 GraphWriter& attribute(const std::string& caption, const Value& value,
1149 const Converter& converter = Converter()) {
1150 _writer_bits::ValueStorageBase* storage =
1151 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1152 _attributes.push_back(std::make_pair(caption, storage));
1156 /// \brief Node writing rule
1158 /// Add a node writing rule to the writer.
1159 GraphWriter& node(const std::string& caption, const Node& node) {
1160 typedef _writer_bits::MapLookUpConverter<Node> Converter;
1161 Converter converter(_node_index);
1162 _writer_bits::ValueStorageBase* storage =
1163 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1164 _attributes.push_back(std::make_pair(caption, storage));
1168 /// \brief Edge writing rule
1170 /// Add an edge writing rule to writer.
1171 GraphWriter& edge(const std::string& caption, const Edge& edge) {
1172 typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1173 Converter converter(_edge_index);
1174 _writer_bits::ValueStorageBase* storage =
1175 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1176 _attributes.push_back(std::make_pair(caption, storage));
1180 /// \brief Arc writing rule
1182 /// Add an arc writing rule to writer.
1183 GraphWriter& arc(const std::string& caption, const Arc& arc) {
1184 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1185 Converter converter(_graph, _edge_index);
1186 _writer_bits::ValueStorageBase* storage =
1187 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1188 _attributes.push_back(std::make_pair(caption, storage));
1192 /// \name Section captions
1195 /// \brief Add an additional caption to the \c \@nodes section
1197 /// Add an additional caption to the \c \@nodes section.
1198 GraphWriter& nodes(const std::string& caption) {
1199 _nodes_caption = caption;
1203 /// \brief Add an additional caption to the \c \@arcs section
1205 /// Add an additional caption to the \c \@arcs section.
1206 GraphWriter& edges(const std::string& caption) {
1207 _edges_caption = caption;
1211 /// \brief Add an additional caption to the \c \@attributes section
1213 /// Add an additional caption to the \c \@attributes section.
1214 GraphWriter& attributes(const std::string& caption) {
1215 _attributes_caption = caption;
1219 /// \name Skipping section
1222 /// \brief Skip writing the node set
1224 /// The \c \@nodes section will not be written to the stream.
1225 GraphWriter& skipNodes() {
1226 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1231 /// \brief Skip writing edge set
1233 /// The \c \@edges section will not be written to the stream.
1234 GraphWriter& skipEdges() {
1235 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1245 _writer_bits::MapStorageBase<Node>* label = 0;
1246 for (typename NodeMaps::iterator it = _node_maps.begin();
1247 it != _node_maps.end(); ++it) {
1248 if (it->first == "label") {
1255 if (!_nodes_caption.empty()) {
1256 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1261 *_os << "label" << '\t';
1263 for (typename NodeMaps::iterator it = _node_maps.begin();
1264 it != _node_maps.end(); ++it) {
1265 _writer_bits::writeToken(*_os, it->first) << '\t';
1269 std::vector<Node> nodes;
1270 for (NodeIt n(_graph); n != INVALID; ++n) {
1275 IdMap<Graph, Node> id_map(_graph);
1276 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1277 std::sort(nodes.begin(), nodes.end(), id_less);
1282 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1285 std::ostringstream os;
1287 _writer_bits::writeToken(*_os, os.str());
1289 _node_index.insert(std::make_pair(n, os.str()));
1291 for (typename NodeMaps::iterator it = _node_maps.begin();
1292 it != _node_maps.end(); ++it) {
1293 std::string value = it->second->get(n);
1294 _writer_bits::writeToken(*_os, value);
1295 if (it->first == "label") {
1296 _node_index.insert(std::make_pair(n, value));
1304 void createNodeIndex() {
1305 _writer_bits::MapStorageBase<Node>* label = 0;
1306 for (typename NodeMaps::iterator it = _node_maps.begin();
1307 it != _node_maps.end(); ++it) {
1308 if (it->first == "label") {
1315 for (NodeIt n(_graph); n != INVALID; ++n) {
1316 std::ostringstream os;
1318 _node_index.insert(std::make_pair(n, os.str()));
1321 for (NodeIt n(_graph); n != INVALID; ++n) {
1322 std::string value = label->get(n);
1323 _node_index.insert(std::make_pair(n, value));
1329 _writer_bits::MapStorageBase<Edge>* label = 0;
1330 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1331 it != _edge_maps.end(); ++it) {
1332 if (it->first == "label") {
1339 if (!_edges_caption.empty()) {
1340 _writer_bits::writeToken(*_os << ' ', _edges_caption);
1344 *_os << '\t' << '\t';
1346 *_os << "label" << '\t';
1348 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1349 it != _edge_maps.end(); ++it) {
1350 _writer_bits::writeToken(*_os, it->first) << '\t';
1354 std::vector<Edge> edges;
1355 for (EdgeIt n(_graph); n != INVALID; ++n) {
1360 IdMap<Graph, Edge> id_map(_graph);
1361 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1362 std::sort(edges.begin(), edges.end(), id_less);
1367 for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1369 _writer_bits::writeToken(*_os, _node_index.
1370 find(_graph.u(e))->second);
1372 _writer_bits::writeToken(*_os, _node_index.
1373 find(_graph.v(e))->second);
1376 std::ostringstream os;
1378 _writer_bits::writeToken(*_os, os.str());
1380 _edge_index.insert(std::make_pair(e, os.str()));
1382 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1383 it != _edge_maps.end(); ++it) {
1384 std::string value = it->second->get(e);
1385 _writer_bits::writeToken(*_os, value);
1386 if (it->first == "label") {
1387 _edge_index.insert(std::make_pair(e, value));
1395 void createEdgeIndex() {
1396 _writer_bits::MapStorageBase<Edge>* label = 0;
1397 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1398 it != _edge_maps.end(); ++it) {
1399 if (it->first == "label") {
1406 for (EdgeIt e(_graph); e != INVALID; ++e) {
1407 std::ostringstream os;
1409 _edge_index.insert(std::make_pair(e, os.str()));
1412 for (EdgeIt e(_graph); e != INVALID; ++e) {
1413 std::string value = label->get(e);
1414 _edge_index.insert(std::make_pair(e, value));
1419 void writeAttributes() {
1420 if (_attributes.empty()) return;
1421 *_os << "@attributes";
1422 if (!_attributes_caption.empty()) {
1423 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1426 for (typename Attributes::iterator it = _attributes.begin();
1427 it != _attributes.end(); ++it) {
1428 _writer_bits::writeToken(*_os, it->first) << ' ';
1429 _writer_bits::writeToken(*_os, it->second->get());
1436 /// \name Execution of the writer
1439 /// \brief Start the batch processing
1441 /// This function starts the batch processing.
1456 /// \brief Give back the stream of the writer
1458 /// Give back the stream of the writer
1459 std::ostream& ostream() {
1466 /// \brief Return a \ref GraphWriter class
1468 /// This function just returns a \ref GraphWriter class.
1469 /// \relates GraphWriter
1470 template <typename Graph>
1471 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph& graph) {
1472 GraphWriter<Graph> tmp(os, graph);
1476 /// \brief Return a \ref GraphWriter class
1478 /// This function just returns a \ref GraphWriter class.
1479 /// \relates GraphWriter
1480 template <typename Graph>
1481 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph& graph) {
1482 GraphWriter<Graph> tmp(fn, graph);
1486 /// \brief Return a \ref GraphWriter class
1488 /// This function just returns a \ref GraphWriter class.
1489 /// \relates GraphWriter
1490 template <typename Graph>
1491 GraphWriter<Graph> graphWriter(const char* fn, const Graph& graph) {
1492 GraphWriter<Graph> tmp(fn, graph);