Reworked versioning.
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");
609 /// \brief Skip writing arc set
611 /// The \c \@arcs section will be not written to the stream.
612 DigraphWriter& skipArcs() {
613 LEMON_ASSERT(!_skip_arcs, "Multiple usage of skipArcs() member");
622 _writer_bits::MapStorageBase<Node>* label = 0;
623 for (typename NodeMaps::iterator it = _node_maps.begin();
624 it != _node_maps.end(); ++it) {
625 if (it->first == "label") {
632 if (!_nodes_caption.empty()) {
633 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
638 *_os << "label" << '\t';
640 for (typename NodeMaps::iterator it = _node_maps.begin();
641 it != _node_maps.end(); ++it) {
642 _writer_bits::writeToken(*_os, it->first) << '\t';
646 std::vector<Node> nodes;
647 for (NodeIt n(_digraph); n != INVALID; ++n) {
652 IdMap<Digraph, Node> id_map(_digraph);
653 _writer_bits::MapLess<IdMap<Digraph, Node> > id_less(id_map);
654 std::sort(nodes.begin(), nodes.end(), id_less);
659 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
662 std::ostringstream os;
663 os << _digraph.id(n);
664 _writer_bits::writeToken(*_os, os.str());
666 _node_index.insert(std::make_pair(n, os.str()));
668 for (typename NodeMaps::iterator it = _node_maps.begin();
669 it != _node_maps.end(); ++it) {
670 std::string value = it->second->get(n);
671 _writer_bits::writeToken(*_os, value);
672 if (it->first == "label") {
673 _node_index.insert(std::make_pair(n, value));
682 _writer_bits::MapStorageBase<Arc>* label = 0;
683 for (typename ArcMaps::iterator it = _arc_maps.begin();
684 it != _arc_maps.end(); ++it) {
685 if (it->first == "label") {
692 if (!_arcs_caption.empty()) {
693 _writer_bits::writeToken(*_os << ' ', _arcs_caption);
697 *_os << '\t' << '\t';
699 *_os << "label" << '\t';
701 for (typename ArcMaps::iterator it = _arc_maps.begin();
702 it != _arc_maps.end(); ++it) {
703 _writer_bits::writeToken(*_os, it->first) << '\t';
707 std::vector<Arc> arcs;
708 for (ArcIt n(_digraph); n != INVALID; ++n) {
713 IdMap<Digraph, Arc> id_map(_digraph);
714 _writer_bits::MapLess<IdMap<Digraph, Arc> > id_less(id_map);
715 std::sort(arcs.begin(), arcs.end(), id_less);
720 for (int i = 0; i < static_cast<int>(arcs.size()); ++i) {
722 _writer_bits::writeToken(*_os, _node_index.
723 find(_digraph.source(a))->second);
725 _writer_bits::writeToken(*_os, _node_index.
726 find(_digraph.target(a))->second);
729 std::ostringstream os;
730 os << _digraph.id(a);
731 _writer_bits::writeToken(*_os, os.str());
733 _arc_index.insert(std::make_pair(a, os.str()));
735 for (typename ArcMaps::iterator it = _arc_maps.begin();
736 it != _arc_maps.end(); ++it) {
737 std::string value = it->second->get(a);
738 _writer_bits::writeToken(*_os, value);
739 if (it->first == "label") {
740 _arc_index.insert(std::make_pair(a, value));
748 void writeAttributes() {
749 if (_attributes.empty()) return;
750 *_os << "@attributes";
751 if (!_attributes_caption.empty()) {
752 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
755 for (typename Attributes::iterator it = _attributes.begin();
756 it != _attributes.end(); ++it) {
757 _writer_bits::writeToken(*_os, it->first) << ' ';
758 _writer_bits::writeToken(*_os, it->second->get());
765 /// \name Execution of the writer
768 /// \brief Start the batch processing
770 /// This function starts the batch processing
781 /// \brief Gives back the stream of the writer
783 /// Gives back the stream of the writer
784 std::ostream& ostream() {
791 /// \relates DigraphWriter
792 template <typename Digraph>
793 DigraphWriter<Digraph> digraphWriter(std::ostream& os, Digraph& digraph) {
794 DigraphWriter<Digraph> tmp(os, digraph);
798 /// \relates DigraphWriter
799 template <typename Digraph>
800 DigraphWriter<Digraph> digraphWriter(const std::string& fn,
802 DigraphWriter<Digraph> tmp(fn, digraph);
806 /// \relates DigraphWriter
807 template <typename Digraph>
808 DigraphWriter<Digraph> digraphWriter(const char* fn, Digraph& digraph) {
809 DigraphWriter<Digraph> tmp(fn, digraph);
813 /// \ingroup lemon_io
815 /// \brief LGF writer for directed graphs
817 /// This utility writes an \ref lgf-format "LGF" file.
818 template <typename _Graph>
822 typedef _Graph Graph;
823 TEMPLATE_GRAPH_TYPEDEFS(Graph);
833 std::string _nodes_caption;
834 std::string _edges_caption;
835 std::string _attributes_caption;
837 typedef std::map<Node, std::string> NodeIndex;
838 NodeIndex _node_index;
839 typedef std::map<Edge, std::string> EdgeIndex;
840 EdgeIndex _edge_index;
842 typedef std::vector<std::pair<std::string,
843 _writer_bits::MapStorageBase<Node>* > > NodeMaps;
846 typedef std::vector<std::pair<std::string,
847 _writer_bits::MapStorageBase<Edge>* > >EdgeMaps;
850 typedef std::vector<std::pair<std::string,
851 _writer_bits::ValueStorageBase*> > Attributes;
852 Attributes _attributes;
859 /// \brief Constructor
861 /// Construct a directed graph writer, which writes to the given
863 GraphWriter(std::ostream& is, Graph& graph)
864 : _os(&is), local_os(false), _graph(graph),
865 _skip_nodes(false), _skip_edges(false) {}
867 /// \brief Constructor
869 /// Construct a directed graph writer, which writes to the given
871 GraphWriter(const std::string& fn, Graph& graph)
872 : _os(new std::ofstream(fn.c_str())), local_os(true), _graph(graph),
873 _skip_nodes(false), _skip_edges(false) {}
875 /// \brief Constructor
877 /// Construct a directed graph writer, which writes to the given
879 GraphWriter(const char* fn, Graph& graph)
880 : _os(new std::ofstream(fn)), local_os(true), _graph(graph),
881 _skip_nodes(false), _skip_edges(false) {}
883 /// \brief Copy constructor
885 /// The copy constructor transfers all data from the other writer,
886 /// therefore the copied writer will not be usable more.
887 GraphWriter(GraphWriter& other)
888 : _os(other._os), local_os(other.local_os), _graph(other._graph),
889 _skip_nodes(other._skip_nodes), _skip_edges(other._skip_edges) {
892 other.local_os = false;
894 _node_index.swap(other._node_index);
895 _edge_index.swap(other._edge_index);
897 _node_maps.swap(other._node_maps);
898 _edge_maps.swap(other._edge_maps);
899 _attributes.swap(other._attributes);
901 _nodes_caption = other._nodes_caption;
902 _edges_caption = other._edges_caption;
903 _attributes_caption = other._attributes_caption;
906 /// \brief Destructor
908 for (typename NodeMaps::iterator it = _node_maps.begin();
909 it != _node_maps.end(); ++it) {
913 for (typename EdgeMaps::iterator it = _edge_maps.begin();
914 it != _edge_maps.end(); ++it) {
918 for (typename Attributes::iterator it = _attributes.begin();
919 it != _attributes.end(); ++it) {
930 GraphWriter& operator=(const GraphWriter&);
934 /// \name Writing rules
937 /// \brief Node map reading rule
939 /// Add a node map reading rule to the writer.
940 template <typename Map>
941 GraphWriter& nodeMap(const std::string& caption, const Map& map) {
942 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
943 _writer_bits::MapStorageBase<Node>* storage =
944 new _writer_bits::MapStorage<Node, Map>(map);
945 _node_maps.push_back(std::make_pair(caption, storage));
949 /// \brief Node map writing rule
951 /// Add a node map writing rule with specialized converter to the
953 template <typename Map, typename Converter>
954 GraphWriter& nodeMap(const std::string& caption, const Map& map,
955 const Converter& converter = Converter()) {
956 checkConcept<concepts::ReadMap<Node, typename Map::Value>, Map>();
957 _writer_bits::MapStorageBase<Node>* storage =
958 new _writer_bits::MapStorage<Node, Map, Converter>(map, converter);
959 _node_maps.push_back(std::make_pair(caption, storage));
963 /// \brief Edge map writing rule
965 /// Add an edge map writing rule to the writer.
966 template <typename Map>
967 GraphWriter& edgeMap(const std::string& caption, const Map& map) {
968 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
969 _writer_bits::MapStorageBase<Edge>* storage =
970 new _writer_bits::MapStorage<Edge, Map>(map);
971 _edge_maps.push_back(std::make_pair(caption, storage));
975 /// \brief Edge map writing rule
977 /// Add an edge map writing rule with specialized converter to the
979 template <typename Map, typename Converter>
980 GraphWriter& edgeMap(const std::string& caption, const Map& map,
981 const Converter& converter = Converter()) {
982 checkConcept<concepts::ReadMap<Edge, typename Map::Value>, Map>();
983 _writer_bits::MapStorageBase<Edge>* storage =
984 new _writer_bits::MapStorage<Edge, Map, Converter>(map, converter);
985 _edge_maps.push_back(std::make_pair(caption, storage));
989 /// \brief Arc map writing rule
991 /// Add an arc map writing rule to the writer.
992 template <typename Map>
993 GraphWriter& arcMap(const std::string& caption, const Map& map) {
994 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
995 _writer_bits::MapStorageBase<Edge>* forward_storage =
996 new _writer_bits::GraphArcMapStorage<Graph, true, Map>(_graph, map);
997 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
998 _writer_bits::MapStorageBase<Edge>* backward_storage =
999 new _writer_bits::GraphArcMapStorage<Graph, false, Map>(_graph, map);
1000 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1004 /// \brief Arc map writing rule
1006 /// Add an arc map writing rule with specialized converter to the
1008 template <typename Map, typename Converter>
1009 GraphWriter& arcMap(const std::string& caption, const Map& map,
1010 const Converter& converter = Converter()) {
1011 checkConcept<concepts::ReadMap<Arc, typename Map::Value>, Map>();
1012 _writer_bits::MapStorageBase<Edge>* forward_storage =
1013 new _writer_bits::GraphArcMapStorage<Graph, true, Map, Converter>
1014 (_graph, map, converter);
1015 _edge_maps.push_back(std::make_pair('+' + caption, forward_storage));
1016 _writer_bits::MapStorageBase<Edge>* backward_storage =
1017 new _writer_bits::GraphArcMapStorage<Graph, false, Map, Converter>
1018 (_graph, map, converter);
1019 _edge_maps.push_back(std::make_pair('-' + caption, backward_storage));
1023 /// \brief Attribute writing rule
1025 /// Add an attribute writing rule to the writer.
1026 template <typename Value>
1027 GraphWriter& attribute(const std::string& caption, const Value& value) {
1028 _writer_bits::ValueStorageBase* storage =
1029 new _writer_bits::ValueStorage<Value>(value);
1030 _attributes.push_back(std::make_pair(caption, storage));
1034 /// \brief Attribute writing rule
1036 /// Add an attribute writing rule with specialized converter to the
1038 template <typename Value, typename Converter>
1039 GraphWriter& attribute(const std::string& caption, const Value& value,
1040 const Converter& converter = Converter()) {
1041 _writer_bits::ValueStorageBase* storage =
1042 new _writer_bits::ValueStorage<Value, Converter>(value, converter);
1043 _attributes.push_back(std::make_pair(caption, storage));
1047 /// \brief Node writing rule
1049 /// Add a node writing rule to the writer.
1050 GraphWriter& node(const std::string& caption, const Node& node) {
1051 typedef _writer_bits::MapLookUpConverter<Node> Converter;
1052 Converter converter(_node_index);
1053 _writer_bits::ValueStorageBase* storage =
1054 new _writer_bits::ValueStorage<Node, Converter>(node, converter);
1055 _attributes.push_back(std::make_pair(caption, storage));
1059 /// \brief Edge writing rule
1061 /// Add an edge writing rule to writer.
1062 GraphWriter& edge(const std::string& caption, const Edge& edge) {
1063 typedef _writer_bits::MapLookUpConverter<Edge> Converter;
1064 Converter converter(_edge_index);
1065 _writer_bits::ValueStorageBase* storage =
1066 new _writer_bits::ValueStorage<Edge, Converter>(edge, converter);
1067 _attributes.push_back(std::make_pair(caption, storage));
1071 /// \brief Arc writing rule
1073 /// Add an arc writing rule to writer.
1074 GraphWriter& arc(const std::string& caption, const Arc& arc) {
1075 typedef _writer_bits::GraphArcLookUpConverter<Graph> Converter;
1076 Converter converter(_graph, _edge_index);
1077 _writer_bits::ValueStorageBase* storage =
1078 new _writer_bits::ValueStorage<Arc, Converter>(arc, converter);
1079 _attributes.push_back(std::make_pair(caption, storage));
1083 /// \name Select section by name
1086 /// \brief Set \c \@nodes section to be read
1088 /// Set \c \@nodes section to be read
1089 GraphWriter& nodes(const std::string& caption) {
1090 _nodes_caption = caption;
1094 /// \brief Set \c \@edges section to be read
1096 /// Set \c \@edges section to be read
1097 GraphWriter& edges(const std::string& caption) {
1098 _edges_caption = caption;
1102 /// \brief Set \c \@attributes section to be read
1104 /// Set \c \@attributes section to be read
1105 GraphWriter& attributes(const std::string& caption) {
1106 _attributes_caption = caption;
1110 /// \name Skipping section
1113 /// \brief Skip writing the node set
1115 /// The \c \@nodes section will be not written to the stream.
1116 GraphWriter& skipNodes() {
1117 LEMON_ASSERT(!_skip_nodes, "Multiple usage of skipNodes() member");
1121 /// \brief Skip writing edge set
1123 /// The \c \@edges section will be not written to the stream.
1124 GraphWriter& skipEdges() {
1125 LEMON_ASSERT(!_skip_edges, "Multiple usage of skipEdges() member");
1134 _writer_bits::MapStorageBase<Node>* label = 0;
1135 for (typename NodeMaps::iterator it = _node_maps.begin();
1136 it != _node_maps.end(); ++it) {
1137 if (it->first == "label") {
1144 if (!_nodes_caption.empty()) {
1145 _writer_bits::writeToken(*_os << ' ', _nodes_caption);
1150 *_os << "label" << '\t';
1152 for (typename NodeMaps::iterator it = _node_maps.begin();
1153 it != _node_maps.end(); ++it) {
1154 _writer_bits::writeToken(*_os, it->first) << '\t';
1158 std::vector<Node> nodes;
1159 for (NodeIt n(_graph); n != INVALID; ++n) {
1164 IdMap<Graph, Node> id_map(_graph);
1165 _writer_bits::MapLess<IdMap<Graph, Node> > id_less(id_map);
1166 std::sort(nodes.begin(), nodes.end(), id_less);
1171 for (int i = 0; i < static_cast<int>(nodes.size()); ++i) {
1174 std::ostringstream os;
1176 _writer_bits::writeToken(*_os, os.str());
1178 _node_index.insert(std::make_pair(n, os.str()));
1180 for (typename NodeMaps::iterator it = _node_maps.begin();
1181 it != _node_maps.end(); ++it) {
1182 std::string value = it->second->get(n);
1183 _writer_bits::writeToken(*_os, value);
1184 if (it->first == "label") {
1185 _node_index.insert(std::make_pair(n, value));
1194 _writer_bits::MapStorageBase<Edge>* label = 0;
1195 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1196 it != _edge_maps.end(); ++it) {
1197 if (it->first == "label") {
1204 if (!_edges_caption.empty()) {
1205 _writer_bits::writeToken(*_os << ' ', _edges_caption);
1209 *_os << '\t' << '\t';
1211 *_os << "label" << '\t';
1213 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1214 it != _edge_maps.end(); ++it) {
1215 _writer_bits::writeToken(*_os, it->first) << '\t';
1219 std::vector<Edge> edges;
1220 for (EdgeIt n(_graph); n != INVALID; ++n) {
1225 IdMap<Graph, Edge> id_map(_graph);
1226 _writer_bits::MapLess<IdMap<Graph, Edge> > id_less(id_map);
1227 std::sort(edges.begin(), edges.end(), id_less);
1232 for (int i = 0; i < static_cast<int>(edges.size()); ++i) {
1234 _writer_bits::writeToken(*_os, _node_index.
1235 find(_graph.u(e))->second);
1237 _writer_bits::writeToken(*_os, _node_index.
1238 find(_graph.v(e))->second);
1241 std::ostringstream os;
1243 _writer_bits::writeToken(*_os, os.str());
1245 _edge_index.insert(std::make_pair(e, os.str()));
1247 for (typename EdgeMaps::iterator it = _edge_maps.begin();
1248 it != _edge_maps.end(); ++it) {
1249 std::string value = it->second->get(e);
1250 _writer_bits::writeToken(*_os, value);
1251 if (it->first == "label") {
1252 _edge_index.insert(std::make_pair(e, value));
1260 void writeAttributes() {
1261 if (_attributes.empty()) return;
1262 *_os << "@attributes";
1263 if (!_attributes_caption.empty()) {
1264 _writer_bits::writeToken(*_os << ' ', _attributes_caption);
1267 for (typename Attributes::iterator it = _attributes.begin();
1268 it != _attributes.end(); ++it) {
1269 _writer_bits::writeToken(*_os, it->first) << ' ';
1270 _writer_bits::writeToken(*_os, it->second->get());
1277 /// \name Execution of the writer
1280 /// \brief Start the batch processing
1282 /// This function starts the batch processing
1293 /// \brief Gives back the stream of the writer
1295 /// Gives back the stream of the writer
1296 std::ostream& ostream() {
1303 /// \relates GraphWriter
1304 template <typename Graph>
1305 GraphWriter<Graph> graphWriter(std::ostream& os, Graph& graph) {
1306 GraphWriter<Graph> tmp(os, graph);
1310 /// \relates GraphWriter
1311 template <typename Graph>
1312 GraphWriter<Graph> graphWriter(const std::string& fn, Graph& graph) {
1313 GraphWriter<Graph> tmp(fn, graph);
1317 /// \relates GraphWriter
1318 template <typename Graph>
1319 GraphWriter<Graph> graphWriter(const char* fn, Graph& graph) {
1320 GraphWriter<Graph> tmp(fn, graph);