3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
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_GRAPH_WRITER_H
25 #define LEMON_GRAPH_WRITER_H
29 #include <lemon/error.h>
30 #include <lemon/lemon_writer.h>
34 /// \addtogroup io_group
37 /// \brief The graph writer class.
39 /// The \c GraphWriter class provides the graph output.
40 /// Before you read this documentation it might be useful to read the general
41 /// description of \ref graph-io-page "Graph Input-Output".
44 /// you should first give writing commands to the writer. You can declare
45 /// write commands as \c NodeMap or \c EdgeMap writing and labeled Node and
49 /// GraphWriter<ListGraph> writer(std::cout, graph);
52 /// The \c writeNodeMap() function declares a \c NodeMap writing
53 /// command in the \c GraphWriter. You should give as parameter
54 /// the name of the map and the map object. The NodeMap writing
55 /// command with name "label" should write a unique map because it
56 /// is regarded as label map (such a map is essential if the graph has edges).
59 /// IdMap<ListGraph, Node> nodeLabelMap;
60 /// writer.writeNodeMap("label", nodeLabelMap);
62 /// writer.writeNodeMap("coords", coords);
63 /// writer.writeNodeMap("color", colorMap);
66 /// With the \c writeEdgeMap() member function you can give an edge map
67 /// writing command similar to the NodeMaps.
70 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
71 /// edgeDescMap(graph);
72 /// writer.writeEdgeMap("descriptor", edgeDescMap);
74 /// writer.writeEdgeMap("weight", weightMap);
75 /// writer.writeEdgeMap("label", labelMap);
78 /// With \c writeNode() and \c writeEdge() functions you can
79 /// point out Nodes and Edges in the graph. For example, you can
80 /// write out the source and target of a maximum flow instance.
83 /// writer.writeNode("source", sourceNode);
84 /// writer.writeNode("target", targetNode);
86 /// writer.writeEdge("observed", edge);
89 /// After you give all write commands you must call the \c run() member
90 /// function, which executes all the writing commands.
96 /// \see DefaultWriterTraits
97 /// \see QuotedStringWriter
99 /// \see DescriptorMap
100 /// \see \ref GraphReader
101 /// \see \ref graph-io-page
102 /// \author Balazs Dezso
103 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
107 typedef _Graph Graph;
108 typedef typename Graph::Node Node;
109 typedef typename Graph::Edge Edge;
111 typedef _WriterTraits WriterTraits;
113 /// \brief Construct a new GraphWriter.
115 /// This function constructs a new GraphWriter to write the given graph
116 /// to the given stream.
117 GraphWriter(std::ostream& _os, const Graph& _graph)
118 : writer(new LemonWriter(_os)), own_writer(true),
119 nodeset_writer(*writer, _graph, std::string()),
120 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
121 node_writer(*writer, nodeset_writer, std::string()),
122 edge_writer(*writer, edgeset_writer, std::string()),
123 attribute_writer(*writer, std::string()) {}
125 /// \brief Construct a new GraphWriter.
127 /// This function constructs a new GraphWriter to write the given graph
128 /// to the given file.
129 GraphWriter(const std::string& _filename, const Graph& _graph)
130 : writer(new LemonWriter(_filename)), own_writer(true),
131 nodeset_writer(*writer, _graph, std::string()),
132 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
133 node_writer(*writer, nodeset_writer, std::string()),
134 edge_writer(*writer, edgeset_writer, std::string()),
135 attribute_writer(*writer, std::string()) {}
137 /// \brief Construct a new GraphWriter.
139 /// This function constructs a new GraphWriter to write the given graph
140 /// to the given LemonReader.
141 GraphWriter(LemonWriter& _writer, const Graph& _graph)
142 : writer(_writer), own_writer(false),
143 nodeset_writer(*writer, _graph, std::string()),
144 edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
145 node_writer(*writer, nodeset_writer, std::string()),
146 edge_writer(*writer, edgeset_writer, std::string()),
147 attribute_writer(*writer, std::string()) {}
149 /// \brief Destruct the graph writer.
151 /// This function destructs the graph writer.
157 /// \brief Issue a new node map writing command for the writer.
159 /// This function issues a new <i> node map writing command</i> to the writer.
160 template <typename Map>
161 GraphWriter& writeNodeMap(std::string name, const Map& map) {
162 nodeset_writer.writeNodeMap(name, map);
167 /// \brief Issue a new node map writing command for the writer.
169 /// This function issues a new <i> node map writing command</i> to the writer.
170 template <typename Writer, typename Map>
171 GraphWriter& writeNodeMap(std::string name, const Map& map,
172 const Writer& writer = Writer()) {
173 nodeset_writer.writeNodeMap(name, map, writer);
178 /// \brief Issue a new edge map writing command for the writer.
180 /// This function issues a new <i> edge map writing command</i> to the writer.
181 template <typename Map>
182 GraphWriter& writeEdgeMap(std::string name, const Map& map) {
183 edgeset_writer.writeEdgeMap(name, map);
188 /// \brief Issue a new edge map writing command for the writer.
190 /// This function issues a new <i> edge map writing command</i> to the writer.
191 template <typename Writer, typename Map>
192 GraphWriter& writeEdgeMap(std::string name, const Map& map,
193 const Writer& writer = Writer()) {
194 edgeset_writer.writeEdgeMap(name, map, writer);
198 /// \brief Issue a new labeled node writing command to the writer.
200 /// This function issues a new <i> labeled node writing command</i>
202 GraphWriter& writeNode(std::string name, const Node& node) {
203 node_writer.writeNode(name, node);
207 /// \brief Issue a new labeled edge writing command to the writer.
209 /// This function issues a new <i> labeled edge writing command</i>
211 GraphWriter& writeEdge(std::string name, const Edge& edge) {
212 edge_writer.writeEdge(name, edge);
215 /// \brief Issue a new attribute writing command.
217 /// This function issues a new <i> attribute writing command</i>
219 template <typename Value>
220 GraphWriter& writeAttribute(std::string name, const Value& value) {
221 attribute_writer.writeAttribute(name, value);
225 /// \brief Issue a new attribute writing command.
227 /// This function issues a new <i> attribute writing command</i>
229 template <typename Writer, typename Value>
230 GraphWriter& writeAttribute(std::string name, const Value& value,
231 const Writer& writer) {
232 attribute_writer.writeAttribute<Writer>(name, value, writer);
236 /// \brief Conversion operator to LemonWriter.
238 /// Conversion operator to LemonWriter. It makes possible
239 /// to access the encapsulated \e LemonWriter, this way
240 /// you can attach to this writer new instances of
241 /// \e LemonWriter::SectionWriter. For more details see
242 /// the \ref rwbackground "Background of Reading and Writing".
243 operator LemonWriter&() {
247 /// \brief Executes the writing commands.
249 /// Executes the writing commands.
254 /// \brief Write the label of the given node.
256 /// It writes the label of the given node. If there was written an "label"
257 /// named node map then it will write the map value belonging to the node.
258 void writeLabel(std::ostream& os, const Node& item) const {
259 nodeset_writer.writeLabel(os, item);
262 /// \brief Write the label of the given edge.
264 /// It writes the label of the given edge. If there was written an "label"
265 /// named edge map then it will write the map value belonging to the edge.
266 void writeLabel(std::ostream& os, const Edge& item) const {
267 edgeset_writer.writeLabel(os, item);
275 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
276 EdgeSetWriter<Graph, WriterTraits> edgeset_writer;
278 NodeWriter<Graph> node_writer;
279 EdgeWriter<Graph> edge_writer;
281 AttributeWriter<WriterTraits> attribute_writer;
286 /// \brief Write a graph to the output.
288 /// It is a helper function to write a graph to the given output
289 /// stream. It gives back a GraphWriter object and this object
290 /// can write more maps, labeled nodes and edges and attributes.
291 /// \warning Do not forget to call the \c run() function.
293 /// \param os The output stream.
294 /// \param g The graph.
295 template <typename Graph>
296 GraphWriter<Graph> graphWriter(std::ostream& os, const Graph &g) {
297 return GraphWriter<Graph>(os, g);
300 /// \brief Write a graph to the output.
302 /// It is a helper function to write a graph to the given output
303 /// file. It gives back a GraphWriter object and this object
304 /// can write more maps, labeled nodes and edges and attributes.
305 /// \warning Do not forget to call the \c run() function.
307 /// \param fn The filename.
308 /// \param g The graph.
309 template <typename Graph>
310 GraphWriter<Graph> graphWriter(const std::string& fn, const Graph &g) {
311 return GraphWriter<Graph>(fn, g);
314 /// \brief The undirected graph writer class.
316 /// The \c UGraphWriter class provides the ugraph output. To write
317 /// a graph you should first give writing commands to the writer. You can
318 /// declare write command as \c NodeMap, \c EdgeMap or \c UEdgeMap
319 /// writing and labeled Node, Edge or UEdge writing.
322 /// UGraphWriter<ListUGraph> writer(std::cout, graph);
325 /// The \c writeNodeMap() function declares a \c NodeMap writing
326 /// command in the \c UGraphWriter. You should give as parameter
327 /// the name of the map and the map object. The NodeMap writing
328 /// command with name "label" should write a unique map because it
329 /// is regarded as label map.
332 /// IdMap<ListUGraph, Node> nodeLabelMap;
333 /// writer.writeNodeMap("label", nodeLabelMap);
335 /// writer.writeNodeMap("coords", coords);
336 /// writer.writeNodeMap("color", colorMap);
339 /// With the \c writeUEdgeMap() member function you can give an
340 /// undirected edge map writing command similar to the NodeMaps.
343 /// DescriptorMap<ListGraph, Edge, ListGraph::EdgeMap<int> >
344 /// edgeDescMap(graph);
345 /// writer.writeUEdgeMap("descriptor", edgeDescMap);
347 /// writer.writeUEdgeMap("weight", weightMap);
348 /// writer.writeUEdgeMap("label", labelMap);
351 /// The EdgeMap handling is just a syntactical sugar. It writes
352 /// two undirected edge map with '+' and '-' prefix in the name.
355 /// writer.writeEdgeMap("capacity", capacityMap);
359 /// With \c writeNode() and \c writeUEdge() functions you can
360 /// designate nodes and undirected edges in the graph. For example, you can
361 /// write out the source and target of the graph.
364 /// writer.writeNode("source", sourceNode);
365 /// writer.writeNode("target", targetNode);
367 /// writer.writeUEdge("observed", uEdge);
370 /// After you give all write commands you must call the \c run() member
371 /// function, which executes all the writing commands.
377 /// \see DefaultWriterTraits
378 /// \see QuotedStringWriter
380 /// \see DescriptorMap
381 /// \see \ref GraphWriter
382 /// \see \ref graph-io-page
383 /// \author Balazs Dezso
384 template <typename _Graph, typename _WriterTraits = DefaultWriterTraits>
388 typedef _Graph Graph;
389 typedef typename Graph::Node Node;
390 typedef typename Graph::Edge Edge;
391 typedef typename Graph::UEdge UEdge;
393 typedef _WriterTraits WriterTraits;
395 /// \brief Construct a new UGraphWriter.
397 /// Construct a new UGraphWriter. It writes the given graph
398 /// to the given stream.
399 UGraphWriter(std::ostream& _os, const Graph& _graph)
400 : writer(new LemonWriter(_os)), own_writer(true),
401 nodeset_writer(*writer, _graph, std::string()),
402 u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
403 node_writer(*writer, nodeset_writer, std::string()),
404 u_edge_writer(*writer, u_edgeset_writer, std::string()),
405 attribute_writer(*writer, std::string()) {}
407 /// \brief Construct a new UGraphWriter.
409 /// Construct a new UGraphWriter. It writes the given graph
410 /// to the given file.
411 UGraphWriter(const std::string& _filename, const Graph& _graph)
412 : writer(new LemonWriter(_filename)), own_writer(true),
413 nodeset_writer(*writer, _graph, std::string()),
414 u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
415 node_writer(*writer, nodeset_writer, std::string()),
416 u_edge_writer(*writer, u_edgeset_writer, std::string()),
417 attribute_writer(*writer, std::string()) {}
419 /// \brief Construct a new UGraphWriter.
421 /// Construct a new UGraphWriter. It writes the given graph
422 /// to given LemonReader.
423 UGraphWriter(LemonWriter& _writer, const Graph& _graph)
424 : writer(_writer), own_writer(false),
425 nodeset_writer(*writer, _graph, std::string()),
426 u_edgeset_writer(*writer, _graph, nodeset_writer, std::string()),
427 node_writer(*writer, nodeset_writer, std::string()),
428 u_edge_writer(*writer, u_edgeset_writer, std::string()),
429 attribute_writer(*writer, std::string()) {}
431 /// \brief Destruct the graph writer.
433 /// Destruct the graph writer.
439 /// \brief Issue a new node map writing command to the writer.
441 /// This function issues a new <i> node map writing command</i> to the writer.
442 template <typename Map>
443 UGraphWriter& writeNodeMap(std::string name, const Map& map) {
444 nodeset_writer.writeNodeMap(name, map);
448 /// \brief Issue a new node map writing command to the writer.
450 /// This function issues a new <i> node map writing command</i> to the writer.
451 template <typename Writer, typename Map>
452 UGraphWriter& writeNodeMap(std::string name, const Map& map,
453 const Writer& writer = Writer()) {
454 nodeset_writer.writeNodeMap(name, map, writer);
458 /// \brief Issue a new edge map writing command to the writer.
460 /// This function issues a new <i> edge map writing command</i> to the writer.
461 template <typename Map>
462 UGraphWriter& writeEdgeMap(std::string name, const Map& map) {
463 u_edgeset_writer.writeEdgeMap(name, map);
467 /// \brief Issue a new edge map writing command to the writer.
469 /// This function issues a new <i> edge map writing command</i> to the writer.
470 template <typename Writer, typename Map>
471 UGraphWriter& writeEdgeMap(std::string name, const Map& map,
472 const Writer& writer = Writer()) {
473 u_edgeset_writer.writeEdgeMap(name, map, writer);
477 /// \brief Issue a new undirected edge map writing command to the writer.
479 /// This function issues a new <i> undirected edge map writing
480 /// command</i> to the writer.
481 template <typename Map>
482 UGraphWriter& writeUEdgeMap(std::string name, const Map& map) {
483 u_edgeset_writer.writeUEdgeMap(name, map);
487 /// \brief Issue a new undirected edge map writing command to the writer.
489 /// This function issues a new <i> undirected edge map writing
490 /// command</i> to the writer.
491 template <typename Writer, typename Map>
492 UGraphWriter& writeUEdgeMap(std::string name, const Map& map,
493 const Writer& writer = Writer()) {
494 u_edgeset_writer.writeUEdgeMap(name, map, writer);
498 /// \brief Issue a new labeled node writer to the writer.
500 /// This function issues a new <i> labeled node writing
501 /// command</i> to the writer.
502 UGraphWriter& writeNode(std::string name, const Node& node) {
503 node_writer.writeNode(name, node);
507 /// \brief Issue a new labeled edge writer to the writer.
509 /// This function issues a new <i> labeled edge writing
510 /// command</i> to the writer.
511 UGraphWriter& writeEdge(std::string name, const Edge& edge) {
512 u_edge_writer.writeEdge(name, edge);
515 /// \brief Issue a new labeled undirected edge writing command to
518 /// Issue a new <i>labeled undirected edge writing command</i> to
520 UGraphWriter& writeUEdge(std::string name, const UEdge& edge) {
521 u_edge_writer.writeUEdge(name, edge);
524 /// \brief Issue a new attribute writing command.
526 /// This function issues a new <i> attribute writing
527 /// command</i> to the writer.
528 template <typename Value>
529 UGraphWriter& writeAttribute(std::string name, const Value& value) {
530 attribute_writer.writeAttribute(name, value);
534 /// \brief Issue a new attribute writing command.
536 /// This function issues a new <i> attribute writing
537 /// command</i> to the writer.
538 template <typename Writer, typename Value>
539 UGraphWriter& writeAttribute(std::string name, const Value& value,
540 const Writer& writer) {
541 attribute_writer.writeAttribute<Writer>(name, value, writer);
545 /// \brief Conversion operator to LemonWriter.
547 /// Conversion operator to LemonWriter. It makes possible
548 /// to access the encapsulated \e LemonWriter, this way
549 /// you can attach to this writer new instances of
550 /// \e LemonWriter::SectionWriter.
551 operator LemonWriter&() {
555 /// \brief Executes the writing commands.
557 /// Executes the writing commands.
562 /// \brief Write the label of the given node.
564 /// It writes the label of the given node. If there was written an "label"
565 /// named node map then it will write the map value belonging to the node.
566 void writeLabel(std::ostream& os, const Node& item) const {
567 nodeset_writer.writeLabel(os, item);
570 /// \brief Write the label of the given edge.
572 /// It writes the label of the given edge. If there was written an "label"
573 /// named edge map then it will write the map value belonging to the edge.
574 void writeLabel(std::ostream& os, const Edge& item) const {
575 u_edgeset_writer.writeLabel(os, item);
578 /// \brief Write the label of the given undirected edge.
580 /// It writes the label of the given undirected edge. If there was written
581 /// an "label" named edge map then it will write the map value belonging to
583 void writeLabel(std::ostream& os, const UEdge& item) const {
584 u_edgeset_writer.writeLabel(os, item);
593 NodeSetWriter<Graph, WriterTraits> nodeset_writer;
594 UEdgeSetWriter<Graph, WriterTraits> u_edgeset_writer;
596 NodeWriter<Graph> node_writer;
597 UEdgeWriter<Graph> u_edge_writer;
599 AttributeWriter<WriterTraits> attribute_writer;
602 /// \brief Write an undirected graph to the output.
604 /// It is a helper function to write an undirected graph to the given output
605 /// stream. It gives back an UGraphWriter object and this object
606 /// can write more maps, labeled nodes and edges and attributes.
607 /// \warning Do not forget to call the \c run() function.
609 /// \param os The output stream.
610 /// \param g The graph.
611 template <typename Graph>
612 UGraphWriter<Graph> uGraphWriter(std::ostream& os, const Graph &g) {
613 return UGraphWriter<Graph>(os, g);
616 /// \brief Write an undirected graph to the output.
618 /// It is a helper function to write an undirected graph to the given output
619 /// file. It gives back an UGraphWriter object and this object
620 /// can write more maps, labeled nodes, edges, undirected edges and
623 /// \warning Do not forget to call the \c run() function.
625 /// \param fn The output file.
626 /// \param g The graph.
627 template <typename Graph>
628 UGraphWriter<Graph> uGraphWriter(const std::string& fn,
630 return UGraphWriter<Graph>(fn, g);