Fix a bug noticed by deba.
2 * src/lemon/graph_writer.h - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Combinatorial Optimization Research Group, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
19 ///\brief Graph writer.
30 #include <lemon/map_utils.h>
31 #include <lemon/invalid.h>
32 #include <lemon/error.h>
37 /// \brief Standard WriterTraits for the GraphWriter class.
39 /// Standard WriterTraits for the GraphWriter class.
40 /// It defines standard writing method for all type of value.
41 struct DefaultWriterTraits {
43 /// \brief Template class for writing an value.
45 /// Template class for writing an value.
46 template <typename _Value>
51 /// \brief Writes a value to the given stream.
53 /// Writes a value to the given stream.
54 void write(std::ostream& os, const Value& value) {
62 /// \brief Writer class for quoted strings.
64 /// Writer class for quoted strings. It can process the escape
65 /// sequences in the string.
66 class QuotedStringWriter {
68 typedef std::string Value;
70 /// \brief Constructor for the writer.
72 /// Constructor for the writer. If the given parameter is true
73 /// the writer creates escape sequences from special characters.
74 QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
76 /// \brief Writes a quoted string to the given stream.
78 /// Writes a quoted string to the given stream.
79 void write(std::ostream& os, const std::string& value) {
83 for (int i = 0; i < (int)value.size(); ++i) {
84 writeEscape(ls, value[i]);
95 static void writeEscape(std::ostream& os, char c) {
132 os << '\\' << oct << (int)c;
144 /// \brief The graph writer class.
146 /// The writer class for the graph output.
147 /// \see \ref GraphReader
148 /// \see \ref graph-io-page
149 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
153 typedef _Graph Graph;
154 typedef typename Graph::Node Node;
155 typedef typename Graph::NodeIt NodeIt;
156 typedef typename Graph::Edge Edge;
157 typedef typename Graph::EdgeIt EdgeIt;
159 typedef _WriterTraits WriterTraits;
161 /// \brief Construct a new GraphWriter.
163 /// Construct a new GraphWriter. It writes from the given map,
164 /// it constructs the given map and it use the given writer as the
166 GraphWriter(std::ostream& _os, const Graph& _graph)
167 : os(_os), graph(_graph) {}
170 /// \brief Destruct the graph writer.
172 /// Destruct the graph writer.
174 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
175 it != node_map_writers.end(); ++it) {
179 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
180 it != edge_map_writers.end(); ++it) {
188 /// \brief Add a new node map writer command for the writer.
190 /// Add a new node map writer command for the writer.
191 template <typename Map>
192 GraphWriter& addNodeMap(std::string name, const Map& map) {
193 return addNodeMap<typename WriterTraits::template Writer<
194 typename Map::Value>, Map>(name, map);
197 /// \brief Add a new node map writer command for the writer.
199 /// Add a new node map writer command for the writer.
200 template <typename Writer, typename Map>
201 GraphWriter& addNodeMap(std::string name, const Map& map,
202 const Writer& writer = Writer()) {
203 node_map_writers.push_back(
204 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
210 /// \brief Add a new edge map writer command for the writer.
212 /// Add a new edge map writer command for the writer.
213 template <typename Map>
214 GraphWriter& addEdgeMap(std::string name, const Map& map) {
215 return addEdgeMap<typename WriterTraits::template Writer<
216 typename Map::Value>, Map>(name, map);
220 /// \brief Add a new edge map writer command for the writer.
222 /// Add a new edge map writer command for the writer.
223 template <typename Writer, typename Map>
224 GraphWriter& addEdgeMap(std::string name,
225 const Map& map, const Writer& writer = Writer()) {
226 edge_map_writers.push_back(make_pair(name,
227 new MapWriter<Edge, Map, Writer>(map, writer)));
231 /// \brief Add a new labeled node writer for the writer.
233 /// Add a new labeled node writer for the writer.
234 GraphWriter& addNode(std::string name, const Node& node) {
235 node_writers.push_back(make_pair(name, node));
239 /// \brief Add a new labeled edge writer for the writer.
241 /// Add a new labeled edge writer for the writer.
242 GraphWriter& addEdge(std::string name, const Edge& edge) {
243 edge_writers.push_back(make_pair(name, edge));
247 /// \brief Executes the writer commands.
249 /// Executes the writer commands.
255 os << "@end" << std::endl;
260 void writeNodeSet() {
261 if (node_map_writers.size() == 0) return;
262 os << "@nodeset" << std::endl;
263 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
264 os << node_map_writers[i].first << '\t';
267 for (NodeIt it(graph); it != INVALID; ++it) {
268 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
269 node_map_writers[i].second->write(os, it);
276 void writeEdgeSet() {
277 if (edge_map_writers.size() == 0) return;
278 if (node_map_writers.size() == 0) {
279 // ErrorMessage message;
280 // message << "Missing node id map";
281 // throw IOLogicError(message);
283 os << "@edgeset" << std::endl;
285 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
286 os << edge_map_writers[i].first << '\t';
289 for (EdgeIt it(graph); it != INVALID; ++it) {
290 node_map_writers[0].second->write(os, graph.source(it));
291 node_map_writers[0].second->write(os, graph.target(it));
292 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
293 edge_map_writers[i].second->write(os, it);
300 if (node_writers.size() == 0) return;
301 if (node_map_writers.size() == 0) {
302 // throw Exception() << "Missing node id map";
304 os << "@nodes" << std::endl;
305 for (int i = 0; i < (int)node_writers.size(); ++i) {
306 os << node_writers[i].first << '\t';
307 node_map_writers[0].second->write(os, node_writers[i].second);
313 if (edge_writers.size() == 0) return;
314 if (edge_map_writers.size() == 0) {
315 // throw Exception() << "Missing edge id map";
317 os << "@edges" << std::endl;
318 for (int i = 0; i < (int)edge_writers.size(); ++i) {
319 os << edge_writers[i].first << '\t';
320 edge_map_writers[0].second->write(os, edge_writers[i].second);
327 template <class _Item>
331 virtual void write(std::ostream&, const Item&) = 0;
334 template <class _Item, typename _Map, typename _Writer>
335 class MapWriter : public WriterBase<_Item> {
338 typedef _Writer Writer;
339 typedef typename Writer::Value Value;
345 MapWriter(const Map& _map, const Writer& _writer)
346 : map(_map), writer(_writer) {}
349 virtual void write(std::ostream& os, const Item& item) {
350 writer.write(os, map[item]);
357 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
359 NodeMapWriters node_map_writers;
361 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
363 EdgeMapWriters edge_map_writers;
365 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
366 NodeWriters node_writers;
368 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
369 EdgeWriters edge_writers;
376 /// Ready to use writer function.
377 template<typename Graph, typename CapacityMap, typename CostMap>
378 void writeGraph(std::ostream& os, const Graph &g,
379 const CapacityMap& capacity, const typename Graph::Node &s,
380 const typename Graph::Node &t, const CostMap& cost) {
381 GraphWriter<Graph> reader(os, g);
382 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
383 reader.addNodeMap("id", nodeIdMap);
384 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
385 reader.addEdgeMap("id", edgeIdMap);
386 reader.addEdgeMap("capacity", capacity);
387 reader.addEdgeMap("cost", cost);
388 reader.addNode("source", s);
389 reader.addNode("target", t);
393 /// Ready to use writer function.
394 template<typename Graph, typename CapacityMap, typename CostMap>
395 void writeGraph(std::ostream& os, const Graph &g,
396 const CapacityMap& capacity, const typename Graph::Node &s,
397 const typename Graph::Node &t) {
398 GraphWriter<Graph> reader(os, g);
399 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
400 reader.addNodeMap("id", nodeIdMap);
401 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
402 reader.addEdgeMap("id", edgeIdMap);
403 reader.addEdgeMap("capacity", capacity);
404 reader.addNode("source", s);
405 reader.addNode("target", t);
409 /// Ready to use writer function.
410 template<typename Graph, typename CapacityMap>
411 void writeGraph(std::ostream& os, const Graph &g,
412 const CapacityMap& capacity, const typename Graph::Node &s) {
413 GraphWriter<Graph> reader(os, g);
414 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
415 reader.addNodeMap("id", nodeIdMap);
416 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
417 reader.addEdgeMap("id", edgeIdMap);
418 reader.addEdgeMap("capacity", capacity);
419 reader.addNode("source", s);
422 /// Ready to use writer function.
423 template<typename Graph, typename CapacityMap>
424 void writeGraph(std::ostream& os, const Graph &g,
425 const CapacityMap& capacity) {
426 GraphWriter<Graph> reader(os, g);
427 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
428 reader.addNodeMap("id", nodeIdMap);
429 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
430 reader.addEdgeMap("id", edgeIdMap);
431 reader.addEdgeMap("capacity", capacity);
434 /// Ready to use writer function.
435 template<typename Graph>
436 void writeGraph(std::ostream& os, const Graph &g) {
437 GraphWriter<Graph> reader(os, g);
438 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
439 reader.addNodeMap("id", nodeIdMap);
440 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
441 reader.addEdgeMap("id", edgeIdMap);