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/invalid.h>
31 #include <lemon/error.h>
36 /// \brief Standard WriterTraits for the GraphWriter class.
38 /// Standard WriterTraits for the GraphWriter class.
39 /// It defines standard writing method for all type of value.
40 struct DefaultWriterTraits {
42 /// \brief Template class for writing an value.
44 /// Template class for writing an value.
45 template <typename _Value>
50 /// \brief Writes a value from the given stream.
52 /// Writes a value from the given stream.
53 void write(std::ostream& os, const Value& value) {
61 /// \brief Writer class for quoted strings.
63 /// Writer class for quoted strings. It can process the escape
64 /// sequences in the string.
65 class QuotedStringWriter {
67 typedef std::string Value;
69 /// \brief Constructor for the writer.
71 /// Constructor for the writer. If the given parameter is true
72 /// the writer creates escape sequences from special characters.
73 QuotedStringWriter(bool _escaped = true) : escaped(_escaped) {}
75 /// \brief Writes a quoted string from the given stream.
77 /// Writes a quoted string from the given stream.
78 void write(std::ostream& os, const std::string& value) {
82 for (int i = 0; i < (int)value.size(); ++i) {
83 writeEscape(ls, value[i]);
94 static void writeEscape(std::ostream& os, char c) {
131 os << '\\' << oct << (int)c;
143 /// \brief The graph writer class.
145 /// The writer class for the graph output.
146 /// \see \ref GraphReader
147 /// \see \ref graph-io-page
148 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
152 typedef _Graph Graph;
153 typedef typename Graph::Node Node;
154 typedef typename Graph::NodeIt NodeIt;
155 typedef typename Graph::Edge Edge;
156 typedef typename Graph::EdgeIt EdgeIt;
158 typedef _WriterTraits WriterTraits;
160 /// \brief Construct a new GraphWriter.
162 /// Construct a new GraphWriter. It writes from the given map,
163 /// it constructs the given map and it use the given writer as the
165 GraphWriter(std::ostream& _os, Graph& _graph) : os(_os), graph(_graph) {}
168 /// \brief Destruct the graph writer.
170 /// Destruct the graph writer.
172 for (typename NodeMapWriters::iterator it = node_map_writers.begin();
173 it != node_map_writers.end(); ++it) {
177 for (typename EdgeMapWriters::iterator it = edge_map_writers.begin();
178 it != edge_map_writers.end(); ++it) {
186 /// \brief Add a new node map writer command for the writer.
188 /// Add a new node map writer command for the writer.
189 template <typename Map>
190 GraphWriter& addNodeMap(std::string name, const Map& map) {
191 return addNodeMap<typename WriterTraits::template Writer<
192 typename Map::Value>, Map>(name, map);
195 /// \brief Add a new node map writer command for the writer.
197 /// Add a new node map writer command for the writer.
198 template <typename Writer, typename Map>
199 GraphWriter& addNodeMap(std::string name, const Map& map,
200 const Writer& writer = Writer()) {
201 node_map_writers.push_back(
202 make_pair(name, new MapWriter<Node, Map, Writer>(map, writer)));
208 /// \brief Add a new edge map writer command for the writer.
210 /// Add a new edge map writer command for the writer.
211 template <typename Map>
212 GraphWriter& addEdgeMap(std::string name, const Map& map) {
213 return addEdgeMap<typename WriterTraits::template Writer<
214 typename Map::Value>, Map>(name, map);
218 /// \brief Add a new edge map writer command for the writer.
220 /// Add a new edge map writer command for the writer.
221 template <typename Writer, typename Map>
222 GraphWriter& addEdgeMap(std::string name,
223 const Map& map, const Writer& writer = Writer()) {
224 edge_map_writers.push_back(make_pair(name,
225 new MapWriter<Edge, Map, Writer>(map, writer)));
229 /// \brief Add a new labeled node writer for the writer.
231 /// Add a new labeled node writer for the writer.
232 GraphWriter& addNode(std::string name, const Node& node) {
233 node_writers.push_back(make_pair(name, node));
237 /// \brief Add a new labeled edge writer for the writer.
239 /// Add a new labeled edge writer for the writer.
240 GraphWriter& addEdge(std::string name, const Edge& edge) {
241 edge_writers.push_back(make_pair(name, edge));
245 /// \brief Executes the writer commands.
247 /// Executes the writer commands.
253 os << "@end" << std::endl;
258 void writeNodeSet() {
259 if (node_map_writers.size() == 0) return;
260 os << "@nodeset" << std::endl;
261 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
262 os << node_map_writers[i].first << '\t';
265 for (NodeIt it(graph); it != INVALID; ++it) {
266 for (int i = 0; i < (int)node_map_writers.size(); ++i) {
267 node_map_writers[i].second->write(os, it);
274 void writeEdgeSet() {
275 if (edge_map_writers.size() == 0) return;
276 if (node_map_writers.size() == 0) {
277 throw Exception() << "Missing node id map";
279 os << "@edgeset" << std::endl;
281 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
282 os << edge_map_writers[i].first << '\t';
285 for (EdgeIt it(graph); it != INVALID; ++it) {
286 node_map_writers[0].second->write(os, graph.source(it));
287 node_map_writers[0].second->write(os, graph.target(it));
288 for (int i = 0; i < (int)edge_map_writers.size(); ++i) {
289 edge_map_writers[i].second->write(os, it);
296 if (node_writers.size() == 0) return;
297 if (node_map_writers.size() == 0) {
298 throw Exception() << "Missing node id map";
300 os << "@nodes" << std::endl;
301 for (int i = 0; i < (int)node_writers.size(); ++i) {
302 os << node_writers[i].first << '\t';
303 node_map_writers[0].second->write(os, node_writers[i].second);
309 if (edge_writers.size() == 0) return;
310 if (edge_map_writers.size() == 0) {
311 throw Exception() << "Missing edge id map";
313 os << "@edges" << std::endl;
314 for (int i = 0; i < (int)edge_writers.size(); ++i) {
315 os << edge_writers[i].first << '\t';
316 edge_map_writers[0].second->write(os, edge_writers[i].second);
323 template <class _Item>
327 virtual void write(std::ostream&, const Item&) = 0;
330 template <class _Item, typename _Map, typename _Writer>
331 class MapWriter : public WriterBase<_Item> {
334 typedef _Writer Writer;
335 typedef typename Writer::Value Value;
341 MapWriter(const Map& _map, const Writer& _writer)
342 : map(_map), writer(_writer) {}
345 virtual void write(std::ostream& os, const Item& item) {
346 writer.write(os, map[item]);
353 typedef std::vector< std::pair<std::string, WriterBase<Node>*> >
355 NodeMapWriters node_map_writers;
357 typedef std::vector< std::pair<std::string, WriterBase<Edge>*> >
359 EdgeMapWriters edge_map_writers;
361 typedef std::vector<std::pair<std::string, Node> > NodeWriters;
362 NodeWriters node_writers;
364 typedef std::vector<std::pair<std::string, Edge> > EdgeWriters;
365 EdgeWriters edge_writers;