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.
21 #ifndef LEMON_GRAPH_WRITER_H
22 #define LEMON_GRAPH_WRITER_H
32 #include <lemon/map_utils.h>
34 #include <lemon/invalid.h>
35 #include <lemon/error.h>
40 /// \brief Standard WriterTraits for the GraphWriter class.
42 /// Standard WriterTraits for the GraphWriter class.
43 /// It defines standard writing method for all type of value.
44 struct DefaultWriterTraits {
46 /// \brief Template class for writing an value.
48 /// Template class for writing an value.
49 template <typename _Value>
54 /// \brief Writes a value to the given stream.
56 /// Writes a value to the given stream.
57 void write(std::ostream& os, const Value& value) {
65 /// \brief Writer class for quoted strings.
67 /// Writer class for quoted strings. It can process the escape
68 /// sequences in the string.
69 class QuotedStringWriter {
71 typedef std::string Value;
73 /// \brief Constructor for the writer.
75 /// Constructor for the writer. If the given parameter is true
76 /// the writer creates escape sequences from special characters.
77 QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
79 /// \brief Writes a quoted string to the given stream.
81 /// Writes a quoted string to the given stream.
82 void write(std::ostream& os, const std::string& value) {
86 for (int i = 0; i < (int)value.size(); ++i) {
87 writeEscape(ls, value[i]);
98 static void writeEscape(std::ostream& os, char c) {
135 os << '\\' << oct << (int)c;
147 /// \brief The graph writer class.
149 /// The writer class for the graph output.
150 /// \see \ref GraphReader
151 /// \see \ref graph-io-page
152 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
156 typedef _Graph Graph;
157 typedef typename Graph::Node Node;
158 typedef typename Graph::NodeIt NodeIt;
159 typedef typename Graph::Edge Edge;
160 typedef typename Graph::EdgeIt EdgeIt;
162 typedef _WriterTraits WriterTraits;
164 /// \brief Construct a new GraphWriter.
166 /// Construct a new GraphWriter. It writes from the given map,
167 /// it constructs the given map and it use the given writer as the
169 GraphWriter(std::ostream& _os, const Graph& _graph)
170 : os(_os), graph(_graph) {}
173 /// \brief Destruct the graph writer.
175 /// Destruct the graph writer.
177 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
178 it != node_map_writers.end(); ++it) {
182 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
183 it != edge_map_writers.end(); ++it) {
191 /// \brief Add a new node map writer command for the writer.
193 /// Add a new node map writer command for the writer.
194 template <typename Map>
195 GraphWriter& addNodeMap(std::string name, const Map& map) {
196 return addNodeMap<typename WriterTraits::template Writer<
197 typename Map::Value>, Map>(name, map);
200 /// \brief Add a new node map writer command for the writer.
202 /// Add a new node map writer command for the writer.
203 template <typename Writer, typename Map>
204 GraphWriter& addNodeMap(std::string name, const Map& map,
205 const Writer& writer = Writer()) {
206 node_map_writers.push_back(
207 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
213 /// \brief Add a new edge map writer command for the writer.
215 /// Add a new edge map writer command for the writer.
216 template <typename Map>
217 GraphWriter& addEdgeMap(std::string name, const Map& map) {
218 return addEdgeMap<typename WriterTraits::template Writer<
219 typename Map::Value>, Map>(name, map);
223 /// \brief Add a new edge map writer command for the writer.
225 /// Add a new edge map writer command for the writer.
226 template <typename Writer, typename Map>
227 GraphWriter& addEdgeMap(std::string name,
228 const Map& map, const Writer& writer = Writer()) {
229 edge_map_writers.push_back(make_pair(name,
230 new MapWriter<Edge, Map, Writer>(map, writer)));
234 /// \brief Add a new labeled node writer for the writer.
236 /// Add a new labeled node writer for the writer.
237 GraphWriter& addNode(std::string name, const Node& node) {
238 node_writers.push_back(make_pair(name, node));
242 /// \brief Add a new labeled edge writer for the writer.
244 /// Add a new labeled edge writer for the writer.
245 GraphWriter& addEdge(std::string name, const Edge& edge) {
246 edge_writers.push_back(make_pair(name, edge));
250 /// \brief Executes the writer commands.
252 /// Executes the writer commands.
258 os << "@end" << std::endl;
263 void writeNodeSet() {
264 if (node_map_writers.size() == 0) return;
265 os << "@nodeset" << std::endl;
266 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
267 os << node_map_writers[i].first << '\t';
270 for (NodeIt it(graph); it != INVALID; ++it) {
271 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
272 node_map_writers[i].second->write(os, it);
279 void writeEdgeSet() {
280 if (edge_map_writers.size() == 0) return;
281 if (node_map_writers.size() == 0) {
282 // ErrorMessage message;
283 // message << "Missing node id map";
284 // throw IOLogicError(message);
286 os << "@edgeset" << std::endl;
288 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
289 os << edge_map_writers[i].first << '\t';
292 for (EdgeIt it(graph); it != INVALID; ++it) {
293 node_map_writers[0].second->write(os, graph.source(it));
294 node_map_writers[0].second->write(os, graph.target(it));
295 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
296 edge_map_writers[i].second->write(os, it);
303 if (node_writers.size() == 0) return;
304 if (node_map_writers.size() == 0) {
305 // throw Exception() << "Missing node id map";
307 os << "@nodes" << std::endl;
308 for (int i = 0; i < (int)node_writers.size(); ++i) {
309 os << node_writers[i].first << '\t';
310 node_map_writers[0].second->write(os, node_writers[i].second);
316 if (edge_writers.size() == 0) return;
317 if (edge_map_writers.size() == 0) {
318 // throw Exception() << "Missing edge id map";
320 os << "@edges" << std::endl;
321 for (int i = 0; i < (int)edge_writers.size(); ++i) {
322 os << edge_writers[i].first << '\t';
323 edge_map_writers[0].second->write(os, edge_writers[i].second);
330 template <class _Item>
334 virtual void write(std::ostream&, const Item&) = 0;
337 template <class _Item, typename _Map, typename _Writer>
338 class MapWriter : public WriterBase<_Item> {
341 typedef _Writer Writer;
342 typedef typename Writer::Value Value;
348 MapWriter(const Map& _map, const Writer& _writer)
349 : map(_map), writer(_writer) {}
352 virtual void write(std::ostream& os, const Item& item) {
353 writer.write(os, map[item]);
360 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
362 NodeMapWriters node_map_writers;
364 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
366 EdgeMapWriters edge_map_writers;
368 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
369 NodeWriters node_writers;
371 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
372 EdgeWriters edge_writers;
379 /// Ready to use writer function.
380 template<typename Graph, typename CapacityMap, typename CostMap>
381 void writeGraph(std::ostream& os, const Graph &g,
382 const CapacityMap& capacity, const typename Graph::Node &s,
383 const typename Graph::Node &t, const CostMap& cost) {
384 GraphWriter<Graph> reader(os, g);
385 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
386 reader.addNodeMap("id", nodeIdMap);
387 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
388 reader.addEdgeMap("id", edgeIdMap);
389 reader.addEdgeMap("capacity", capacity);
390 reader.addEdgeMap("cost", cost);
391 reader.addNode("source", s);
392 reader.addNode("target", t);
396 /// Ready to use writer function.
397 template<typename Graph, typename CapacityMap, typename CostMap>
398 void writeGraph(std::ostream& os, const Graph &g,
399 const CapacityMap& capacity, const typename Graph::Node &s,
400 const typename Graph::Node &t) {
401 GraphWriter<Graph> reader(os, g);
402 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
403 reader.addNodeMap("id", nodeIdMap);
404 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
405 reader.addEdgeMap("id", edgeIdMap);
406 reader.addEdgeMap("capacity", capacity);
407 reader.addNode("source", s);
408 reader.addNode("target", t);
412 /// Ready to use writer function.
413 template<typename Graph, typename CapacityMap>
414 void writeGraph(std::ostream& os, const Graph &g,
415 const CapacityMap& capacity, const typename Graph::Node &s) {
416 GraphWriter<Graph> reader(os, g);
417 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
418 reader.addNodeMap("id", nodeIdMap);
419 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
420 reader.addEdgeMap("id", edgeIdMap);
421 reader.addEdgeMap("capacity", capacity);
422 reader.addNode("source", s);
425 /// Ready to use writer function.
426 template<typename Graph, typename CapacityMap>
427 void writeGraph(std::ostream& os, const Graph &g,
428 const CapacityMap& capacity) {
429 GraphWriter<Graph> reader(os, g);
430 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
431 reader.addNodeMap("id", nodeIdMap);
432 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
433 reader.addEdgeMap("id", edgeIdMap);
434 reader.addEdgeMap("capacity", capacity);
437 /// Ready to use writer function.
438 template<typename Graph>
439 void writeGraph(std::ostream& os, const Graph &g) {
440 GraphWriter<Graph> reader(os, g);
441 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
442 reader.addNodeMap("id", nodeIdMap);
443 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
444 reader.addEdgeMap("id", edgeIdMap);