3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2008
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
21 ///\brief Lemon Graph Format writer.
24 #ifndef LEMON_LGF_WRITER_H
25 #define LEMON_LGF_WRITER_H
36 #include <lemon/assert.h>
37 #include <lemon/graph_utils.h>
41 namespace _writer_bits {
43 template <typename Value>
44 struct DefaultConverter {
45 std::string operator()(const Value& value) {
46 std::ostringstream os;
53 bool operator<(const T&, const T&) {
54 throw DataFormatError("Label map is not comparable");
57 template <typename _Map>
61 typedef typename Map::Key Item;
67 MapLess(const Map& map) : _map(map) {}
69 bool operator()(const Item& left, const Item& right) {
70 return _map[left] < _map[right];
74 template <typename _Graph, bool _dir, typename _Map>
75 class GraphArcMapLess {
79 typedef typename Graph::Edge Item;
86 GraphArcMapLess(const Graph& graph, const Map& map)
87 : _graph(graph), _map(map) {}
89 bool operator()(const Item& left, const Item& right) {
90 return _map[_graph.direct(left, _dir)] <
91 _map[_graph.direct(right, _dir)];
95 template <typename _Item>
96 class MapStorageBase {
102 virtual ~MapStorageBase() {}
104 virtual std::string get(const Item& item) = 0;
105 virtual void sort(std::vector<Item>&) = 0;
108 template <typename _Item, typename _Map,
109 typename _Converter = DefaultConverter<typename _Map::Value> >
110 class MapStorage : public MapStorageBase<_Item> {
113 typedef _Converter Converter;
118 Converter _converter;
121 MapStorage(const Map& map, const Converter& converter = Converter())
122 : _map(map), _converter(converter) {}
123 virtual ~MapStorage() {}
125 virtual std::string get(const Item& item) {
126 return _converter(_map[item]);
128 virtual void sort(std::vector<Item>& items) {
129 MapLess<Map> less(_map);
130 std::sort(items.begin(), items.end(), less);
134 template <typename _Graph, bool _dir, typename _Map,
135 typename _Converter = DefaultConverter<typename _Map::Value> >
136 class GraphArcMapStorage : public MapStorageBase<typename _Graph::Edge> {
139 typedef _Converter Converter;
140 typedef _Graph Graph;
141 typedef typename Graph::Edge Item;
142 static const bool dir = _dir;
147 Converter _converter;
150 GraphArcMapStorage(const Graph& graph, const Map& map,
151 const Converter& converter = Converter())
152 : _graph(graph), _map(map), _converter(converter) {}
153 virtual ~GraphArcMapStorage() {}
155 virtual std::string get(const Item& item) {
156 return _converter(_map[_graph.direct(item, dir)]);
158 virtual void sort(std::vector<Item>& items) {
159 GraphArcMapLess<Graph, dir, Map> less(_graph, _map);
160 std::sort(items.begin(), items.end(), less);
164 class ValueStorageBase {
166 ValueStorageBase() {}
167 virtual ~ValueStorageBase() {}
169 virtual std::string get() = 0;
172 template <typename _Value, typename _Converter = DefaultConverter<_Value> >
173 class ValueStorage : public ValueStorageBase {
175 typedef _Value Value;
176 typedef _Converter Converter;
180 Converter _converter;
183 ValueStorage(const Value& value, const Converter& converter = Converter())
184 : _value(value), _converter(converter) {}
186 virtual std::string get() {
187 return _converter(_value);
191 template <typename Value>
192 struct MapLookUpConverter {
193 const std::map<Value, std::string>& _map;
195 MapLookUpConverter(const std::map<Value, std::string>& map)
198 std::string operator()(const Value& str) {
199 typename std::map<Value, std::string>::const_iterator it =
201 if (it == _map.end()) {
202 throw DataFormatError("Item not found");
208 template <typename Graph>
209 struct GraphArcLookUpConverter {
211 const std::map<typename Graph::Edge, std::string>& _map;
213 GraphArcLookUpConverter(const Graph& graph,
214 const std::map<typename Graph::Edge,
216 : _graph(graph), _map(map) {}
218 std::string operator()(const typename Graph::Arc& val) {
219 typename std::map<typename Graph::Edge, std::string>
220 ::const_iterator it = _map.find(val);
221 if (it == _map.end()) {
222 throw DataFormatError("Item not found");
224 return (_graph.direction(val) ? '+' : '-') + it->second;
228 bool isWhiteSpace(char c) {
229 return c == ' ' || c == '\t' || c == '\v' ||
230 c == '\n' || c == '\r' || c == '\f';
233 bool isEscaped(char c) {
234 return c == '\\' || c == '\"' || c == '\'' ||
235 c == '\a' || c == '\b';
238 static void writeEscape(std::ostream& os, char c) {
269 std::ios::fmtflags flags = os.flags();
270 os << '\\' << std::oct << static_cast<int>(c);
279 bool requireEscape(const std::string& str) {
280 if (str.empty() || str[0] == '@') return true;
281 std::istringstream is(str);
284 if (isWhiteSpace(c) || isEscaped(c)) {
291 std::ostream& writeToken(std::ostream& os, const std::string& str) {
293 if (requireEscape(str)) {
295 for (std::string::const_iterator it = str.begin();
296 it != str.end(); ++it) {
297 writeEscape(os, *it);
308 /// \ingroup lemon_io
310 /// \brief LGF writer for directed graphs
312 /// This utility writes an \ref lgf-format "LGF" file.
314 /// The writing method does a batch processing. The user creates a
315 /// writer object, then various writing rules can be added to the
316 /// writer, and eventually the writing is executed with the \c run()
317 /// member function. A map writing rule can be added to the writer
318 /// with the \c nodeMap() or \c arcMap() members. An optional
319 /// converter parameter can also be added as a standard functor
320 /// converting from the value type of the map to std::string. If it
321 /// is set, it will determine how the map's value type is written to
322 /// the output stream. If the functor is not set, then a default
323 /// conversion will be used. The \c attribute(), \c node() and \c
324 /// arc() functions are used to add attribute writing rules.
327 /// DigraphWriter<Digraph>(std::cout, digraph).
328 /// nodeMap("coordinates", coord_map).
329 /// nodeMap("size", size).
330 /// nodeMap("title", title).
331 /// arcMap("capacity", cap_map).
332 /// node("source", src).
333 /// node("target", trg).
334 /// attribute("caption", caption).
339 /// By default, the writer does not write additional captions to the
340 /// sections, but they can be give as an optional parameter of
341 /// the \c nodes(), \c arcs() or \c
342 /// attributes() functions.
344 /// The \c skipNodes() and \c skipArcs() functions forbid the
345 /// writing of the sections. If two arc sections should be written
346 /// to the output, it can be done in two passes, the first pass
347 /// writes the node section and the first arc section, then the
348 /// second pass skips the node section and writes just the arc
349 /// section to the stream. The output stream can be retrieved with
350 /// the \c ostream() function, hence the second pass can append its
351 /// output to the output of the first pass.
352 template <typename _Digraph>
353 class DigraphWriter {
356 typedef _Digraph Digraph;
357 TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
367 std::string _nodes_caption;
368 std::string _arcs_caption;
369 std::string _attributes_caption;
371 typedef std::map<Node, std::string> NodeIndex;
372 NodeIndex _node_index;
373 typedef std::map<Arc, std::string> ArcIndex;
376 typedef std::vector<std::pair<std::string,
377 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
380 typedef std::vector<std::pair<std::string,
381 _writer_bits::MapStorageBase<Arc>* > >ArcMaps;
384 typedef std::vector<std::pair<std::string,
385 _writer_bits::ValueStorageBase*> > Attributes;
386 Attributes _attributes;
393 /// \brief Constructor
395 /// Construct a directed graph writer, which writes to the given
397 DigraphWriter(std::ostream& is, Digraph& digraph)
398 : _os(&is), local_os(false), _digraph(digraph),
399 _skip_nodes(false), _skip_arcs(false) {}
401 /// \brief Constructor
403 /// Construct a directed graph writer, which writes to the given
405 DigraphWriter(const std::string& fn, Digraph& digraph)
406 : _os(new std::ofstream(fn.c_str())), local_os(true), _digraph(digraph),
407 _skip_nodes(false), _skip_arcs(false) {}
409 /// \brief Constructor
411 /// Construct a directed graph writer, which writes to the given
413 DigraphWriter(const char* fn, Digraph& digraph)
414 : _os(new std::ofstream(fn)), local_os(true), _digraph(digraph),
415 _skip_nodes(false), _skip_arcs(false) {}
417 /// \brief Copy constructor
419 /// The copy constructor transfers all data from the other writer,
420 /// therefore the copied writer will not be usable more.
421 DigraphWriter(DigraphWriter& other)
422 : _os(other._os), local_os(other.local_os), _digraph(other._digraph),
423 _skip_nodes(other._skip_nodes), _skip_arcs(other._skip_arcs) {
426 other.local_os = false;
428 _node_index.swap(other._node_index);
429 _arc_index.swap(other._arc_index);
431 _node_maps.swap(other._node_maps);
432 _arc_maps.swap(other._arc_maps);
433 _attributes.swap(other._attributes);
435 _nodes_caption = other._nodes_caption;
436 _arcs_caption = other._arcs_caption;
437 _attributes_caption = other._attributes_caption;
440 /// \brief Destructor
442 for (typename NodeMaps::iterator it = _node_maps.begin();
443 it != _node_maps.end(); ++it) {
447 for (typename ArcMaps::iterator it = _arc_maps.begin();
448 it != _arc_maps.end(); ++it) {
452 for (typename Attributes::iterator it = _attributes.begin();
453 it != _attributes.end(); ++it) {
464 DigraphWriter& operator=(const DigraphWriter&);
468 /// \name Writing rules
471 /// \brief Node map reading rule
473 /// Add a node map reading rule to the writer.
474 template <typename Map>
475 DigraphWriter& nodeMap(const std::string& caption, const Map& map) {
476 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
477 _writer_bits::MapStorageBase<Node>* storage =
478 new _writer_bits::MapStorage<Node, Map>(map);
479 _node_maps.push_back(std::make_pair(caption, storage));
483 /// \brief Node map writing rule
485 /// Add a node map writing rule with specialized converter to the
487 template <typename Map, typename Converter>
488 DigraphWriter& nodeMap(const std::string& caption, const Map& map,
489 const Converter& converter = Converter()) {
490 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
491 _writer_bits::MapStorageBase<Node>* storage =
492 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
493 _node_maps.push_back(std::make_pair(caption, storage));
497 /// \brief Arc map writing rule
499 /// Add an arc map writing rule to the writer.
500 template <typename Map>
501 DigraphWriter& arcMap(const std::string& caption, const Map& map) {
502 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
503 _writer_bits::MapStorageBase<Arc>* storage =
504 new _writer_bits::MapStorage<Arc, Map>(map);
505 _arc_maps.push_back(std::make_pair(caption, storage));
509 /// \brief Arc map writing rule
511 /// Add an arc map writing rule with specialized converter to the
513 template <typename Map, typename Converter>
514 DigraphWriter& arcMap(const std::string& caption, const Map& map,
515 const Converter& converter = Converter()) {
516 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
517 _writer_bits::MapStorageBase<Arc>* storage =
518 new _writer_bits::MapStorage<Arc, Map, Converter>(map, converter);
519 _arc_maps.push_back(std::make_pair(caption, storage));
523 /// \brief Attribute writing rule
525 /// Add an attribute writing rule to the writer.
526 template <typename Value>
527 DigraphWriter& attribute(const std::string& caption, const Value& value) {
528 _writer_bits::ValueStorageBase* storage =
529 new _writer_bits::ValueStorage<Value>(value);
530 _attributes.push_back(std::make_pair(caption, storage));
534 /// \brief Attribute writing rule
536 /// Add an attribute writing rule with specialized converter to the
538 template <typename Value, typename Converter>
539 DigraphWriter& attribute(const std::string& caption, const Value& value,
540 const Converter& converter = Converter()) {
541 _writer_bits::ValueStorageBase* storage =
542 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
543 _attributes.push_back(std::make_pair(caption, storage));
547 /// \brief Node writing rule
549 /// Add a node writing rule to the writer.
550 DigraphWriter& node(const std::string& caption, const Node& node) {
551 typedef _writer_bits::MapLookUpConverter<Node> Converter;
552 Converter converter(_node_index);
553 _writer_bits::ValueStorageBase* storage =
554 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
555 _attributes.push_back(std::make_pair(caption, storage));
559 /// \brief Arc writing rule
561 /// Add an arc writing rule to writer.
562 DigraphWriter& arc(const std::string& caption, const Arc& arc) {
563 typedef _writer_bits::MapLookUpConverter<Arc> Converter;
564 Converter converter(_arc_index);
565 _writer_bits::ValueStorageBase* storage =
566 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
567 _attributes.push_back(std::make_pair(caption, storage));
571 /// \name Select section by name
574 /// \brief Set \c \@nodes section to be read
576 /// Set \c \@nodes section to be read
577 DigraphWriter& nodes(const std::string& caption) {
578 _nodes_caption = caption;
582 /// \brief Set \c \@arcs section to be read
584 /// Set \c \@arcs section to be read
585 DigraphWriter& arcs(const std::string& caption) {
586 _arcs_caption = caption;
590 /// \brief Set \c \@attributes section to be read
592 /// Set \c \@attributes section to be read
593 DigraphWriter& attributes(const std::string& caption) {
594 _attributes_caption = caption;
598 /// \name Skipping section
601 /// \brief Skip writing the node set
603 /// The \c \@nodes section will be not written to the stream.
604 DigraphWriter& skipNodes() {
605 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
610 /// \brief Skip writing arc set
612 /// The \c \@arcs section will be not written to the stream.
613 DigraphWriter& skipArcs() {
614 LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
624 _writer_bits::MapStorageBase<Node>* label = 0;
625 for (typename NodeMaps::iterator it = _node_maps.begin();
626 it != _node_maps.end(); ++it) {
627 if (it->first == "label") {
634 if (!_nodes_caption.empty()) {
635 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
640 *_os << "label" << '\t';
642 for (typename NodeMaps::iterator it = _node_maps.begin();
643 it != _node_maps.end(); ++it) {
644 _writer_bits::writeToken(*_os, it->first) << '\t';
648 std::vector<Node> nodes;
649 for (NodeIt n(_digraph); n != INVALID; ++n) {
654 IdMap<Digraph, Node> id_map(_digraph);
655 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
656 std::sort(nodes.begin(), nodes.end(), id_less);
661 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
664 std::ostringstream os;
665 os << _digraph.id(n);
666 _writer_bits::writeToken(*_os, os.str());
668 _node_index.insert(std::make_pair(n, os.str()));
670 for (typename NodeMaps::iterator it = _node_maps.begin();
671 it != _node_maps.end(); ++it) {
672 std::string value = it->second->get(n);
673 _writer_bits::writeToken(*_os, value);
674 if (it->first == "label") {
675 _node_index.insert(std::make_pair(n, value));
683 void createNodeIndex() {
684 _writer_bits::MapStorageBase<Node>* label = 0;
685 for (typename NodeMaps::iterator it = _node_maps.begin();
686 it != _node_maps.end(); ++it) {
687 if (it->first == "label") {
694 for (NodeIt n(_digraph); n != INVALID; ++n) {
695 std::ostringstream os;
696 os << _digraph.id(n);
697 _node_index.insert(std::make_pair(n, os.str()));
700 for (NodeIt n(_digraph); n != INVALID; ++n) {
701 std::string value = label->get(n);
702 _node_index.insert(std::make_pair(n, value));
708 _writer_bits::MapStorageBase<Arc>* label = 0;
709 for (typename ArcMaps::iterator it = _arc_maps.begin();
710 it != _arc_maps.end(); ++it) {
711 if (it->first == "label") {
718 if (!_arcs_caption.empty()) {
719 _writer_bits::writeToken(*_os << ' ', _arcs_caption);
723 *_os << '\t' << '\t';
725 *_os << "label" << '\t';
727 for (typename ArcMaps::iterator it = _arc_maps.begin();
728 it != _arc_maps.end(); ++it) {
729 _writer_bits::writeToken(*_os, it->first) << '\t';
733 std::vector<Arc> arcs;
734 for (ArcIt n(_digraph); n != INVALID; ++n) {
739 IdMap<Digraph, Arc> id_map(_digraph);
740 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
741 std::sort(arcs.begin(), arcs.end(), id_less);
746 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
748 _writer_bits::writeToken(*_os, _node_index.
749 find(_digraph.source(a))->second);
751 _writer_bits::writeToken(*_os, _node_index.
752 find(_digraph.target(a))->second);
755 std::ostringstream os;
756 os << _digraph.id(a);
757 _writer_bits::writeToken(*_os, os.str());
759 _arc_index.insert(std::make_pair(a, os.str()));
761 for (typename ArcMaps::iterator it = _arc_maps.begin();
762 it != _arc_maps.end(); ++it) {
763 std::string value = it->second->get(a);
764 _writer_bits::writeToken(*_os, value);
765 if (it->first == "label") {
766 _arc_index.insert(std::make_pair(a, value));
774 void createArcIndex() {
775 _writer_bits::MapStorageBase<Arc>* label = 0;
776 for (typename ArcMaps::iterator it = _arc_maps.begin();
777 it != _arc_maps.end(); ++it) {
778 if (it->first == "label") {
785 for (ArcIt a(_digraph); a != INVALID; ++a) {
786 std::ostringstream os;
787 os << _digraph.id(a);
788 _arc_index.insert(std::make_pair(a, os.str()));
791 for (ArcIt a(_digraph); a != INVALID; ++a) {
792 std::string value = label->get(a);
793 _arc_index.insert(std::make_pair(a, value));
798 void writeAttributes() {
799 if (_attributes.empty()) return;
800 *_os << "@attributes";
801 if (!_attributes_caption.empty()) {
802 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
805 for (typename Attributes::iterator it = _attributes.begin();
806 it != _attributes.end(); ++it) {
807 _writer_bits::writeToken(*_os, it->first) << ' ';
808 _writer_bits::writeToken(*_os, it->second->get());
815 /// \name Execution of the writer
818 /// \brief Start the batch processing
820 /// This function starts the batch processing
835 /// \brief Gives back the stream of the writer
837 /// Gives back the stream of the writer
838 std::ostream& ostream() {
845 /// \relates DigraphWriter
846 template <typename Digraph>
847 DigraphWriter<Digraph> digraphWriter(std::ostream& os, Digraph& digraph) {
848 DigraphWriter<Digraph> tmp(os, digraph);
852 /// \relates DigraphWriter
853 template <typename Digraph>
854 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
856 DigraphWriter<Digraph> tmp(fn, digraph);
860 /// \relates DigraphWriter
861 template <typename Digraph>
862 DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
863 DigraphWriter<Digraph> tmp(fn, digraph);
867 /// \ingroup lemon_io
869 /// \brief LGF writer for directed graphs
871 /// This utility writes an \ref lgf-format "LGF" file.
872 template <typename _Graph>
876 typedef _Graph Graph;
877 TEMPLATE_GRAPH_TYPEDEFS(Graph);
887 std::string _nodes_caption;
888 std::string _edges_caption;
889 std::string _attributes_caption;
891 typedef std::map<Node, std::string> NodeIndex;
892 NodeIndex _node_index;
893 typedef std::map<Edge, std::string> EdgeIndex;
894 EdgeIndex _edge_index;
896 typedef std::vector<std::pair<std::string,
897 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
900 typedef std::vector<std::pair<std::string,
901 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
904 typedef std::vector<std::pair<std::string,
905 _writer_bits::ValueStorageBase*> > Attributes;
906 Attributes _attributes;
913 /// \brief Constructor
915 /// Construct a directed graph writer, which writes to the given
917 GraphWriter(std::ostream& is, Graph& graph)
918 : _os(&is), local_os(false), _graph(graph),
919 _skip_nodes(false), _skip_edges(false) {}
921 /// \brief Constructor
923 /// Construct a directed graph writer, which writes to the given
925 GraphWriter(const std::string& fn, Graph& graph)
926 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
927 _skip_nodes(false), _skip_edges(false) {}
929 /// \brief Constructor
931 /// Construct a directed graph writer, which writes to the given
933 GraphWriter(const char* fn, Graph& graph)
934 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
935 _skip_nodes(false), _skip_edges(false) {}
937 /// \brief Copy constructor
939 /// The copy constructor transfers all data from the other writer,
940 /// therefore the copied writer will not be usable more.
941 GraphWriter(GraphWriter& other)
942 : _os(other._os), local_os(other.local_os), _graph(other._graph),
943 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
946 other.local_os = false;
948 _node_index.swap(other._node_index);
949 _edge_index.swap(other._edge_index);
951 _node_maps.swap(other._node_maps);
952 _edge_maps.swap(other._edge_maps);
953 _attributes.swap(other._attributes);
955 _nodes_caption = other._nodes_caption;
956 _edges_caption = other._edges_caption;
957 _attributes_caption = other._attributes_caption;
960 /// \brief Destructor
962 for (typename NodeMaps::iterator it = _node_maps.begin();
963 it != _node_maps.end(); ++it) {
967 for (typename EdgeMaps::iterator it = _edge_maps.begin();
968 it != _edge_maps.end(); ++it) {
972 for (typename Attributes::iterator it = _attributes.begin();
973 it != _attributes.end(); ++it) {
984 GraphWriter& operator=(const GraphWriter&);
988 /// \name Writing rules
991 /// \brief Node map reading rule
993 /// Add a node map reading rule to the writer.
994 template <typename Map>
995 GraphWriter& nodeMap(const std::string& caption, const Map& map) {
996 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
997 _writer_bits::MapStorageBase<Node>* storage =
998 new _writer_bits::MapStorage<Node, Map>(map);
999 _node_maps.push_back(std::make_pair(caption, storage));
1003 /// \brief Node map writing rule
1005 /// Add a node map writing rule with specialized converter to the
1007 template <typename Map, typename Converter>
1008 GraphWriter& nodeMap(const std::string& caption, const Map& map,
1009 const Converter& converter = Converter()) {
1010 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
1011 _writer_bits::MapStorageBase<Node>* storage =
1012 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
1013 _node_maps.push_back(std::make_pair(caption, storage));
1017 /// \brief Edge map writing rule
1019 /// Add an edge map writing rule to the writer.
1020 template <typename Map>
1021 GraphWriter& edgeMap(const std::string& caption, const Map& map) {
1022 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1023 _writer_bits::MapStorageBase<Edge>* storage =
1024 new _writer_bits::MapStorage<Edge, Map>(map);
1025 _edge_maps.push_back(std::make_pair(caption, storage));
1029 /// \brief Edge map writing rule
1031 /// Add an edge map writing rule with specialized converter to the
1033 template <typename Map, typename Converter>
1034 GraphWriter& edgeMap(const std::string& caption, const Map& map,
1035 const Converter& converter = Converter()) {
1036 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
1037 _writer_bits::MapStorageBase<Edge>* storage =
1038 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
1039 _edge_maps.push_back(std::make_pair(caption, storage));
1043 /// \brief Arc map writing rule
1045 /// Add an arc map writing rule to the writer.
1046 template <typename Map>
1047 GraphWriter& arcMap(const std::string& caption, const Map& map) {
1048 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1049 _writer_bits::MapStorageBase<Edge>* forward_storage =
1050 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
1051 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1052 _writer_bits::MapStorageBase<Edge>* backward_storage =
1053 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1054 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1058 /// \brief Arc map writing rule
1060 /// Add an arc map writing rule with specialized converter to the
1062 template <typename Map, typename Converter>
1063 GraphWriter& arcMap(const std::string& caption, const Map& map,
1064 const Converter& converter = Converter()) {
1065 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1066 _writer_bits::MapStorageBase<Edge>* forward_storage =
1067 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1068 (_graph, map, converter);
1069 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1070 _writer_bits::MapStorageBase<Edge>* backward_storage =
1071 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1072 (_graph, map, converter);
1073 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1077 /// \brief Attribute writing rule
1079 /// Add an attribute writing rule to the writer.
1080 template <typename Value>
1081 GraphWriter& attribute(const std::string& caption, const Value& value) {
1082 _writer_bits::ValueStorageBase* storage =
1083 new _writer_bits::ValueStorage<Value>(value);
1084 _attributes.push_back(std::make_pair(caption, storage));
1088 /// \brief Attribute writing rule
1090 /// Add an attribute writing rule with specialized converter to the
1092 template <typename Value, typename Converter>
1093 GraphWriter& attribute(const std::string& caption, const Value& value,
1094 const Converter& converter = Converter()) {
1095 _writer_bits::ValueStorageBase* storage =
1096 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1097 _attributes.push_back(std::make_pair(caption, storage));
1101 /// \brief Node writing rule
1103 /// Add a node writing rule to the writer.
1104 GraphWriter& node(const std::string& caption, const Node& node) {
1105 typedef _writer_bits::MapLookUpConverter<Node> Converter;
1106 Converter converter(_node_index);
1107 _writer_bits::ValueStorageBase* storage =
1108 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1109 _attributes.push_back(std::make_pair(caption, storage));
1113 /// \brief Edge writing rule
1115 /// Add an edge writing rule to writer.
1116 GraphWriter& edge(const std::string& caption, const Edge& edge) {
1117 typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1118 Converter converter(_edge_index);
1119 _writer_bits::ValueStorageBase* storage =
1120 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1121 _attributes.push_back(std::make_pair(caption, storage));
1125 /// \brief Arc writing rule
1127 /// Add an arc writing rule to writer.
1128 GraphWriter& arc(const std::string& caption, const Arc& arc) {
1129 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1130 Converter converter(_graph, _edge_index);
1131 _writer_bits::ValueStorageBase* storage =
1132 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1133 _attributes.push_back(std::make_pair(caption, storage));
1137 /// \name Select section by name
1140 /// \brief Set \c \@nodes section to be read
1142 /// Set \c \@nodes section to be read
1143 GraphWriter& nodes(const std::string& caption) {
1144 _nodes_caption = caption;
1148 /// \brief Set \c \@edges section to be read
1150 /// Set \c \@edges section to be read
1151 GraphWriter& edges(const std::string& caption) {
1152 _edges_caption = caption;
1156 /// \brief Set \c \@attributes section to be read
1158 /// Set \c \@attributes section to be read
1159 GraphWriter& attributes(const std::string& caption) {
1160 _attributes_caption = caption;
1164 /// \name Skipping section
1167 /// \brief Skip writing the node set
1169 /// The \c \@nodes section will be not written to the stream.
1170 GraphWriter& skipNodes() {
1171 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1176 /// \brief Skip writing edge set
1178 /// The \c \@edges section will be not written to the stream.
1179 GraphWriter& skipEdges() {
1180 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1190 _writer_bits::MapStorageBase<Node>* label = 0;
1191 for (typename NodeMaps::iterator it = _node_maps.begin();
1192 it != _node_maps.end(); ++it) {
1193 if (it->first == "label") {
1200 if (!_nodes_caption.empty()) {
1201 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1206 *_os << "label" << '\t';
1208 for (typename NodeMaps::iterator it = _node_maps.begin();
1209 it != _node_maps.end(); ++it) {
1210 _writer_bits::writeToken(*_os, it->first) << '\t';
1214 std::vector<Node> nodes;
1215 for (NodeIt n(_graph); n != INVALID; ++n) {
1220 IdMap<Graph, Node> id_map(_graph);
1221 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1222 std::sort(nodes.begin(), nodes.end(), id_less);
1227 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1230 std::ostringstream os;
1232 _writer_bits::writeToken(*_os, os.str());
1234 _node_index.insert(std::make_pair(n, os.str()));
1236 for (typename NodeMaps::iterator it = _node_maps.begin();
1237 it != _node_maps.end(); ++it) {
1238 std::string value = it->second->get(n);
1239 _writer_bits::writeToken(*_os, value);
1240 if (it->first == "label") {
1241 _node_index.insert(std::make_pair(n, value));
1249 void createNodeIndex() {
1250 _writer_bits::MapStorageBase<Node>* label = 0;
1251 for (typename NodeMaps::iterator it = _node_maps.begin();
1252 it != _node_maps.end(); ++it) {
1253 if (it->first == "label") {
1260 for (NodeIt n(_graph); n != INVALID; ++n) {
1261 std::ostringstream os;
1263 _node_index.insert(std::make_pair(n, os.str()));
1266 for (NodeIt n(_graph); n != INVALID; ++n) {
1267 std::string value = label->get(n);
1268 _node_index.insert(std::make_pair(n, value));
1274 _writer_bits::MapStorageBase<Edge>* label = 0;
1275 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1276 it != _edge_maps.end(); ++it) {
1277 if (it->first == "label") {
1284 if (!_edges_caption.empty()) {
1285 _writer_bits::writeToken(*_os << ' ', _edges_caption);
1289 *_os << '\t' << '\t';
1291 *_os << "label" << '\t';
1293 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1294 it != _edge_maps.end(); ++it) {
1295 _writer_bits::writeToken(*_os, it->first) << '\t';
1299 std::vector<Edge> edges;
1300 for (EdgeIt n(_graph); n != INVALID; ++n) {
1305 IdMap<Graph, Edge> id_map(_graph);
1306 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1307 std::sort(edges.begin(), edges.end(), id_less);
1312 for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1314 _writer_bits::writeToken(*_os, _node_index.
1315 find(_graph.u(e))->second);
1317 _writer_bits::writeToken(*_os, _node_index.
1318 find(_graph.v(e))->second);
1321 std::ostringstream os;
1323 _writer_bits::writeToken(*_os, os.str());
1325 _edge_index.insert(std::make_pair(e, os.str()));
1327 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1328 it != _edge_maps.end(); ++it) {
1329 std::string value = it->second->get(e);
1330 _writer_bits::writeToken(*_os, value);
1331 if (it->first == "label") {
1332 _edge_index.insert(std::make_pair(e, value));
1340 void createEdgeIndex() {
1341 _writer_bits::MapStorageBase<Edge>* label = 0;
1342 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1343 it != _edge_maps.end(); ++it) {
1344 if (it->first == "label") {
1351 for (EdgeIt e(_graph); e != INVALID; ++e) {
1352 std::ostringstream os;
1354 _edge_index.insert(std::make_pair(e, os.str()));
1357 for (EdgeIt e(_graph); e != INVALID; ++e) {
1358 std::string value = label->get(e);
1359 _edge_index.insert(std::make_pair(e, value));
1364 void writeAttributes() {
1365 if (_attributes.empty()) return;
1366 *_os << "@attributes";
1367 if (!_attributes_caption.empty()) {
1368 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1371 for (typename Attributes::iterator it = _attributes.begin();
1372 it != _attributes.end(); ++it) {
1373 _writer_bits::writeToken(*_os, it->first) << ' ';
1374 _writer_bits::writeToken(*_os, it->second->get());
1381 /// \name Execution of the writer
1384 /// \brief Start the batch processing
1386 /// This function starts the batch processing
1401 /// \brief Gives back the stream of the writer
1403 /// Gives back the stream of the writer
1404 std::ostream& ostream() {
1411 /// \relates GraphWriter
1412 template <typename Graph>
1413 GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) {
1414 GraphWriter<Graph> tmp(os, graph);
1418 /// \relates GraphWriter
1419 template <typename Graph>
1420 GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) {
1421 GraphWriter<Graph> tmp(fn, graph);
1425 /// \relates GraphWriter
1426 template <typename Graph>
1427 GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) {
1428 GraphWriter<Graph> tmp(fn, graph);