Conceptions and bug fixes.
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 Lemon Graph Format 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.
150 /// The writer class for the graph output.
151 /// \see DefaultWriterTraits
152 /// \see QuotedStringWriter
153 /// \see \ref GraphReader
154 /// \see \ref graph-io-page
155 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
159 typedef _Graph Graph;
160 typedef typename Graph::Node Node;
161 typedef typename Graph::NodeIt NodeIt;
162 typedef typename Graph::Edge Edge;
163 typedef typename Graph::EdgeIt EdgeIt;
165 typedef _WriterTraits WriterTraits;
167 /// \brief Construct a new GraphWriter.
169 /// Construct a new GraphWriter. It writes from the given map,
170 /// it constructs the given map and it use the given writer as the
172 GraphWriter(std::ostream& _os, const Graph& _graph)
173 : os(_os), graph(_graph) {}
176 /// \brief Destruct the graph writer.
178 /// Destruct the graph writer.
180 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
181 it != node_map_writers.end(); ++it) {
185 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
186 it != edge_map_writers.end(); ++it) {
194 /// \brief Add a new node map writer command for the writer.
196 /// Add a new node map writer command for the writer.
197 template <typename Map>
198 GraphWriter& addNodeMap(std::string name, const Map& map) {
199 return addNodeMap<typename WriterTraits::template Writer<
200 typename Map::Value>, Map>(name, map);
203 /// \brief Add a new node map writer command for the writer.
205 /// Add a new node map writer command for the writer.
206 template <typename Writer, typename Map>
207 GraphWriter& addNodeMap(std::string name, const Map& map,
208 const Writer& writer = Writer()) {
209 node_map_writers.push_back(
210 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
216 /// \brief Add a new edge map writer command for the writer.
218 /// Add a new edge map writer command for the writer.
219 template <typename Map>
220 GraphWriter& addEdgeMap(std::string name, const Map& map) {
221 return addEdgeMap<typename WriterTraits::template Writer<
222 typename Map::Value>, Map>(name, map);
226 /// \brief Add a new edge map writer command for the writer.
228 /// Add a new edge map writer command for the writer.
229 template <typename Writer, typename Map>
230 GraphWriter& addEdgeMap(std::string name,
231 const Map& map, const Writer& writer = Writer()) {
232 edge_map_writers.push_back(make_pair(name,
233 new MapWriter<Edge, Map, Writer>(map, writer)));
237 /// \brief Add a new labeled node writer for the writer.
239 /// Add a new labeled node writer for the writer.
240 GraphWriter& addNode(std::string name, const Node& node) {
241 node_writers.push_back(make_pair(name, node));
245 /// \brief Add a new labeled edge writer for the writer.
247 /// Add a new labeled edge writer for the writer.
248 GraphWriter& addEdge(std::string name, const Edge& edge) {
249 edge_writers.push_back(make_pair(name, edge));
253 /// \brief Executes the writer commands.
255 /// Executes the writer commands.
261 os << "@end" << std::endl;
266 void writeNodeSet() {
267 if (node_map_writers.size() == 0) return;
268 os << "@nodeset" << std::endl;
269 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
270 os << node_map_writers[i].first << '\t';
273 for (NodeIt it(graph); it != INVALID; ++it) {
274 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
275 node_map_writers[i].second->write(os, it);
282 void writeEdgeSet() {
283 if (edge_map_writers.size() == 0) return;
284 if (node_map_writers.size() == 0) {
285 // ErrorMessage message;
286 // message << "Missing node id map";
287 // throw IOLogicError(message);
289 os << "@edgeset" << std::endl;
291 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
292 os << edge_map_writers[i].first << '\t';
295 for (EdgeIt it(graph); it != INVALID; ++it) {
296 node_map_writers[0].second->write(os, graph.source(it));
297 node_map_writers[0].second->write(os, graph.target(it));
298 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
299 edge_map_writers[i].second->write(os, it);
306 if (node_writers.size() == 0) return;
307 if (node_map_writers.size() == 0) {
308 // throw Exception() << "Missing node id map";
310 os << "@nodes" << std::endl;
311 for (int i = 0; i < (int)node_writers.size(); ++i) {
312 os << node_writers[i].first << '\t';
313 node_map_writers[0].second->write(os, node_writers[i].second);
319 if (edge_writers.size() == 0) return;
320 if (edge_map_writers.size() == 0) {
321 // throw Exception() << "Missing edge id map";
323 os << "@edges" << std::endl;
324 for (int i = 0; i < (int)edge_writers.size(); ++i) {
325 os << edge_writers[i].first << '\t';
326 edge_map_writers[0].second->write(os, edge_writers[i].second);
333 template <class _Item>
337 virtual void write(std::ostream&, const Item&) = 0;
340 template <class _Item, typename _Map, typename _Writer>
341 class MapWriter : public WriterBase<_Item> {
344 typedef _Writer Writer;
345 typedef typename Writer::Value Value;
351 MapWriter(const Map& _map, const Writer& _writer)
352 : map(_map), writer(_writer) {}
355 virtual void write(std::ostream& os, const Item& item) {
356 writer.write(os, map[item]);
363 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
365 NodeMapWriters node_map_writers;
367 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
369 EdgeMapWriters edge_map_writers;
371 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
372 NodeWriters node_writers;
374 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
375 EdgeWriters edge_writers;
382 /// Ready to use writer function.
383 template<typename Graph, typename CapacityMap, typename CostMap>
384 void writeGraph(std::ostream& os, const Graph &g,
385 const CapacityMap& capacity, const typename Graph::Node &s,
386 const typename Graph::Node &t, const CostMap& cost) {
387 GraphWriter<Graph> reader(os, g);
388 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
389 reader.addNodeMap("id", nodeIdMap);
390 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
391 reader.addEdgeMap("id", edgeIdMap);
392 reader.addEdgeMap("capacity", capacity);
393 reader.addEdgeMap("cost", cost);
394 reader.addNode("source", s);
395 reader.addNode("target", t);
399 /// Ready to use writer function.
400 template<typename Graph, typename CapacityMap, typename CostMap>
401 void writeGraph(std::ostream& os, const Graph &g,
402 const CapacityMap& capacity, const typename Graph::Node &s,
403 const typename Graph::Node &t) {
404 GraphWriter<Graph> reader(os, g);
405 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
406 reader.addNodeMap("id", nodeIdMap);
407 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
408 reader.addEdgeMap("id", edgeIdMap);
409 reader.addEdgeMap("capacity", capacity);
410 reader.addNode("source", s);
411 reader.addNode("target", t);
415 /// Ready to use writer function.
416 template<typename Graph, typename CapacityMap>
417 void writeGraph(std::ostream& os, const Graph &g,
418 const CapacityMap& capacity, const typename Graph::Node &s) {
419 GraphWriter<Graph> reader(os, g);
420 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
421 reader.addNodeMap("id", nodeIdMap);
422 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
423 reader.addEdgeMap("id", edgeIdMap);
424 reader.addEdgeMap("capacity", capacity);
425 reader.addNode("source", s);
428 /// Ready to use writer function.
429 template<typename Graph, typename CapacityMap>
430 void writeGraph(std::ostream& os, const Graph &g,
431 const CapacityMap& capacity) {
432 GraphWriter<Graph> reader(os, g);
433 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
434 reader.addNodeMap("id", nodeIdMap);
435 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
436 reader.addEdgeMap("id", edgeIdMap);
437 reader.addEdgeMap("capacity", capacity);
440 /// Ready to use writer function.
441 template<typename Graph>
442 void writeGraph(std::ostream& os, const Graph &g) {
443 GraphWriter<Graph> reader(os, g);
444 IdMap<Graph, typename Graph::Node> nodeIdMap(g);
445 reader.addNodeMap("id", nodeIdMap);
446 IdMap<Graph, typename Graph::Edge> edgeIdMap(g);
447 reader.addEdgeMap("id", edgeIdMap);